Skip to content

Commit

Permalink
fix name of Ident and Select trees for module class from java
Browse files Browse the repository at this point in the history
  • Loading branch information
bishabosha committed Mar 11, 2024
1 parent a4a379f commit 373e8e9
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 35 deletions.
5 changes: 1 addition & 4 deletions compiler/src/dotty/tools/dotc/core/ContextOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 22 additions & 16 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
37 changes: 25 additions & 12 deletions tests/run/i17255/J.java
Original file line number Diff line number Diff line change
@@ -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"; }
}
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";
}
}
10 changes: 7 additions & 3 deletions tests/run/i17255/Module.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// scalajs: --skip

package p {
object Module {
override def toString = "Module"

object InnerModule {
override def toString = "InnerModule"
}
}
}

object Test extends App {
assert(p.J.f().toString == "J")
assert(p.J.module().toString == "Module")
assert(p.J.module2().toString == "Module")
}
assert(p.J.innermodule().toString == "InnerModule")
assert(p.J.innermodule2().toString == "InnerModule")
}

0 comments on commit 373e8e9

Please sign in to comment.