Skip to content

Change backend name handling #2322

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 8 commits into from
Apr 28, 2017
Merged
Show file tree
Hide file tree
Changes from 5 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
51 changes: 20 additions & 31 deletions compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import Decorators._
import tpd._

import scala.tools.asm
import StdNames.nme
import StdNames.{nme, str}
import NameOps._
import NameKinds.DefaultGetterName
import dotty.tools.dotc.core
Expand Down Expand Up @@ -161,7 +161,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def boxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map{x => // @darkdimius Are you sure this should be a def?
(x, Erasure.Boxing.boxMethod(x.asClass))
}.toMap
def unboxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap
def unboxMethods: Map[Symbol, Symbol] =
defn.ScalaValueClasses().map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap

override def isSyntheticArrayConstructor(s: Symbol) = {
s eq defn.newArrayMethod
Expand Down Expand Up @@ -244,15 +245,15 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
case ClazzTag => av.visit(name, const.typeValue.toTypeKind(bcodeStore)(innerClasesStore).toASMType)
case EnumTag =>
val edesc = innerClasesStore.typeDescriptor(const.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class.
val evalue = const.symbolValue.name.toString // value the actual enumeration value.
val evalue = const.symbolValue.name.mangledString // value the actual enumeration value.
av.visitEnum(name, edesc, evalue)
}
case t: TypeApply if (t.fun.symbol == Predef_classOf) =>
av.visit(name, t.args.head.tpe.classSymbol.denot.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType)
case t: tpd.Select =>
if (t.symbol.denot.is(Flags.Enum)) {
val edesc = innerClasesStore.typeDescriptor(t.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class.
val evalue = t.symbol.name.toString // value the actual enumeration value.
val evalue = t.symbol.name.mangledString // value the actual enumeration value.
av.visitEnum(name, edesc, evalue)
} else {
assert(toDenot(t.symbol).name.is(DefaultGetterName)) // this should be default getter. do not emmit.
Expand All @@ -262,8 +263,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
for(arg <- t.elems) { emitArgument(arrAnnotV, null, arg, bcodeStore)(innerClasesStore) }
arrAnnotV.visitEnd()

case Apply(fun, args) if (fun.symbol == defn.ArrayClass.primaryConstructor ||
(toDenot(fun.symbol).owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply)) =>
case Apply(fun, args) if fun.symbol == defn.ArrayClass.primaryConstructor ||
toDenot(fun.symbol).owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply =>
val arrAnnotV: AnnotationVisitor = av.visitArray(name)

var actualArgs = if (fun.tpe.isInstanceOf[ImplicitMethodType]) {
Expand Down Expand Up @@ -311,7 +312,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
private def emitAssocs(av: asm.AnnotationVisitor, assocs: List[(Name, Object)], bcodeStore: BCodeHelpers)
(innerClasesStore: bcodeStore.BCInnerClassGen) = {
for ((name, value) <- assocs)
emitArgument(av, name.toString, value.asInstanceOf[Tree], bcodeStore)(innerClasesStore)
emitArgument(av, name.mangledString, value.asInstanceOf[Tree], bcodeStore)(innerClasesStore)
av.visitEnd()
}

Expand Down Expand Up @@ -360,9 +361,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
else clazz.getName
}

def requiredClass[T](implicit evidence: ClassTag[T]): Symbol = {
def requiredClass[T](implicit evidence: ClassTag[T]): Symbol =
ctx.requiredClass(erasureString(evidence.runtimeClass).toTermName)
}

def requiredModule[T](implicit evidence: ClassTag[T]): Symbol = {
val moduleName = erasureString(evidence.runtimeClass)
Expand Down Expand Up @@ -404,16 +404,15 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def newAnyRefMap[K <: AnyRef, V](): mutable.AnyRefMap[K, V] = new mutable.AnyRefMap[K, V]()
def newWeakMap[K, V](): mutable.WeakHashMap[K, V] = new mutable.WeakHashMap[K, V]()
def recordCache[T <: Clearable](cache: T): T = cache
def newWeakSet[K <: AnyRef](): WeakHashSet[K] = new WeakHashSet[K]()
def newWeakSet[K >: Null <: AnyRef](): WeakHashSet[K] = new WeakHashSet[K]()
def newMap[K, V](): mutable.HashMap[K, V] = new mutable.HashMap[K, V]()
def newSet[K](): mutable.Set[K] = new mutable.HashSet[K]
}

val MODULE_INSTANCE_FIELD: String = str.MODULE_INSTANCE_FIELD


val MODULE_INSTANCE_FIELD: String = nme.MODULE_INSTANCE_FIELD.toString

def internalNameString(offset: Int, length: Int): String = new String(Names.chrs, offset, length)
def dropModule(str: String) =
if (!str.isEmpty && str.last == '$') str.take(str.length - 1) else str

def newTermName(prefix: String): Name = prefix.toTermName

Expand All @@ -424,7 +423,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
Flags.Bridge | Flags.VBridge | Flags.Private | Flags.Macro
}.bits


def isQualifierSafeToElide(qual: Tree): Boolean = tpd.isIdempotentExpr(qual)
def desugarIdent(i: Ident): Option[tpd.Select] = {
i.tpe match {
Expand Down Expand Up @@ -537,32 +535,25 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}
}


implicit def nameHelper(n: Name): NameHelper = new NameHelper {
def toTypeName: Name = n.toTypeName
def isTypeName: Boolean = n.isTypeName
def toTermName: Name = n.toTermName
def dropModule: Name = n.stripModuleClassSuffix

def len: Int = n.toSimpleName.length
def offset: Int = n.toSimpleName.start
def isTermName: Boolean = n.isTermName
def startsWith(s: String): Boolean = n.startsWith(s)
def mangledString: String = n.mangledString
}


implicit def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper {
// names
def fullName(sep: Char): String = sym.showFullName
def fullName: String = sym.showFullName
def simpleName: Name = sym.name
def javaSimpleName: Name = toDenot(sym).name // addModuleSuffix(simpleName.dropLocal)
def javaBinaryName: Name = javaClassName.replace('.', '/').toTypeName // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/'))
def javaClassName: String = toDenot(sym).fullName.toString// addModuleSuffix(fullNameInternal('.')).toString
def javaSimpleName: String = toDenot(sym).name.mangledString // addModuleSuffix(simpleName.dropLocal)
def javaBinaryName: String = javaClassName.replace('.', '/') // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This TODO is no longer necessary.

def javaClassName: String = toDenot(sym).fullName.mangledString // addModuleSuffix(fullNameInternal('.')).toString
def name: Name = sym.name
def rawname: Name = {
def rawname: String = {
val original = toDenot(sym).initial
sym.name(ctx.withPhase(original.validFor.phaseId))
sym.name(ctx.withPhase(original.validFor.phaseId)).mangledString
}

// types
Expand Down Expand Up @@ -675,9 +666,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}
def enclClass: Symbol = toDenot(sym).enclosingClass
def linkedClassOfClass: Symbol = linkedClass
def linkedClass: Symbol = {
toDenot(sym)(ctx).linkedClass(ctx)
} //exitingPickler(sym.linkedClassOfClass)
def linkedClass: Symbol = toDenot(sym)(ctx).linkedClass(ctx) //exitingPickler(sym.linkedClassOfClass)
def companionClass: Symbol = toDenot(sym).companionClass
def companionModule: Symbol = toDenot(sym).companionModule
def companionSymbol: Symbol = if (sym is Flags.Module) companionClass else companionModule
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/backend/jvm/GenBCode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter

if (claszSymbol.isClass) // @DarkDimius is this test needed here?
for (binary <- ctx.compilationUnit.pickled.get(claszSymbol.asClass)) {
val dataAttr = new CustomAttr(nme.TASTYATTR.toString, binary)
val dataAttr = new CustomAttr(nme.TASTYATTR.mangledString, binary)
val store = if (mirrorC ne null) mirrorC else plainC
store.visitAttribute(dataAttr)
if (ctx.settings.emitTasty.value) {
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ object Denotations {
def hasUniqueSym: Boolean
protected def newLikeThis(symbol: Symbol, info: Type): SingleDenotation

final def signature(implicit ctx: Context): Signature = {
final def signature(implicit ctx: Context): Signature =
if (isType) Signature.NotAMethod // don't force info if this is a type SymDenotation
else info match {
case info: MethodicType =>
Expand All @@ -594,7 +594,6 @@ object Denotations {
}
case _ => Signature.NotAMethod
}
}

def derivedSingleDenotation(symbol: Symbol, info: Type)(implicit ctx: Context): SingleDenotation =
if ((symbol eq this.symbol) && (info eq this.info)) this
Expand Down
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Names.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ object Names {
def asSimpleName: SimpleTermName
def toSimpleName: SimpleTermName
def mangled: Name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to add some documentation on the meaning/use of mangled.

def mangledString: String = mangled.toString

def rewrite(f: PartialFunction[Name, Name]): ThisName
def collect[T](f: PartialFunction[Name, T]): Option[T]
Expand Down Expand Up @@ -287,7 +288,8 @@ object Names {
override def hashCode: Int = start

override def toString =
if (length == 0) "" else new String(chrs, start, length)
if (length == 0) ""
else new String(chrs, start, length)

def debugString: String = toString
}
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/StdNames.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ object StdNames {
final val INTERPRETER_LINE_PREFIX = "line"
final val INTERPRETER_VAR_PREFIX = "res"
final val INTERPRETER_WRAPPER_SUFFIX = "$object"
final val MODULE_INSTANCE_FIELD = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"

final val Function = "Function"
final val ImplicitFunction = "ImplicitFunction"
Expand Down