Skip to content

Commit

Permalink
fix naming conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
iusildra committed Jul 4, 2023
1 parent 6b808e2 commit feed351
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class RuntimeDefaultValidator(val frame: JdiFrame, val logger: Logger) extends R
args: Seq[RuntimeEvaluableTree]
): Validation[RuntimeEvaluableTree] =
methodTreeByNameAndArgs(on, "apply", args)
.orElse { ArrayElemTree(on, "apply", args) }
.orElse { ArrayElemTree(on, args) }

def validateIndirectApply(
on: Validation[RuntimeTree],
Expand All @@ -192,8 +192,8 @@ class RuntimeDefaultValidator(val frame: JdiFrame, val logger: Logger) extends R
name: String,
args: Seq[RuntimeEvaluableTree]
): Validation[RuntimeEvaluableTree] =
validateIndirectApply(Valid(tree), name, args)
.orElse { methodTreeByNameAndArgs(tree, name, args) }
methodTreeByNameAndArgs(tree, name, args)
.orElse { validateIndirectApply(Valid(tree), name, args) }
.orElse { validateApply(tree, args) }
.orElse { findOuter(tree).flatMap(findMethod(_, name, args)) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ private[evaluator] class RuntimeEvaluationHelpers(frame: JdiFrame) {
encode: Boolean = true
): Validation[MethodTree] = tree match {
case ReferenceTree(ref) =>
methodsByNameAndArgs(ref, funName, args.map(_.`type`), encode).flatMap(toStaticIfNeeded(_, args, tree))
methodsByNameAndArgs(ref, funName, args.map(_.`type`), encode).flatMap {
case ModuleCall() =>
Recoverable("Accessing a module from its instanciation method is not allowed at console-level")
case mt => toStaticIfNeeded(mt, args, tree)
}
case _ => Recoverable(new IllegalArgumentException(s"Cannot find method $funName on $tree"))
}

Expand Down Expand Up @@ -242,7 +246,7 @@ private[evaluator] class RuntimeEvaluationHelpers(frame: JdiFrame) {

def searchAllClassesFor(name: String, in: Option[String]): Validation[ClassTree] = {
def fullName = in match {
case Some(value) if value == name => name // name duplication when implicit apply call
case Some(value) if value == name => name // name duplication when indirect apply call
case Some(value) => concatenateInnerTypes(value, name)
case None => name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ protected[internal] object RuntimeEvaluatorExtractors {
unapply(tree.`type`).map(_ => tree.asInstanceOf[RuntimeEvaluableTree])
}

object ModuleCall {
def unapply(m: Method): Boolean = {
val rt = m.returnTypeName
val noArgs = m.argumentTypeNames.size == 0
val isSingleton = rt.endsWith("$")
val isSingletonInstantiation = rt.stripSuffix("$").endsWith(m.name)
noArgs && isSingleton && isSingletonInstantiation
}
}

object MethodCall {
def unapply(tree: RuntimeTree): Boolean =
tree match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,9 @@ case class ArrayElemTree private (array: RuntimeEvaluableTree, index: RuntimeEva
}

object ArrayElemTree {
def apply(tree: RuntimeTree, funName: String, index: Seq[RuntimeEvaluableTree]): Validation[ArrayElemTree] = {
def apply(tree: RuntimeTree, index: Seq[RuntimeEvaluableTree]): Validation[ArrayElemTree] = {
val integerTypes = Seq("java.lang.Integer", "java.lang.Short", "java.lang.Byte", "java.lang.Character")
if (funName != "apply") Recoverable("Not an array accessor")
else if (index.size < 1 || index.size > 1) Recoverable("Array accessor must have one argument")
if (index.size < 1 || index.size > 1) Recoverable("Array accessor must have one argument")
else
(tree, tree.`type`) match {
case (tree: RuntimeEvaluableTree, arr: ArrayType) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,20 @@ object RuntimeEvaluatorEnvironments {
|
| case class Test(i: Int)
|}""".stripMargin

val staticAccess =
"""|package example
|
|object Main {
| def main(args: Array[String]): Unit = {
| val x = 1
| val test = Test(-1)
| println("ok")
| }
| def test(x: Int): String = s"int $x"
| def test(t: Test): String = s"test ${t.i}"
| case class Test(i: Int)
|}""".stripMargin
}

abstract class RuntimeEvaluatorTests(val scalaVersion: ScalaVersion) extends DebugTestSuite {
Expand All @@ -380,6 +394,8 @@ abstract class RuntimeEvaluatorTests(val scalaVersion: ScalaVersion) extends Deb
TestingDebuggee.mainClass(RuntimeEvaluatorEnvironments.outerPreEval, "example.Main", scalaVersion)
lazy val controlFlow =
TestingDebuggee.mainClass(RuntimeEvaluatorEnvironments.flowControl, "example.Main", scalaVersion)
lazy val staticAccess =
TestingDebuggee.mainClass(RuntimeEvaluatorEnvironments.staticAccess, "example.Main", scalaVersion)

protected override def defaultConfig: DebugConfig =
super.defaultConfig.copy(evaluationMode = DebugConfig.RuntimeEvaluationOnly)
Expand Down Expand Up @@ -552,7 +568,7 @@ abstract class RuntimeEvaluatorTests(val scalaVersion: ScalaVersion) extends Deb
Evaluation.success("set(1)", true),
Evaluation.success("set(2)", true),
Evaluation.success("set(new Integer(2))", true),
Evaluation.successOrIgnore("set(new Character('\u0000')).toStrign", "1", true),
Evaluation.success("set(new Character('\u0000'))", false),
Evaluation.success("set(4)", false),
Evaluation.success("seq(0).toString", "1"),
Evaluation.success("seq(2).toString", "3"),
Expand Down Expand Up @@ -765,6 +781,17 @@ abstract class RuntimeEvaluatorTests(val scalaVersion: ScalaVersion) extends Deb
Evaluation.failed("test(if(Test(-1).i == -1) Test(-1) else x)")
)
}

test(
"Should not call the apply method when calling a method with the same name as an instance with an apply method"
) {
implicit val debuggee = staticAccess
check(
Breakpoint(7),
Evaluation.success("test(-1)", "int -1"),
Evaluation.success("test(test)", "test -1")
)
}
}

/* -------------------------------------------------------------------------- */
Expand Down

0 comments on commit feed351

Please sign in to comment.