aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-07-03 19:02:26 +0200
committerMartin Odersky <odersky@gmail.com>2014-07-17 11:02:00 +0200
commitdb88bf06958e33ae415ca227808ab1f3e48fed7f (patch)
treedef81047ef7f2bdf930e2a5561cfcd2403a61912 /src/dotty
parentefe4f7e43652a303d16a5253f84316e547f45cca (diff)
downloaddotty-db88bf06958e33ae415ca227808ab1f3e48fed7f.tar.gz
dotty-db88bf06958e33ae415ca227808ab1f3e48fed7f.tar.bz2
dotty-db88bf06958e33ae415ca227808ab1f3e48fed7f.zip
Various cleanups and utility additions
- Some new functionality in tpd and in Symbols. - Added `sm` interpolator to print nicely. - Make use of nestedMap where possible. - Add IdentityDenotTransformer as a convencience class
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala14
-rw-r--r--src/dotty/tools/dotc/core/Decorators.scala36
-rw-r--r--src/dotty/tools/dotc/core/DenotTransformers.scala8
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala38
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala6
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala6
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala16
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala12
-rw-r--r--src/dotty/tools/dotc/transform/SuperAccessors.scala17
-rw-r--r--src/dotty/tools/dotc/typer/ErrorReporting.scala2
-rw-r--r--src/dotty/tools/dotc/typer/ImportInfo.scala2
11 files changed, 116 insertions, 41 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 84e1118f9..f0151e1d3 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -204,11 +204,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}
val (vparamss, rtp) = valueParamss(mtp)
val targs = tparams map (_.typeRef)
- val argss = vparamss map (_ map (vparam => Ident(vparam.termRef)))
+ val argss = vparamss.nestedMap(vparam => Ident(vparam.termRef))
ta.assignType(
untpd.DefDef(
Modifiers(sym), sym.name, tparams map TypeDef,
- vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhsFn(targs)(argss)), sym)
+ vparamss.nestedMap(ValDef(_)), TypeTree(rtp), rhsFn(targs)(argss)), sym)
}
def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef =
@@ -384,6 +384,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def changeOwner(from: Symbol, to: Symbol)(implicit ctx: Context): ThisTree =
new TreeTypeMap(ownerMap = (sym => if (sym == from) to else sym)).apply(tree)
+ def appliedToArg(arg: Tree)(implicit ctx: Context): Tree = appliedToArgs(arg :: Nil)
+
+ def appliedToArgs(args: List[Tree])(implicit ctx: Context): Tree =
+ if (args.isEmpty) tree else Apply(tree, args)
+
+ def appliedToArgss(argss: List[List[Tree]])(implicit ctx: Context): Tree =
+ ((tree: Tree) /: argss)(Apply(_, _))
+
def appliedToTypes(targs: List[Type])(implicit ctx: Context): Tree =
appliedToTypeTrees(targs map (TypeTree(_)))
@@ -395,7 +403,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def tpes: List[Type] = xs map (_.tpe)
}
- class TreeTypeMap(val typeMap: TypeMap = IdentityTypeMap, val ownerMap: Symbol => Symbol = identity _)(implicit ctx: Context) extends TreeMap {
+ class TreeTypeMap(val typeMap: Type => Type = IdentityTypeMap, val ownerMap: Symbol => Symbol = identity _)(implicit ctx: Context) extends TreeMap {
override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = super.transform {
tree.withType(typeMap(tree.tpe)) match {
case bind: tpd.Bind =>
diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala
index 155ea87e0..cd7b46896 100644
--- a/src/dotty/tools/dotc/core/Decorators.scala
+++ b/src/dotty/tools/dotc/core/Decorators.scala
@@ -143,7 +143,7 @@ object Decorators {
* 2) Lists can be formatted using the desired separator between two `%` signs,
* eg `i"myList = (${myList}%, %)"`
*/
- implicit class InfoString(val sc: StringContext) extends AnyVal {
+ implicit class StringInterpolators(val sc: StringContext) extends AnyVal {
def i(args: Any*)(implicit ctx: Context): String = {
@@ -166,7 +166,39 @@ object Decorators {
val (args1, suffixes1) = (args, suffixes).zipped.map(treatArg(_, _)).unzip
new StringContext(prefix :: suffixes1.toList: _*).s(args1: _*)
}
- }
+ /** Lifted from scala.reflect.internal.util
+ * A safe combination of [[scala.collection.immutable.StringLike#stripMargin]]
+ * and [[scala.StringContext#raw]].
+ *
+ * The margin of each line is defined by whitespace leading up to a '|' character.
+ * This margin is stripped '''before''' the arguments are interpolated into to string.
+ *
+ * String escape sequences are '''not''' processed; this interpolater is designed to
+ * be used with triple quoted Strings.
+ *
+ * {{{
+ * scala> val foo = "f|o|o"
+ * foo: String = f|o|o
+ * scala> sm"""|${foo}
+ * |"""
+ * res0: String =
+ * "f|o|o
+ * "
+ * }}}
+ */
+ final def sm(args: Any*): String = {
+ def isLineBreak(c: Char) = c == '\n' || c == '\f' // compatible with StringLike#isLineBreak
+ def stripTrailingPart(s: String) = {
+ val (pre, post) = s.span(c => !isLineBreak(c))
+ pre + post.stripMargin
+ }
+ val stripped: List[String] = sc.parts.toList match {
+ case head :: tail => head.stripMargin :: (tail map stripTrailingPart)
+ case Nil => Nil
+ }
+ new StringContext(stripped: _*).raw(args: _*)
+ }
+ }
}
diff --git a/src/dotty/tools/dotc/core/DenotTransformers.scala b/src/dotty/tools/dotc/core/DenotTransformers.scala
index 6daa028fc..e052a07ea 100644
--- a/src/dotty/tools/dotc/core/DenotTransformers.scala
+++ b/src/dotty/tools/dotc/core/DenotTransformers.scala
@@ -46,4 +46,12 @@ object DenotTransformers {
}
}
}
+
+ /** A `DenotTransformer` trait that has the identity as its `transform` method.
+ * You might want to inherit from this trait so that new denotations can be
+ * installed using `installAfter` and `enteredAfter` at the end of the phase.
+ */
+ trait IdentityDenotTransformer extends DenotTransformer {
+ def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref
+ }
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 643237038..ba57909a0 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -212,6 +212,14 @@ object SymDenotations {
final def addAnnotation(annot: Annotation): Unit =
annotations = annot :: myAnnotations
+ /** Remove annotation with given class from this denotation */
+ final def removeAnnotation(cls: Symbol)(implicit ctx: Context): Unit =
+ annotations = myAnnotations.filterNot(_ matches cls)
+
+ /** Copy all annotations from given symbol by adding them to this symbol */
+ final def addAnnotations(from: Symbol)(implicit ctx: Context): Unit =
+ from.annotations.foreach(addAnnotation)
+
@tailrec
private def dropOtherAnnotations(anns: List[Annotation], cls: Symbol)(implicit ctx: Context): List[Annotation] = anns match {
case ann :: rest => if (ann matches cls) anns else dropOtherAnnotations(rest, cls)
@@ -861,6 +869,22 @@ object SymDenotations {
/** Install this denotation as the result of the given denotation transformer. */
override def installAfter(phase: DenotTransformer)(implicit ctx: Context): Unit =
super.installAfter(phase)
+
+ /** Remove private modifier from symbol's definition. If this symbol
+ * is not a constructor nor a static module, rename it by expanding its name to avoid name clashes
+ * @param base the fully qualified name of this class will be appended if name expansion is needed
+ */
+ final def makeNotPrivateAfter(base: Symbol, phase: DenotTransformer)(implicit ctx: Context): Unit = {
+ if (this.is(Private)) {
+ val newName =
+ if (this.is(Module) && isStatic || isClassConstructor) name
+ else {
+ if (this.is(Module)) moduleClass.makeNotPrivateAfter(base, phase)
+ name.expandedName(base)
+ }
+ copySymDenotation(name = newName, initFlags = flags &~ Private).installAfter(phase)
+ }
+ }
}
/** The contents of a class definition during a period
@@ -1311,9 +1335,17 @@ object SymDenotations {
decls.denotsNamed(cname).first.symbol
}
- def underlyingOfValueClass: Type = ???
-
- def valueClassUnbox: Symbol = ???
+ /** The member that of a derived value class that unboxes it. */
+ def valueClassUnbox(implicit ctx: Context): Symbol =
+ // (info.decl(nme.unbox)).orElse(...) uncomment once we accept unbox methods
+ classInfo.decls
+ .find(d => d.isTerm && d.symbol.is(ParamAccessor))
+ .map(_.symbol)
+ .getOrElse(NoSymbol)
+
+ /** The unboxed type that underlies a derived value class */
+ def underlyingOfValueClass(implicit ctx: Context): Type =
+ valueClassUnbox.info.resultType
/** If this class has the same `decls` scope reference in `phase` and
* `phase.next`, install a new denotation with a cloned scope in `phase.next`.
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index bebad60cc..886c728b7 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -12,7 +12,7 @@ import scala.compat.Platform.currentTime
import dotty.tools.io.{ ClassPath, AbstractFile }
import Contexts._, Symbols._, Flags._, SymDenotations._, Types._, Scopes._, util.Positions._, Names._
import StdNames._, NameOps._
-import Decorators.StringDecorator
+import Decorators.{StringDecorator, StringInterpolators}
import pickling.ClassfileParser
object SymbolLoaders {
@@ -69,8 +69,8 @@ class SymbolLoaders {
// require yjp.jar at runtime. See SI-2089.
if (ctx.settings.termConflict.isDefault)
throw new TypeError(
- s"""$owner contains object and package with same name: $pname
- |one of them needs to be removed from classpath""".stripMargin)
+ sm"""$owner contains object and package with same name: $pname
+ |one of them needs to be removed from classpath""")
else if (ctx.settings.termConflict.value == "package") {
ctx.warning(
s"Resolving package/object name conflict in favor of package ${preExisting.fullName}. The object will be inaccessible.")
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index cfd5bdf23..6421018e5 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -261,16 +261,14 @@ trait Symbols { this: Context =>
newSymbol(owner, name, SyntheticArtifact,
if (name.isTypeName) TypeAlias(ErrorType) else ErrorType)
- type OwnerMap = Symbol => Symbol
-
/** Map given symbols, subjecting all types to given type map and owner map.
* Cross symbol references are brought over from originals to copies.
* Do not copy any symbols if all attributes of all symbols stay the same.
*/
def mapSymbols(
originals: List[Symbol],
- typeMap: TypeMap = IdentityTypeMap,
- ownerMap: OwnerMap = identity)
+ typeMap: Type => Type = IdentityTypeMap,
+ ownerMap: Symbol => Symbol = identity)
=
if (originals forall (sym =>
(typeMap(sym.info) eq sym.info) && (ownerMap(sym.owner) eq sym.owner)))
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 0f0747597..f2b81072a 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -48,8 +48,8 @@ class ClassfileParser(
case e: RuntimeException =>
if (ctx.debug) e.printStackTrace()
throw new IOException(
- s"""class file $classfile is broken, reading aborted with $e.getClass
- |${Option(e.getMessage).getOrElse("")}""".stripMargin)
+ sm"""class file $classfile is broken, reading aborted with $e.getClass
+ |${Option(e.getMessage).getOrElse("")}""")
}
private def parseHeader(): Unit = {
@@ -702,12 +702,12 @@ class ClassfileParser(
getMember(owner, innerName.toTypeName)
}
assert(result ne NoSymbol,
- s"""failure to resolve inner class:
- |externalName = $externalName,
- |outerName = $outerName,
- |innerName = $innerName
- |owner.fullName = owner.showFullName
- |while parsing ${classfile}""".stripMargin)
+ sm"""failure to resolve inner class:
+ |externalName = $externalName,
+ |outerName = $outerName,
+ |innerName = $innerName
+ |owner.fullName = owner.showFullName
+ |while parsing ${classfile}""")
result
case None =>
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index dd26b20df..462c10137 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -53,10 +53,10 @@ object UnPickler {
val result = restpe.parameterizeWith(tparams)
for ((msg, pos) <- err)
ctx.warning(
- s"""$msg
- |originally parsed type : ${tp.show}
- |will be approximated by: ${result.show}.
- |Proceed at own risk.""".stripMargin)
+ sm"""$msg
+ |originally parsed type : ${tp.show}
+ |will be approximated by: ${result.show}.
+ |Proceed at own risk.""")
result
}
else
@@ -161,8 +161,8 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
protected def errorBadSignature(msg: String, original: Option[RuntimeException] = None)(implicit ctx: Context) = {
val ex = new BadSignature(
- s"""error reading Scala signature of $classRoot from $source:
- |error occured at position $readIndex: $msg""".stripMargin)
+ sm"""error reading Scala signature of $classRoot from $source:
+ |error occured at position $readIndex: $msg""")
/*if (debug)*/ original.getOrElse(ex).printStackTrace() // !!! DEBUG
throw ex
}
diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala
index 27378f533..d6af96301 100644
--- a/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -48,7 +48,7 @@ import Symbols._
*
* TODO: Rename phase to "Accessors" because it handles more than just super accessors
*/
-class SuperAccessors extends MacroTransform with DenotTransformer { thisTransformer =>
+class SuperAccessors extends MacroTransform with IdentityDenotTransformer { thisTransformer =>
import tpd._
@@ -58,9 +58,6 @@ class SuperAccessors extends MacroTransform with DenotTransformer { thisTransfor
protected def newTransformer(implicit ctx: Context): Transformer =
new SuperAccTransformer
- /** No transformation here, but new denotations are installed by the tree traversal */
- def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref
-
class SuperAccTransformer extends Transformer {
/** validCurrentOwner arrives undocumented, but I reverse engineer it to be
@@ -444,10 +441,10 @@ class SuperAccessors extends MacroTransform with DenotTransformer { thisTransfor
val protectedAccessor = clazz.info.decl(accName).suchThat(_.signature == accType.signature).symbol orElse {
val newAcc = ctx.newSymbol(
clazz, accName, Artifact, accType, coord = tree.pos).enteredAfter(thisTransformer)
- val code = polyDefDef(newAcc, targs => argss => {
- val (receiver :: _) :: tail = argss
- val base = Select(receiver, sym).appliedToTypes(targs)
- (base /: argss)(Apply(_, _))
+ val code = polyDefDef(newAcc, trefs => vrefss => {
+ val (receiver :: _) :: tail = vrefss
+ val base = Select(receiver, sym).appliedToTypes(trefs)
+ (base /: vrefss)(Apply(_, _))
})
ctx.debuglog("created protected accessor: " + code)
storeAccessorDefinition(clazz, code)
@@ -474,8 +471,8 @@ class SuperAccessors extends MacroTransform with DenotTransformer { thisTransfor
val protectedAccessor = clazz.info.decl(accName).symbol orElse {
val newAcc = ctx.newSymbol(
clazz, accName, Artifact, accType, coord = tree.pos).enteredAfter(thisTransformer)
- val code = DefDef(newAcc, argss => {
- val (receiver :: value :: Nil) :: Nil = argss
+ val code = DefDef(newAcc, vrefss => {
+ val (receiver :: value :: Nil) :: Nil = vrefss
Assign(Select(receiver, field), value).withPos(tree.pos)
})
ctx.debuglog("created protected setter: " + code)
diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala
index 0b016769b..89e73013f 100644
--- a/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -127,7 +127,7 @@ object ErrorReporting {
case _ => true
}
- val s = new InfoString(sc).i(args : _*)
+ val s = new StringInterpolators(sc).i(args : _*)
if (args.forall(isSensical(_))) s else nonSensicalStartTag + s + nonSensicalEndTag
}
}
diff --git a/src/dotty/tools/dotc/typer/ImportInfo.scala b/src/dotty/tools/dotc/typer/ImportInfo.scala
index 9fbd07102..18e5db209 100644
--- a/src/dotty/tools/dotc/typer/ImportInfo.scala
+++ b/src/dotty/tools/dotc/typer/ImportInfo.scala
@@ -7,7 +7,7 @@ import ast.Trees._
import core._
import util.SimpleMap
import Symbols._, Names._, Denotations._, Types._, Contexts._, StdNames._, Flags._
-import Decorators.InfoString
+import Decorators.StringInterpolators
object ImportInfo {
/** The import info for a root import from given symbol `sym` */