From 373e8e9788a9f11c0214cd6817966025e3a93f74 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 11 Mar 2024 14:53:02 +0100 Subject: [PATCH] fix name of Ident and Select trees for module class from java --- .../dotty/tools/dotc/core/ContextOps.scala | 5 +-- .../src/dotty/tools/dotc/typer/Typer.scala | 38 +++++++++++-------- tests/run/i17255/J.java | 37 ++++++++++++------ tests/run/i17255/Module.scala | 10 +++-- 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/ContextOps.scala b/compiler/src/dotty/tools/dotc/core/ContextOps.scala index 427cfa47c7c1..57c369a08de6 100644 --- a/compiler/src/dotty/tools/dotc/core/ContextOps.scala +++ b/compiler/src/dotty/tools/dotc/core/ContextOps.scala @@ -64,10 +64,7 @@ object ContextOps: val directSearch = def asModule = if name.isTypeName && name.endsWith(StdNames.str.MODULE_SUFFIX) then - pre.findMember(name.stripModuleClassSuffix.moduleClassName, pre, required, excluded) match - case NoDenotation => NoDenotation - case symDenot: SymDenotation => - symDenot.companionModule.denot + pre.findMember(name.stripModuleClassSuffix.moduleClassName, pre, required, excluded) else NoDenotation pre.findMember(name, pre, required, excluded) match case NoDenotation => asModule diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 6d537ea62c7c..5b176a7797ee 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -631,7 +631,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer case checkedType: NamedType if !prefixIsElidable(checkedType) => ref(checkedType).withSpan(tree.span) case _ => - tree.withType(checkedType) + def isScalaModuleRef = checkedType match + case moduleRef: TypeRef if moduleRef.symbol.is(ModuleClass, butNot = JavaDefined) => true + case _ => false + if ctx.isJava && isScalaModuleRef then + cpy.Ident(tree)(tree.name.unmangleClassName).withType(checkedType) + else + tree.withType(checkedType) val tree2 = toNotNullTermRef(tree1, pt) checkLegalValue(tree2, pt) tree2 @@ -688,11 +694,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer report.error(StableIdentPattern(tree, pt), tree.srcPos) def typedSelect(tree0: untpd.Select, pt: Type, qual: Tree)(using Context): Tree = - val selName = - if ctx.isJava && tree0.name.isTypeName && tree0.name.endsWith(StdNames.str.MODULE_SUFFIX) then - tree0.name.stripModuleClassSuffix.moduleClassName - else - tree0.name + val selName = tree0.name val tree = cpy.Select(tree0)(qual, selName) val superAccess = qual.isInstanceOf[Super] val rawType = selectionType(tree, qual) @@ -769,26 +771,30 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer def typeSelectOnTerm(using Context): Tree = val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this, tree.nameSpan)) - typedSelect(tree, pt, qual).withSpan(tree.span).computeNullable() - - def javaSelectOnType(qual: Tree)(using Context) = - // semantic name conversion for `O$` in java code - if !qual.symbol.is(JavaDefined) then - val tree2 = untpd.cpy.Select(tree)(qual, tree.name.unmangleClassName) - assignType(tree2, qual) + if ctx.isJava then + javaSelection(qual) else - assignType(cpy.Select(tree)(qual, tree.name), qual) + typedSelect(tree, pt, qual).withSpan(tree.span).computeNullable() + + def javaSelection(qual: Tree)(using Context) = + val tree1 = assignType(cpy.Select(tree)(qual, tree.name), qual) + tree1.tpe match + case moduleRef: TypeRef if moduleRef.symbol.is(ModuleClass, butNot = JavaDefined) => + // handle unmangling of module names (Foo$ -> Foo[ModuleClass]) + cpy.Select(tree)(qual, tree.name.unmangleClassName).withType(moduleRef) + case _ => + tree1 def tryJavaSelectOnType(using Context): Tree = tree.qualifier match { case sel @ Select(qual, name) => val qual1 = untpd.cpy.Select(sel)(qual, name.toTypeName) val qual2 = typedType(qual1, WildcardType) - javaSelectOnType(qual2) + javaSelection(qual2) case id @ Ident(name) => val qual1 = untpd.cpy.Ident(id)(name.toTypeName) val qual2 = typedType(qual1, WildcardType) - javaSelectOnType(qual2) + javaSelection(qual2) case _ => errorTree(tree, em"cannot convert to type selection") // will never be printed due to fallback diff --git a/tests/run/i17255/J.java b/tests/run/i17255/J.java index 3c6d64d75ab9..3706e53cbbc3 100644 --- a/tests/run/i17255/J.java +++ b/tests/run/i17255/J.java @@ -1,16 +1,29 @@ package p; public class J { - public static J j = new J(); - public static p.J f() { - return p.J.j; - } - public static Module$ module2() { - return p.Module$.MODULE$; - } - public static p.Module$ module() { - return p.Module$.MODULE$; - } + public static J j = new J(); - public String toString() { return "J"; } -} \ No newline at end of file + public static p.J f() { + return p.J.j; + } + + public static Module$ module2() { + return p.Module$.MODULE$; + } + + public static p.Module$ module() { + return p.Module$.MODULE$; + } + + public static Module.InnerModule$ innermodule2() { + return p.Module.InnerModule$.MODULE$; + } + + public static p.Module.InnerModule$ innermodule() { + return p.Module.InnerModule$.MODULE$; + } + + public String toString() { + return "J"; + } +} diff --git a/tests/run/i17255/Module.scala b/tests/run/i17255/Module.scala index e681264093da..936e78e8e4ce 100644 --- a/tests/run/i17255/Module.scala +++ b/tests/run/i17255/Module.scala @@ -1,8 +1,10 @@ -// scalajs: --skip - package p { object Module { override def toString = "Module" + + object InnerModule { + override def toString = "InnerModule" + } } } @@ -10,4 +12,6 @@ object Test extends App { assert(p.J.f().toString == "J") assert(p.J.module().toString == "Module") assert(p.J.module2().toString == "Module") -} \ No newline at end of file + assert(p.J.innermodule().toString == "InnerModule") + assert(p.J.innermodule2().toString == "InnerModule") +}