Skip to content

Commit

Permalink
Repl truncation copes with null
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Apr 24, 2023
1 parent e0ac98b commit 440f68d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 9 deletions.
22 changes: 13 additions & 9 deletions compiler/src/dotty/tools/repl/Rendering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,16 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
// In order to figure out if it did get truncated, we invoke it twice - once with the `maxElements` that we
// want to print, and once without a limit. If the first is shorter, truncation did occur.
val notTruncated = stringOfMaybeTruncated(value, Int.MaxValue)
val maybeTruncatedByElementCount = stringOfMaybeTruncated(value, maxElements)
val maybeTruncated = truncate(maybeTruncatedByElementCount, maxCharacters)

// our string representation may have been truncated by element and/or character count
// if so, append an info string - but only once
if (notTruncated.length == maybeTruncated.length) maybeTruncated
else s"$maybeTruncated ... large output truncated, print value to show all"
if notTruncated == null then null else
val maybeTruncated =
val maybeTruncatedByElementCount = stringOfMaybeTruncated(value, maxElements)
truncate(maybeTruncatedByElementCount, maxCharacters)

// our string representation may have been truncated by element and/or character count
// if so, append an info string - but only once
if notTruncated.length == maybeTruncated.length then maybeTruncated
else s"$maybeTruncated ... large output truncated, print value to show all"
end if
}

}
Expand All @@ -95,8 +98,9 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
"replStringOf should only be called on values creating using `classLoader()`, but `classLoader()` has not been called so far")
val maxPrintElements = ctx.settings.VreplMaxPrintElements.valueIn(ctx.settingsState)
val maxPrintCharacters = ctx.settings.VreplMaxPrintCharacters.valueIn(ctx.settingsState)
val res = myReplStringOf(value, maxPrintElements, maxPrintCharacters)
if res == null then "null // non-null reference has null-valued toString" else res
Option(value)
.flatMap(v => Option(myReplStringOf(v, maxPrintElements, maxPrintCharacters)))
.getOrElse("null // non-null reference has null-valued toString")

/** Load the value of the symbol using reflection.
*
Expand Down
9 changes: 9 additions & 0 deletions compiler/test/dotty/tools/repl/ReplCompilerTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,15 @@ class ReplCompilerTests extends ReplTest:
assertEquals("java.lang.AssertionError: assertion failed", all.head)
}

@Test def `i17333 print null result of toString`: Unit =
initially:
run("val tpolecat = new Object { override def toString(): String = null }")
.andThen:
assertEquals("val tpolecat: Object = null // non-null reference has null-valued toString", lines().head)

end ReplCompilerTests


object ReplCompilerTests:

private val pattern = Pattern.compile("\\r[\\n]?|\\n");
Expand Down

0 comments on commit 440f68d

Please sign in to comment.