aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-31 14:40:06 +0200
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:12 +0200
commit24f40bc76493410f2688c8a74028ecb1db7306bf (patch)
tree1376406c3114b52c62d3350805c6c6c8323ecd7e
parenta3f6ca5a5cd96e17d2f9a9c5187f45ff02b5dd61 (diff)
downloaddotty-24f40bc76493410f2688c8a74028ecb1db7306bf.tar.gz
dotty-24f40bc76493410f2688c8a74028ecb1db7306bf.tar.bz2
dotty-24f40bc76493410f2688c8a74028ecb1db7306bf.zip
Make outer select names semantic
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameKinds.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/transform/FirstTransform.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TreeChecker.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Inliner.scala9
9 files changed, 27 insertions, 24 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
index 8279c21bb..cabb83171 100644
--- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
@@ -242,6 +242,16 @@ object NameKinds {
}
}
+ /** Names of the form N_<outer>. Emitted by inliner, replaced by outer path
+ * in ExplicitOuter.
+ */
+ object OuterSelectName extends NumberedNameKind(OUTERSELECT, "OuterSelect") {
+ def mkString(underlying: TermName, info: ThisInfo) = {
+ assert(underlying.isEmpty)
+ info.num + "_<outer>"
+ }
+ }
+
val SuperAccessorName = new PrefixNameKind(SUPERACCESSOR, "super$")
val InitializerName = new PrefixNameKind(INITIALIZER, "initial$")
val ShadowedName = new PrefixNameKind(SHADOWED, "(shadowed)")
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index b262fb536..44c5c1e09 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -60,11 +60,9 @@ object NameOps {
def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
def isReplWrapperName = name.toSimpleName containsSlice INTERPRETER_IMPORT_WRAPPER
def isSetterName = name endsWith SETTER_SUFFIX
- def isImportName = name startsWith IMPORT
def isScala2LocalSuffix = name.endsWith(" ")
def isModuleVarName(name: Name): Boolean = name.exclude(UniqueName).is(ModuleVarName)
def isSelectorName = name.startsWith("_") && name.tail.forall(_.isDigit)
- def isOuterSelect = name.endsWith(nme.OUTER_SELECT)
/** Is name a variable name? */
def isVariableName: Boolean = name.length > 0 && {
@@ -247,12 +245,6 @@ object NameOps {
else -1
}
- /** The number of hops specified in an outer-select name */
- def outerSelectHops: Int = {
- require(isOuterSelect)
- name.dropRight(nme.OUTER_SELECT.length).toString.toInt
- }
-
/** The name of the generic runtime operation corresponding to an array operation */
def genericArrayOp: TermName = name match {
case nme.apply => nme.array_apply
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index b89775e9e..b5d8e356e 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -253,7 +253,6 @@ object StdNames {
val MODULE_INSTANCE_FIELD: N = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
val OUTER: N = "$outer"
val OUTER_LOCAL: N = "$outer "
- val OUTER_SELECT: N = "_<outer>" // emitted by inliner, replaced by outer path in explicitouter
val REFINE_CLASS: N = "<refinement>"
val ROOTPKG: N = "_root_"
val SELECTOR_DUMMY: N = "<unapply-selector>"
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index 04550f188..68c5bf10e 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -229,6 +229,8 @@ object TastyFormat {
final val UNIQUE = 10
final val DEFAULTGETTER = 11
final val VARIANT = 12
+ final val OUTERSELECT = 13
+
final val SUPERACCESSOR = 20
final val PROTECTEDACCESSOR = 21
final val PROTECTEDSETTER = 22
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index a6e643992..c302aa61b 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -11,6 +11,7 @@ import core.Decorators._
import core.StdNames.nme
import core.Names._
import core.NameOps._
+import core.NameKinds.OuterSelectName
import ast.Trees._
import SymUtils._
import dotty.tools.dotc.ast.tpd
@@ -61,10 +62,11 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
/** Convert a selection of the form `qual.C_<OUTER>` to an outer path from `qual` to `C` */
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
- if (tree.name.isOuterSelect)
- outer.path(start = tree.qualifier, count = tree.name.outerSelectHops)
- .ensureConforms(tree.tpe)
- else tree
+ tree.name match {
+ case OuterSelectName(_, nhops) =>
+ outer.path(start = tree.qualifier, count = nhops).ensureConforms(tree.tpe)
+ case _ => tree
+ }
/** First, add outer accessors if a class does not have them yet and it references an outer this.
* If the class has outer accessors, implement them.
diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
index 37f978f11..a3cf71ef2 100644
--- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
@@ -20,7 +20,7 @@ import scala.collection.mutable
import DenotTransformers._
import typer.Checking
import NameOps._
-import NameKinds.AvoidClashName
+import NameKinds.{AvoidClashName, OuterSelectName}
import StdNames._
@@ -77,7 +77,7 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = {
tree match {
- case Select(qual, name) if !name.isOuterSelect && tree.symbol.exists =>
+ case Select(qual, name) if !name.is(OuterSelectName) && tree.symbol.exists =>
assert(qual.tpe derivesFrom tree.symbol.owner, i"non member selection of ${tree.symbol.showLocated} from ${qual.tpe} in $tree")
case _: TypeTree =>
case _: Import | _: NamedArg | _: TypTree =>
diff --git a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
index 583834fb3..80d9091fb 100644
--- a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -11,7 +11,7 @@ import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTrans
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
import util.Positions._
import Decorators._
-import NameKinds.{ProtectedAccessorName, ProtectedSetterName}
+import NameKinds.{ProtectedAccessorName, ProtectedSetterName, OuterSelectName}
import Symbols._, TypeUtils._
/** This class performs the following functions:
@@ -152,7 +152,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
*/
private def ensureProtectedAccessOK(sel: Select, targs: List[Tree])(implicit ctx: Context) = {
val sym = sel.symbol
- if (sym.isTerm && !sel.name.isOuterSelect && needsProtectedAccessor(sym, sel.pos)) {
+ if (sym.isTerm && !sel.name.is(OuterSelectName) && needsProtectedAccessor(sym, sel.pos)) {
ctx.debuglog("Adding protected accessor for " + sel)
protectedAccessorCall(sel, targs)
} else sel
diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
index 9bb00e683..44c26ecd9 100644
--- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -13,6 +13,7 @@ import core.Flags._
import core.Constants._
import core.StdNames._
import core.NameOps._
+import core.NameKinds.OuterSelectName
import core.Decorators._
import core.TypeErasure.isErasedType
import core.Phases.Phase
@@ -339,7 +340,7 @@ class TreeChecker extends Phase with SymTransformer {
val sym = tree.symbol
if (!tpe.isInstanceOf[WithFixedSym] &&
sym.exists && !sym.is(Private) &&
- !tree.name.isOuterSelect // outer selects have effectively fixed symbols
+ !tree.name.is(OuterSelectName) // outer selects have effectively fixed symbols
) {
val qualTpe = tree.qualifier.typeOpt
val member =
diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
index eaabb0689..38a139be1 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
@@ -13,9 +13,9 @@ import Decorators._
import Constants._
import StdNames.nme
import Contexts.Context
-import Names.{Name, TermName}
+import Names.{Name, TermName, EmptyTermName}
import NameOps._
-import NameKinds.InlineAccessorName
+import NameKinds.{InlineAccessorName, OuterSelectName}
import SymDenotations.SymDenotation
import Annotations._
import transform.ExplicitOuter
@@ -399,9 +399,6 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
// The class that the this-proxy `selfSym` represents
def classOf(selfSym: Symbol) = selfSym.info.widen.classSymbol
- // The name of the outer selector that computes the rhs of `selfSym`
- def outerSelector(n: Int): TermName = n.toString.toTermName ++ nme.OUTER_SELECT
-
// The total nesting depth of the class represented by `selfSym`.
def outerLevel(selfSym: Symbol): Int = classOf(selfSym).ownersIterator.length
@@ -419,7 +416,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
if (!lastSelf.exists)
prefix
else
- untpd.Select(ref(lastSelf), outerSelector(lastLevel - level)).withType(selfSym.info)
+ untpd.Select(ref(lastSelf), OuterSelectName(EmptyTermName, lastLevel - level)).withType(selfSym.info)
bindingsBuf += ValDef(selfSym.asTerm, rhs)
lastSelf = selfSym
lastLevel = level