diff options
Diffstat (limited to 'compiler/src/dotty')
11 files changed, 88 insertions, 50 deletions
diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala index 371396e36..654507991 100644 --- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala +++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala @@ -37,44 +37,47 @@ import StdNames.nme /** * Verifies that each Label DefDef has only a single address to jump back and - * reorders them such that they are not nested and this address is a fall-through address for JVM - * - * ei such code - * + * reorders them such that they are not nested and this address is a + * fall-through address for the JVM. * + * ```scala * <label> def foo(i: Int) = { * <label> def bar = 0 * <label> def dough(i: Int) = if (i == 0) bar else foo(i-1) * dough(i) - * } + * } * * foo(100) + * ``` * - * will get rewritten to + * will get rewritten to: * - * \ + * ```scala * <label> def foo(i: Int) = dough(i) * <label> def dough(i: Int) = if (i == 0) bar else foo(i-1) * <label> def bar = 2 * foo(100) + * ``` * - * Proposed way to generate this pattern in backend is: + * Proposed way to generate this pattern in backend is: * - * foo(100) - * <jump foo> - * <label> def foo(i: Int) = dough(i) - * // <jump a> // unreachable - * <label> def dough(i: Int) = if (i == 0) bar else foo(i-1) - * // <jump a> // unreachable - * <label> def bar = 2 - * // <jump a> // unreachable - * <asm point a> + * ```scala + * foo(100) + * <jump foo> + * <label> def foo(i: Int) = dough(i) + * // <jump a> // unreachable + * <label> def dough(i: Int) = if (i == 0) bar else foo(i-1) + * // <jump a> // unreachable + * <label> def bar = 2 + * // <jump a> // unreachable + * <asm point a> + * ``` * - * Unreachable jumps will be eliminated by local dead code analysis. - * After JVM is smart enough to remove next-line jumps + * Unreachable jumps will be eliminated by local dead code analysis. + * After JVM is smart enough to remove next-line jumps * - * Note that Label DefDefs can be only nested in Block, otherwise no one would be able to call them - * Other DefDefs are eliminated + * Note that Label DefDefs can be only nested in Block, otherwise no one would + * be able to call them Other DefDefs are eliminated */ class LabelDefs extends MiniPhaseTransform { def phaseName: String = "labelDef" diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala index 0f652ff0b..38bf80bad 100644 --- a/compiler/src/dotty/tools/dotc/Run.scala +++ b/compiler/src/dotty/tools/dotc/Run.scala @@ -15,6 +15,7 @@ import reporting.Reporter import transform.TreeChecker import rewrite.Rewrites import java.io.{BufferedWriter, OutputStreamWriter} +import printing.XprintMode import scala.annotation.tailrec import scala.reflect.io.VirtualFile @@ -95,7 +96,7 @@ class Run(comp: Compiler)(implicit ctx: Context) { val unit = ctx.compilationUnit val prevPhase = ctx.phase.prev // can be a mini-phase val squashedPhase = ctx.squashed(prevPhase) - val treeString = unit.tpdTree.show + val treeString = unit.tpdTree.show(ctx.withProperty(XprintMode, Some(()))) ctx.echo(s"result of $unit after $squashedPhase:") diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 21a6c1165..e4c90789c 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -101,6 +101,7 @@ class ScalaSettings extends Settings.SettingGroup { val XoldPatmat = BooleanSetting("-Xoldpatmat", "Use the pre-2.10 pattern matcher. Otherwise, the 'virtualizing' pattern matcher is used in 2.10.") val XnoPatmatAnalysis = BooleanSetting("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.") val XfullLubs = BooleanSetting("-Xfull-lubs", "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds.") + val wikiSyntax = BooleanSetting("-Xwiki-syntax", "Retains the Scala2 behavior of using Wiki Syntax in Scaladoc") /** -Y "Private" settings */ @@ -212,11 +213,18 @@ class ScalaSettings extends Settings.SettingGroup { "A directory containing static resources needed for the API documentation" ) - val DocTitle = StringSetting ( - "-Ydoc-title", - "title", - "The overall name of the Scaladoc site", - "" + val siteRoot = StringSetting( + "-siteroot", + "site root", + "A directory containing static files from which to generate documentation", + sys.props("user.dir") + ) + + val projectName = StringSetting ( + "-project", + "project title", + "The name of the project", + sys.props("user.dir").split(sys.props("file.separator")).last ) val DocVersion = StringSetting ( diff --git a/compiler/src/dotty/tools/dotc/core/Phases.scala b/compiler/src/dotty/tools/dotc/core/Phases.scala index d217afed8..44608296a 100644 --- a/compiler/src/dotty/tools/dotc/core/Phases.scala +++ b/compiler/src/dotty/tools/dotc/core/Phases.scala @@ -263,6 +263,13 @@ object Phases { trait Phase extends DotClass { + /** A name given to the `Phase` that can be used to debug the compiler. For + * instance, it is possible to print trees after a given phase using: + * + * ```bash + * $ ./bin/dotc -Xprint:<phaseNameHere> sourceFile.scala + * ``` + */ def phaseName: String /** List of names of phases that should precede this phase */ diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 636204f64..ae9122853 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -41,9 +41,11 @@ object Types { implicit def eqType: Eq[Type, Type] = Eq - /** The class of types. + /** Main class representing types. + * * The principal subclasses and sub-objects are as follows: * + * ```none * Type -+- ProxyType --+- NamedType ----+--- TypeRef * | | \ * | +- SingletonType-+-+- TermRef @@ -74,6 +76,7 @@ object Types { * +- NoPrefix * +- ErrorType * +- WildcardType + * ``` * * Note: please keep in sync with copy in `docs/docs/internals/type-system.md`. */ diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala index 0dc8d8fea..fb37c9e7d 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala @@ -31,8 +31,10 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) { def nameRefToString(ref: NameRef): String = nameToString(tastyName(ref)) def printNames() = - for ((name, idx) <- tastyName.contents.zipWithIndex) - println(f"$idx%4d: " + nameToString(name)) + for ((name, idx) <- tastyName.contents.zipWithIndex) { + val index = "%4d: ".format(idx) + println(index + nameToString(name)) + } def printContents(): Unit = { println("Names:") @@ -47,7 +49,10 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) { def unpickle(reader: TastyReader, tastyName: TastyName.Table): Unit = { import reader._ var indent = 0 - def newLine() = print(f"\n ${index(currentAddr) - index(startAddr)}%5d:" + " " * indent) + def newLine() = { + val length = "%5d:".format(index(currentAddr) - index(startAddr)) + print(s"\n $length" + " " * indent) + } def printNat() = print(" " + readNat()) def printName() = { val idx = readNat() diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 3085ad8fd..7f124563d 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -61,7 +61,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { override def nameString(name: Name): String = name.decode.toString override protected def simpleNameString(sym: Symbol): String = { - val name = sym.originalName + val name = if (ctx.property(XprintMode).isEmpty) sym.originalName else sym.name nameString(if (sym is ExpandedTypeParam) name.asTypeName.unexpandedName else name) } diff --git a/compiler/src/dotty/tools/dotc/printing/package.scala b/compiler/src/dotty/tools/dotc/printing/package.scala index 814eb2ad0..e2c0dda1b 100644 --- a/compiler/src/dotty/tools/dotc/printing/package.scala +++ b/compiler/src/dotty/tools/dotc/printing/package.scala @@ -2,6 +2,7 @@ package dotty.tools.dotc import core.StdNames.nme import parsing.{precedence, minPrec, maxPrec, minInfixPrec} +import util.Property.Key package object printing { @@ -14,4 +15,9 @@ package object printing { val GlobalPrec = parsing.minPrec val TopLevelPrec = parsing.minPrec - 1 + /** A property to indicate whether the compiler is currently doing -Xprint + * + * -Xprint will print `sym.name` instead of `sym.originalName` + */ + val XprintMode = new Key[Unit] } diff --git a/compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala b/compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala index 8bc4a2aa9..ebd2ae436 100644 --- a/compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala +++ b/compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala @@ -7,36 +7,37 @@ import core._ import Contexts.Context, Types._, Constants._, Decorators._, Symbols._ import TypeUtils._, TypeErasure._, Flags._ - /** Implements partial evaluation of `sc.isInstanceOf[Sel]` according to: * - * +-------------+----------------------------+----------------------------+------------------+ * | Sel\sc | trait | class | final class | - * +-------------+----------------------------+----------------------------+------------------+ + * | ----------: | :------------------------: | :------------------------: | :--------------: | * | trait | ? | ? | statically known | * | class | ? | false if classes unrelated | statically known | * | final class | false if classes unrelated | false if classes unrelated | statically known | - * +-------------+----------------------------+----------------------------+------------------+ * * This is a generalized solution to raising an error on unreachable match * cases and warnings on other statically known results of `isInstanceOf`. * * Steps taken: * - * 1. evalTypeApply will establish the matrix and choose the appropriate - * handling for the case: - * 2. a) Sel/sc is a value class or scrutinee is `Any` - * b) handleStaticallyKnown - * c) falseIfUnrelated with `scrutinee <:< selector` - * d) handleFalseUnrelated - * e) leave as is (aka `happens`) - * 3. Rewrite according to step taken in `2` + * 1. `evalTypeApply` will establish the matrix and choose the appropriate + * handling for the case: + * - Sel/sc is a value class or scrutinee is `Any` + * - `handleStaticallyKnown` + * - `falseIfUnrelated` with `scrutinee <:< selector` + * - `handleFalseUnrelated` + * - leave as is (`happens`) + * 2. Rewrite according to steps taken in 1 */ class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer => import dotty.tools.dotc.ast.tpd._ - def phaseName = "isInstanceOfEvaluator" + val phaseName = "isInstanceOfEvaluator" + + /** Transforms a [TypeApply](dotty.tools.dotc.ast.Trees.TypeApply) in order to + * evaluate an `isInstanceOf` check according to the rules defined above. + */ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = { val defn = ctx.definitions diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 09487570d..cfc0003c6 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -327,7 +327,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) { (tp.paramNames, tp.paramTypes, argss.head).zipped.foreach { (name, paramtp, arg) => def isByName = paramtp.dealias.isInstanceOf[ExprType] paramBinding(name) = arg.tpe.stripAnnots.stripTypeVar match { - case argtpe: SingletonType if isByName || isIdempotentExpr(arg) => argtpe + case argtpe: SingletonType if isIdempotentExpr(arg) => argtpe case argtpe => val inlineFlag = if (paramtp.hasAnnotation(defn.InlineParamAnnot)) Inline else EmptyFlags val (bindingFlags, bindingType) = diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 6bd8f6d06..772d9385b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -491,22 +491,26 @@ class Namer { typer: Typer => if (cdef.isClassDef) { classDef(name) = cdef cdef.attachmentOrElse(ExpandedTree, cdef) match { - case Thicket(cls :: mval :: (mcls @ TypeDef(_, _: Template)) :: crest) => + case Thicket(cls :: mval :: (mcls @ TypeDef(mname, _: Template)) :: crest) + if name.moduleClassName == mname => moduleDef(name) = mcls case _ => } } for (mdef @ ModuleDef(name, _) <- stats if !mdef.mods.is(Flags.Package)) { val typName = name.toTypeName - val Thicket(vdef :: (mcls @ TypeDef(_, impl: Template)) :: Nil) = mdef.attachment(ExpandedTree) + // Expansion of object is a flattened thicket with the first two elements being: + // module val :: module class :: rest + val Thicket(vdef :: (mcls @ TypeDef(_, impl: Template)) :: rest) = expanded(mdef) moduleDef(typName) = mcls classDef get name.toTypeName match { case Some(cdef) => cdef.attachmentOrElse(ExpandedTree, cdef) match { - case Thicket(cls :: mval :: TypeDef(_, compimpl: Template) :: crest) => + case Thicket(cls :: mval :: TypeDef(mname, compimpl: Template) :: crest) + if name.moduleClassName == mname => val mcls1 = cpy.TypeDef(mcls)( rhs = cpy.Template(impl)(body = compimpl.body ++ impl.body)) - mdef.putAttachment(ExpandedTree, Thicket(vdef :: mcls1 :: Nil)) + mdef.putAttachment(ExpandedTree, Thicket(vdef :: mcls1 :: rest)) moduleDef(typName) = mcls1 cdef.putAttachment(ExpandedTree, Thicket(cls :: crest)) case _ => |