diff options
author | Martin Odersky <odersky@gmail.com> | 2017-03-29 16:58:41 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-04-11 09:33:11 +0200 |
commit | a5d94d23341b2f30f677f1420f1ce088a0f1ed5b (patch) | |
tree | 8d1ce019cf60853b3f9b8ed918f122d7c3f6ac82 /compiler/src/dotty/tools/dotc | |
parent | d5c1e6dc677ef9ef49f02075747b2301ba45fd74 (diff) | |
download | dotty-a5d94d23341b2f30f677f1420f1ce088a0f1ed5b.tar.gz dotty-a5d94d23341b2f30f677f1420f1ce088a0f1ed5b.tar.bz2 dotty-a5d94d23341b2f30f677f1420f1ce088a0f1ed5b.zip |
Decentralize unmangling, add new nameKinds
Start scheme where unmangling is done by NameKinds instead of
in NameOps.
Also add namekinds for protected accessors.
Diffstat (limited to 'compiler/src/dotty/tools/dotc')
-rw-r--r-- | compiler/src/dotty/tools/dotc/ast/Desugar.scala | 4 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/NameKinds.scala (renamed from compiler/src/dotty/tools/dotc/core/NameExtractors.scala) | 26 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/NameOps.scala | 58 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/StdNames.scala | 2 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala | 4 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala | 6 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala | 3 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala | 4 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala | 10 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Applications.scala | 3 |
10 files changed, 62 insertions, 58 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index e9df66186..9cf530f8f 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -6,7 +6,7 @@ import core._ import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._ import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._ import Decorators._ -import NameKinds.{UniqueName, EvidenceParamName} +import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName} import language.higherKinds import typer.FrontEnd import collection.mutable.ListBuffer @@ -187,7 +187,7 @@ object desugar { case (vparam :: vparams) :: vparamss1 => def defaultGetter: DefDef = DefDef( - name = meth.name.defaultGetterName(n), + name = DefaultGetterName(meth.name, n), tparams = meth.tparams.map(tparam => dropContextBound(toDefParam(tparam))), vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam), n), tpt = TypeTree(), diff --git a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index 7350087a5..2c5e3ee3e 100644 --- a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -31,6 +31,7 @@ object NameKinds { override def toString = infoString } def definesNewName = false + def unmangle(name: SimpleTermName): TermName = name def mkString(underlying: TermName, info: ThisInfo): String def infoString: String } @@ -58,11 +59,17 @@ object NameKinds { extends ClassifiedNameKind(tag, if (optInfoString.isEmpty) s"Prefix $prefix" else optInfoString) { def mkString(underlying: TermName, info: ThisInfo) = underlying.mapLast(n => termName(prefix + n.toString)).toString + override def unmangle(name: SimpleTermName): TermName = + if (name.startsWith(prefix)) apply(name.drop(prefix.length).asSimpleName) + else name } class SuffixNameKind(tag: Int, suffix: String, optInfoString: String = "") extends ClassifiedNameKind(tag, if (optInfoString.isEmpty) s"Suffix $suffix" else optInfoString) { def mkString(underlying: TermName, info: ThisInfo) = underlying.toString ++ suffix + override def unmangle(name: SimpleTermName): TermName = + if (name.endsWith(suffix)) apply(name.take(name.length - suffix.length).asSimpleName) + else name } trait QualifiedInfo extends NameInfo { @@ -181,6 +188,20 @@ object NameKinds { val prefix = if (underlying.isConstructorName) nme.DEFAULT_GETTER_INIT else underlying prefix.toString + nme.DEFAULT_GETTER + (info.num + 1) } + + private val dgLen = nme.DEFAULT_GETTER.length + + override def unmangle(name: SimpleTermName): TermName = { + var i = name.length + while (i > 0 && name(i - 1).isDigit) i -= 1 + if (i > dgLen && i < name.length && name.slice(i - dgLen, i) == nme.DEFAULT_GETTER) { + val index = name.drop(i).toString.toInt - 1 + var original = name.take(i - dgLen).asTermName + if (original == nme.DEFAULT_GETTER_INIT) original = Names.CONSTRUCTOR + apply(original, index) + } + else name + } } object VariantName extends NumberedNameKind(VARIANT, "Variant") { @@ -194,6 +215,8 @@ object NameKinds { val SuperAccessorName = new PrefixNameKind(SUPERACCESSOR, "super$") val InitializerName = new PrefixNameKind(INITIALIZER, "initial$") val ShadowedName = new PrefixNameKind(SHADOWED, "(shadowed)") + val ProtectedAccessorName = new PrefixNameKind(PROTECTEDACCESSOR, "protected$") + val ProtectedSetterName = new PrefixNameKind(PROTECTEDSETTER, "protected$set") // dubious encoding, kept for Scala2 compatibility val AvoidClashName = new SuffixNameKind(AVOIDCLASH, "$_avoid_name_clash_$") val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass") @@ -216,6 +239,9 @@ object NameKinds { def infoString: String = "Signed" } + val Scala2MethodNameKinds: List[NameKind] = + List(DefaultGetterName, ProtectedAccessorName, ProtectedSetterName) + def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds def qualifiedNameKindOfSeparator: collection.Map[String, QualifiedNameKind] = qualifiedNameKinds def uniqueNameKindOfSeparator : collection.Map[String, UniqueNameKind] = uniqueNameKinds diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 356b41efb..f936e5a34 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -60,13 +60,11 @@ object NameOps { def isImplClassName = name endsWith IMPL_CLASS_SUFFIX def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX def isLoopHeaderLabel = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX) - def isProtectedAccessorName = name startsWith PROTECTED_PREFIX def isReplWrapperName = name.toSimpleName containsSlice INTERPRETER_IMPORT_WRAPPER def isSetterName = name endsWith SETTER_SUFFIX def isSingletonName = name endsWith SINGLETON_SUFFIX def isImportName = name startsWith IMPORT def isFieldName = name endsWith LOCAL_SUFFIX - def isDefaultGetterName = name.isTermName && name.asTermName.defaultGetterIndex >= 0 def isScala2LocalSuffix = name.endsWith(" ") def isModuleVarName(name: Name): Boolean = name.stripAnonNumberSuffix endsWith MODULE_VAR_SUFFIX @@ -400,54 +398,21 @@ object NameOps { name.mapLast(n => n.take(n.length - LOCAL_SUFFIX.length).asSimpleName) } - /** Nominally, name$default$N, encoded for <init> - * @param Post the parameters position. - * @note Default getter name suffixes start at 1, so `pos` has to be adjusted by +1 - */ - def defaultGetterName(pos: Int): TermName = - DefaultGetterName(name, pos) - /** Nominally, name from name$default$N, CONSTRUCTOR for <init> */ def defaultGetterToMethod: TermName = name rewrite { case DefaultGetterName(methName, _) => methName } - def defaultGetterToMethodOfMangled: TermName = { - val p = name.indexOfSlice(DEFAULT_GETTER) - if (p >= 0) { - val q = name.take(p).asTermName - // i.e., if (q.decoded == CONSTRUCTOR.toString) CONSTRUCTOR else q - if (q == DEFAULT_GETTER_INIT) CONSTRUCTOR else q - } else name - } - /** If this is a default getter, its index (starting from 0), else -1 */ def defaultGetterIndex: Int = name collect { case DefaultGetterName(_, num) => num } getOrElse -1 - def defaultGetterIndexOfMangled: Int = { - var i = name.length - while (i > 0 && name(i - 1).isDigit) i -= 1 - if (i > 0 && i < name.length && name.take(i).endsWith(DEFAULT_GETTER)) - name.drop(i).toString.toInt - 1 - else - -1 - } - def stripScala2LocalSuffix: TermName = if (name.isScala2LocalSuffix) name.init.asTermName else name - /** The name of an accessor for protected symbols. */ - def protectedAccessorName: TermName = - PROTECTED_PREFIX ++ name.unexpandedName - - /** The name of a setter for protected symbols. Used for inherited Java fields. */ - def protectedSetterName: TermName = - PROTECTED_SET_PREFIX ++ name.unexpandedName - def moduleVarName: TermName = name ++ MODULE_VAR_SUFFIX @@ -509,18 +474,25 @@ object NameOps { case name => name } - def unmangleMethodName: TermName = - if (name.isSimple) { - val idx = name.defaultGetterIndexOfMangled - if (idx >= 0) name.defaultGetterToMethodOfMangled.defaultGetterName(idx) - else name - } - else name - def unmangleSuperName: TermName = if (name.isSimple && name.startsWith(str.SUPER_PREFIX)) SuperAccessorName(name.drop(str.SUPER_PREFIX.length).asTermName) else name + + def unmangle(kind: NameKind): TermName = name rewrite { + case unmangled: SimpleTermName => + kind.unmangle(unmangled) + case ExpandedName(prefix, last) => + kind.unmangle(last) rewrite { + case kernel: SimpleTermName => + ExpandedName(prefix, kernel) + } + } + + def unmangle(kinds: List[NameKind]): TermName = { + val unmangled = (name /: kinds)(_.unmangle(_)) + if (unmangled eq name) name else unmangled.unmangle(kinds) + } } private final val FalseSuper = "$$super".toTermName diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 598d55650..7dd569d04 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -123,8 +123,6 @@ object StdNames { val OVERLOADED: N = "<overloaded>" val PACKAGE: N = "package" val PACKAGE_CLS: N = "package$" - val PROTECTED_PREFIX: N = "protected$" - val PROTECTED_SET_PREFIX: N = PROTECTED_PREFIX + "set" val ROOT: N = "<root>" val SINGLETON_SUFFIX: N = ".type" val SPECIALIZED_SUFFIX: N = "$sp" diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index 13315eb3e..b09da70e1 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -5,7 +5,7 @@ package classfile import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, Decorators._ import SymDenotations._, unpickleScala2.Scala2Unpickler._, Constants._, Annotations._, util.Positions._ -import NameKinds.ModuleClassName +import NameKinds.{ModuleClassName, DefaultGetterName} import ast.tpd._ import java.io.{ File, IOException } import java.lang.Integer.toHexString @@ -598,7 +598,7 @@ class ClassfileParser( def addDefaultGetter(attr: Symbol, n: Int) = ctx.newSymbol( owner = moduleRoot.symbol, - name = nme.CONSTRUCTOR.defaultGetterName(n), + name = DefaultGetterName(nme.CONSTRUCTOR, n), flags = attr.flags & Flags.AccessFlags, info = defn.NothingType).entered diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index 18d4a6344..f7e61c924 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -229,8 +229,10 @@ object TastyFormat { final val DEFAULTGETTER = 11 final val VARIANT = 12 final val SUPERACCESSOR = 20 - final val INITIALIZER = 21 - final val SHADOWED = 22 + final val PROTECTEDACCESSOR = 21 + final val PROTECTEDSETTER = 22 + final val INITIALIZER = 23 + final val SHADOWED = 24 final val AVOIDCLASH = 27 final val OBJECTCLASS = 29 diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 976eb5df4..e4b6faa4b 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -9,6 +9,7 @@ import java.lang.Double.longBitsToDouble import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._ import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._ +import NameKinds.Scala2MethodNameKinds import dotty.tools.dotc.typer.ProtoTypes.{FunProtoTyped, FunProto} import util.Positions._ import dotty.tools.dotc.ast.{tpd, Trees, untpd}, ast.tpd._ @@ -436,7 +437,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas if (flags is Method) { name = if (name == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR - else name.asTermName.unmangleMethodName + else name.asTermName.unmangle(Scala2MethodNameKinds) } if (flags is Scala2ExpandedName) { name = name.unmangleExpandedName diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala index 324aecdf0..db19bf6b6 100644 --- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala +++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala @@ -5,6 +5,7 @@ import ast.{Trees, tpd} import core._, core.Decorators._ import Annotations._, Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._ import Names._, NameOps._, StdNames._ +import NameKinds.DefaultGetterName import typer.Inliner import typer.ErrorReporting.cyclicErrorMsg import transform.SymUtils._ @@ -300,7 +301,8 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder sym.owner.companionModule // default getters for class constructors are found in the companion object else sym.owner - (0 until pnames.length).map(i => qual.info.member(sym.name.defaultGetterName(start + i)).exists) + (0 until pnames.length).map(i => + qual.info.member(DefaultGetterName(sym.name, start + i)).exists) } else (0 until pnames.length).map(Function.const(false)) val params = (pnames, ptypes, defaults).zipped.map((pname, ptype, isDefault) => diff --git a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala index bae1b897e..583834fb3 100644 --- a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala +++ b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala @@ -11,6 +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 Symbols._, TypeUtils._ /** This class performs the following functions: @@ -168,7 +169,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) { assert(clazz.exists, sym) ctx.debuglog("Decided for host class: " + clazz) - val accName = sym.name.protectedAccessorName + val accName = ProtectedAccessorName(sym.name) // if the result type depends on the this type of an enclosing class, the accessor // has to take an object of exactly this type, otherwise it's more general @@ -206,7 +207,8 @@ class SuperAccessors(thisTransformer: DenotTransformer) { } def isProtectedAccessor(tree: Tree)(implicit ctx: Context): Boolean = tree match { - case Apply(TypeApply(Select(_, name), _), qual :: Nil) => name.isProtectedAccessorName + case Apply(TypeApply(Select(_, name), _), qual :: Nil) => + name.is(ProtectedAccessorName) || name.is(ProtectedSetterName) case _ => false } @@ -221,7 +223,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) { assert(clazz.exists, sym) ctx.debuglog("Decided for host class: " + clazz) - val accName = sym.name.protectedAccessorName + val accName = ProtectedAccessorName(sym.name) // if the result type depends on the this type of an enclosing class, the accessor // has to take an object of exactly this type, otherwise it's more general @@ -265,7 +267,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) { assert(clazz.exists, field) ctx.debuglog("Decided for host class: " + clazz) - val accName = field.name.protectedSetterName + val accName = ProtectedSetterName(field.name) val accType = MethodType(clazz.classInfo.selfType :: field.info :: Nil, defn.UnitType) val protectedAccessor = clazz.info.decl(accName).symbol orElse { val newAcc = ctx.newSymbol( diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 1fcebf4f0..db1e0bcfb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -20,6 +20,7 @@ import Trees._ import config.Config import Names._ import StdNames._ +import NameKinds.DefaultGetterName import ProtoTypes._ import EtaExpansion._ import Inferencing._ @@ -345,7 +346,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => } val getterPrefix = if ((meth is Synthetic) && meth.name == nme.apply) nme.CONSTRUCTOR else meth.name - def getterName = getterPrefix.defaultGetterName(n) + def getterName = DefaultGetterName(getterPrefix, n) if (!meth.hasDefaultParams) EmptyTree else if (receiver.isEmpty) { |