Skip to content

Commit 3149a0c

Browse files
committed
Allow classOf[Foo.type] if Foo is an object
And use this in SyntheticMethods instead of the impossible-to-write-in-user-code `classOf[Foo$]`. This is necessary if we want decompilation to produce valid source code for objects. Note that the decompilation printer is currently wrong here and will print `classOf[Foo]` instead of `classOf[Foo.type]`.
1 parent 03ed10e commit 3149a0c

File tree

4 files changed

+10
-4
lines changed

4 files changed

+10
-4
lines changed

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
471471

472472
def toText(const: Constant): Text = const.tag match {
473473
case StringTag => stringText("\"" + escapedString(const.value.toString) + "\"")
474-
case ClazzTag => "classOf[" ~ toText(const.typeValue.classSymbol) ~ "]"
474+
case ClazzTag => "classOf[" ~ toText(const.typeValue) ~ "]"
475475
case CharTag => literalText(s"'${escapedChar(const.charValue)}'")
476476
case LongTag => literalText(const.longValue.toString + "L")
477477
case EnumTag => literalText(const.symbolValue.name.toString)

compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ class SyntheticMethods(thisPhase: DenotTransformer) {
264264
/** If this is a serializable static object `Foo`, add the method:
265265
*
266266
* private def writeReplace(): AnyRef =
267-
* new scala.runtime.ModuleSerializationProxy(classOf[Foo$])
267+
* new scala.runtime.ModuleSerializationProxy(classOf[Foo.type])
268268
*
269269
* unless an implementation already exists, otherwise do nothing.
270270
*/
@@ -280,7 +280,7 @@ class SyntheticMethods(thisPhase: DenotTransformer) {
280280
DefDef(writeReplace,
281281
_ => New(defn.ModuleSerializationProxyType,
282282
defn.ModuleSerializationProxyConstructor,
283-
List(Literal(Constant(clazz.typeRef)))))
283+
List(Literal(Constant(clazz.sourceModule.termRef)))))
284284
.withSpan(ctx.owner.span.focus))
285285
}
286286
else

compiler/src/dotty/tools/dotc/typer/Applications.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
907907
if (typedArgs.length <= pt.paramInfos.length && !isNamed)
908908
if (typedFn.symbol == defn.Predef_classOf && typedArgs.nonEmpty) {
909909
val arg = typedArgs.head
910-
checkClassType(arg.tpe, arg.sourcePos, traitReq = false, stablePrefixReq = false)
910+
if (!arg.symbol.is(Module)) // Allow `classOf[Foo.type]` if `Foo` is an object
911+
checkClassType(arg.tpe, arg.sourcePos, traitReq = false, stablePrefixReq = false)
911912
}
912913
case _ =>
913914
}

tests/run/classof-object.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
assert(classOf[Test.type] == Test.getClass)
4+
}
5+
}

0 commit comments

Comments
 (0)