diff --git a/src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala b/src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala index b24723aa9690..eccc9d382c85 100755 --- a/src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala @@ -335,7 +335,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { coercionTo(code) } else abort( - s"Primitive operation not handled yet: ${sym.fullName}(${fun.symbol.simpleName}) at: ${tree.pos}" + s"Primitive operation not handled yet: ${sym.fullName}(${fun.symbol.name}) at: ${tree.pos}" ) } @@ -499,7 +499,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { val owner = if (hostClass == null) internalName(field.owner) else internalName(hostClass) - val fieldJName = field.javaSimpleName.toString + val fieldJName = javaName(field).toString val fieldDescr = symInfoTK(field).getDescriptor val isStatic = field.isStaticMember val opc = @@ -552,7 +552,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { case EnumTag => val sym = const.symbolValue val ownerName = internalName(sym.owner) - val fieldName = sym.javaSimpleName.toString + val fieldName = javaName(sym).toString val fieldDesc = toTypeKind(sym.tpe.underlying).getDescriptor mnode.visitFieldInsn( asm.Opcodes.GETSTATIC, @@ -1050,7 +1050,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { val receiver = if (useMethodOwner) methodOwner else hostSymbol val bmOwner = asmClassType(receiver) val jowner = bmOwner.getInternalName - val jname = method.javaSimpleName.toString + val jname = javaName(method).toString val bmType = asmMethodType(method) val mdescr = bmType.getDescriptor diff --git a/src/dotty/tools/dotc/backend/jvm/BCodeGlue.scala b/src/dotty/tools/dotc/backend/jvm/BCodeGlue.scala index d70a86043e67..8c6fa1b044f8 100755 --- a/src/dotty/tools/dotc/backend/jvm/BCodeGlue.scala +++ b/src/dotty/tools/dotc/backend/jvm/BCodeGlue.scala @@ -11,8 +11,13 @@ import scala.annotation.switch import scala.collection.{ immutable, mutable } import ast.Trees.Tree +import core.Contexts.Context import core.Types.Type import core.Symbols.{Symbol, NoSymbol} +import core.SymDenotations.SymDenotation +import core.Flags +import core.NameOps._ +import core.Names.Name /* * Immutable representations of bytecode-level types. @@ -717,4 +722,25 @@ abstract class BCodeGlue { DOUBLE -> MethodNameAndType("unboxToDouble", "(Ljava/lang/Object;)D") ) } + + def javaName(symDenot: SymDenotation): Name = { + addModuleSuffix(symDenot.name, symDenot) + } + + def javaBinaryName(symDenot: SymDenotation)(implicit ctx: Context): Name = { + addModuleSuffix(symDenot.fullNameSeparated('/'), symDenot) + } + + def javaClassName(symDenot: SymDenotation)(implicit ctx: Context): String = { + addModuleSuffix(symDenot.fullName, symDenot).toString + } + + private def addModuleSuffix(name: Name, symDenot: SymDenotation): Name = { + // TODO(lrytz): the `needsModuleSuffix` check in scalac also checks: + // !isMethod && !isImplClass && !isJavaDefined + // Moreover, it checks for the `Module` flag instead of `ModuleClass`. + // I assume only a ModuleClass should ever get a moduleClassName. + if (symDenot is Flags.ModuleClass) name.moduleClassName + else name + } } diff --git a/src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala b/src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala index 4cb9febff579..ede04577b20b 100755 --- a/src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala +++ b/src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala @@ -155,7 +155,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters { // TODO: make this next claim true, if possible // by generating valid main methods as static in module classes // not sure what the jvm allows here - // + " You can still run the program by calling it as " + sym.javaSimpleName + " instead." + // + " You can still run the program by calling it as " + javaName(sym) + " instead." ) false } @@ -919,7 +919,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters { val jReturnType = toTypeKind(methodInfo.resultType) val mdesc = BType.getMethodType(jReturnType, mkArray(paramJavaTypes)).getDescriptor - val mirrorMethodName = m.javaSimpleName.toString + val mirrorMethodName = javaName(m).toString val mirrorMethod: asm.MethodVisitor = jclass.visitMethod( flags, mirrorMethodName, @@ -1051,7 +1051,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters { def newEEE(eClass: Symbol, m: Symbol) = { EnclMethodEntry( internalName(eClass), - m.javaSimpleName.toString, + javaName(m).toString, asmMethodType(m) ) } @@ -1160,7 +1160,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters { */ def genBeanInfoClass(cls: Symbol, cunit: CompilationUnit, fieldSymbols: List[Symbol], methodSymbols: List[Symbol]): asm.tree.ClassNode = { - def javaSimpleName(s: Symbol): String = { s.javaSimpleName.toString } + def javaNameString(s: Symbol): String = javaName(s).toString innerClassBufferASM.clear() @@ -1193,7 +1193,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters { if g.isPublic && !(f.name startsWith "$") ) { // inserting $outer breaks the bean - fieldList = javaSimpleName(f) :: javaSimpleName(g) :: (if (s != NoSymbol) javaSimpleName(s) else null) :: fieldList + fieldList = javaNameString(f) :: javaNameString(g) :: (if (s != NoSymbol) javaNameString(s) else null) :: fieldList } val methodList: List[String] = @@ -1203,7 +1203,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters { !(m.name startsWith "$") && !m.isGetter && !m.isSetter) - yield javaSimpleName(m) + yield javaNameString(m) val constructor = beanInfoClass.visitMethod( asm.Opcodes.ACC_PUBLIC, diff --git a/src/dotty/tools/dotc/backend/jvm/BCodeSkelBuilder.scala b/src/dotty/tools/dotc/backend/jvm/BCodeSkelBuilder.scala index 636622e6a72a..defd9e0fc6ab 100755 --- a/src/dotty/tools/dotc/backend/jvm/BCodeSkelBuilder.scala +++ b/src/dotty/tools/dotc/backend/jvm/BCodeSkelBuilder.scala @@ -252,7 +252,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { val jfield = new asm.tree.FieldNode( flags, - f.javaSimpleName.toString, + javaName(f).toString, symInfoTK(f).getDescriptor, javagensig, null // no initial value @@ -387,7 +387,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { private def makeLocal(sym: Symbol, tk: BType): Local = { assert(!slots.contains(sym), "attempt to create duplicate local var.") assert(nxtIdx != -1, "not a valid start index") - val loc = Local(tk, sym.javaSimpleName.toString, nxtIdx, sym.isSynthetic) + val loc = Local(tk, javaName(sym).toString, nxtIdx, sym.isSynthetic) slots += (sym -> loc) assert(tk.getSize > 0, "makeLocal called for a symbol whose type is Unit.") nxtIdx += tk.getSize @@ -546,7 +546,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { assert(mnode == null, "GenBCode detected nested method.") methSymbol = dd.symbol - jMethodName = methSymbol.javaSimpleName.toString + jMethodName = javaName(methSymbol).toString returnType = asmMethodType(dd.symbol).getReturnType isMethSymStaticCtor = methSymbol.isStaticConstructor @@ -671,7 +671,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { insnModA = new asm.tree.TypeInsnNode(asm.Opcodes.NEW, className) // INVOKESPECIAL val callee = methSymbol.enclClass.primaryConstructor - val jname = callee.javaSimpleName.toString + val jname = javaName(callee).toString val jowner = internalName(callee.owner) val jtype = asmMethodType(callee).getDescriptor insnModB = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESPECIAL, jowner, jname, jtype) @@ -693,7 +693,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { // INVOKESTATIC CREATOR(): android.os.Parcelable$Creator; -- TODO where does this Android method come from? val callee = definitions.getMember(claszSymbol.companionModule, androidFieldName) val jowner = internalName(callee.owner) - val jname = callee.javaSimpleName.toString + val jname = javaName(callee).toString val jtype = asmMethodType(callee).getDescriptor insnParcA = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESTATIC, jowner, jname, jtype) // PUTSTATIC `thisName`.CREATOR; diff --git a/src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala b/src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala index 3345edfc1ac1..29e7f00a2d4b 100755 --- a/src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala +++ b/src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala @@ -124,7 +124,7 @@ abstract class BCodeTypes extends BCodeIdiomatic { defn.BoxedDoubleClass ) for(csym <- boxedClasses) { - val key = brefType(csym.javaBinaryName.toTypeName) + val key = brefType(javaBinaryName(csym).toTypeName) val tr = buildExemplar(key, csym) symExemplars.put(csym, tr) exemplars.put(tr.c, tr) @@ -401,7 +401,7 @@ abstract class BCodeTypes extends BCodeIdiomatic { return opt } - val key = brefType(csym.javaBinaryName.toTypeName) + val key = brefType(javaBinaryName(csym).toTypeName) assert(key.isNonSpecial || isCompilingStdLib, s"Not a class to track: ${csym.fullName}") // TODO accomodate the fix for SI-5031 of https://github.com/scala/scala/commit/0527b2549bcada2fda2201daa630369b377d0877 @@ -767,7 +767,7 @@ abstract class BCodeTypes extends BCodeIdiomatic { if (innerSym.originalEnclosingMethod != NoSymbol) null else { - val outerName = innerSym.rawowner.javaBinaryName + val outerName = javaBinaryName(innerSym.rawowner) if (isTopLevelModule(innerSym.rawowner)) nme.stripModuleSuffix(outerName) else outerName } @@ -787,7 +787,7 @@ abstract class BCodeTypes extends BCodeIdiomatic { ) & (INNER_CLASSES_FLAGS | asm.Opcodes.ACC_DEPRECATED) val flags = if (innerSym.isModuleClass) flagsWithFinal & ~asm.Opcodes.ACC_FINAL else flagsWithFinal // For SI-5676, object overriding. - val jname = innerSym.javaBinaryName.toString // never null + val jname = javaBinaryName(innerSym).toString // never null val oname = { // null when method-enclosed val on = outerName(innerSym) if (on == null) null else on.toString diff --git a/src/dotty/tools/dotc/backend/jvm/GenBCode.scala b/src/dotty/tools/dotc/backend/jvm/GenBCode.scala index 24542427bd84..3aa6cf11c32b 100755 --- a/src/dotty/tools/dotc/backend/jvm/GenBCode.scala +++ b/src/dotty/tools/dotc/backend/jvm/GenBCode.scala @@ -59,9 +59,9 @@ object GenBCode extends BCodeSyncAndTry { override def description = "Generate bytecode from ASTs using the ASM library" // override def erasedTypes = true // TODO(lrytz) remove, probably not necessary in dotty - private var bytecodeWriter : BytecodeWriter = null - // TODO(lrytz): pass builders around instead of storing them in fields. Builders + // TODO(lrytz): pass writer and builders around instead of storing them in fields. They // have a context, potential for memory leaks. + private var bytecodeWriter : BytecodeWriter = null private var mirrorCodeGen : JMirrorBuilder = null private var beanInfoCodeGen : JBeanInfoBuilder = null @@ -154,15 +154,15 @@ object GenBCode extends BCodeSyncAndTry { val claszSymbol = cd.symbol // GenASM checks this before classfiles are emitted, https://github.com/scala/scala/commit/e4d1d930693ac75d8eb64c2c3c69f2fc22bec739 - val lowercaseJavaClassName = claszSymbol.javaClassName.toLowerCase + val lowercaseJavaClassName = javaClassName(claszSymbol).toLowerCase caseInsensitively.get(lowercaseJavaClassName) match { case None => caseInsensitively.put(lowercaseJavaClassName, claszSymbol) case Some(dupClassSym) => - item.cunit.warning( - claszSymbol.pos, - s"Class ${claszSymbol.javaClassName} differs only in case from ${dupClassSym.javaClassName}. " + - "Such classes will overwrite one another on case-insensitive filesystems." + ctx.warning( + s"Class ${javaClassName(claszSymbol)} differs only in case from ${javaClassName(dupClassSym)}. " + + "Such classes will overwrite one another on case-insensitive filesystems.", + cunit.source.atPos(claszSymbol.pos) ) } @@ -172,13 +172,13 @@ object GenBCode extends BCodeSyncAndTry { if (claszSymbol.companionClass == NoSymbol) { mirrorCodeGen.genMirrorClass(claszSymbol, cunit) } else { - log(s"No mirror class for module with linked class: ${claszSymbol.fullName}") + ctx.log(s"No mirror class for module with linked class: ${claszSymbol.fullName}") null } } else null // -------------- "plain" class -------------- - val pcb = new PlainClassBuilder(cunit, ctx) + val pcb = new PlainClassBuilder(cunit) pcb.genPlainClass(cd) val outF = if (needsOutFolder) getOutFolder(claszSymbol, pcb.thisName, cunit) else null; val plainC = pcb.cnode @@ -298,8 +298,10 @@ object GenBCode extends BCodeSyncAndTry { // clearing maps clearBCodeTypes() - // free the Context instance reachable from BytecodeWriter + // free the reachable Context instances bytecodeWriter = null + mirrorCodeGen = null + beanInfoCodeGen = null } override def run(implicit ctx: Context): Unit = unsupported("run()") diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 5278a08d296f..0cbe22d0fbf2 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1116,7 +1116,8 @@ object SymDenotations { } // to avoid overloading ambiguities - override def fullName(implicit ctx: Context): Name = super.fullName + // TODO(lrytz) remove + // override def fullName(implicit ctx: Context): Name = super.fullName override def primaryConstructor(implicit ctx: Context): Symbol = { val cname = if (this is ImplClass) nme.IMPLCLASS_CONSTRUCTOR else nme.CONSTRUCTOR