From 65c1b122df4523205f813112dd0776bf2b611b3d Mon Sep 17 00:00:00 2001 From: Grzegorz Kossakowski Date: Wed, 26 Jun 2013 16:50:05 -0700 Subject: [PATCH] Add documentation for api debugging feature. Include a new section in `Understanding-incremental-compilation` document which explains in detail how to turn on and use the new api debugging feature. --- ...nderstanding-incremental-recompilation.rst | 85 +++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/src/sphinx/Detailed-Topics/Understanding-incremental-recompilation.rst b/src/sphinx/Detailed-Topics/Understanding-incremental-recompilation.rst index 53441dfdf..51b96d3ee 100644 --- a/src/sphinx/Detailed-Topics/Understanding-incremental-recompilation.rst +++ b/src/sphinx/Detailed-Topics/Understanding-incremental-recompilation.rst @@ -68,9 +68,7 @@ file: referring to a member (class, method, type, etc.) defined in some other source file -Here's an example illustrating the definition above: - -:: +Here's an example illustrating the definition above:: //A.scala class A { @@ -91,14 +89,14 @@ Here's an example illustrating the definition above: There are the following dependencies through inheritance: -:: +.. code-block:: none B.scala -> A.scala C.scala -> B.scala There are also the following member reference dependencies: -:: +.. code-block:: none D.scala -> A.scala E.scala -> D.scala @@ -159,6 +157,83 @@ just to illustrate the ideas; this list is not intended to be complete. issue `SI-2559 `_ for an example.) +Debugging an interface representation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you see spurious incremental recompilations or you want understand +what changes to an extracted interface cause incremental recompilation +then sbt 0.13 has the right tools for that. + +In order to debug the interface representation and its changes as you +modify and recompile source code you need to do two things: + + 1. Enable incremental compiler's ``apiDebug`` option. + 2. Add `diff-utils library `_ + to sbt's classpath. Check documentation of `sbt.extraClasspath` + system property in the :doc:`Command-Line-Reference`. + +.. warning:: Enabling the ``apiDebug`` option increases significantly + memory consumption and degrades performance of the + incremental compiler. The underlaying reason is that in + order to produce meaningful debugging information about + interface differences incremental compiler has to retain + the full representation of the interface instead of just + hash sum as it does by default. + + Keep this option enabled when you are debugging incremental + compiler problem only. + +Below is complete transcript which shows how to enable interface debugging +in your project. First, we download the ``diffutils`` jar and pass it +to sbt: + +.. code-block:: none + + curl -O https://java-diff-utils.googlecode.com/files/diffutils-1.2.1.jar + sbt -Dsbt.extraClasspath=diffutils-1.2.1.jar + [info] Loading project definition from /Users/grek/tmp/sbt-013/project + [info] Set current project to sbt-013 (in build file:/Users/grek/tmp/sbt-013/) + > set incOptions := incOptions.value.copy(apiDebug = true) + [info] Defining *:incOptions + [info] The new value will be used by compile:incCompileSetup, test:incCompileSetup + [info] Reapplying settings... + [info] Set current project to sbt-013 (in build file:/Users/grek/tmp/sbt-013/) + +Let's suppose you have the following source code in ``Test.scala``:: + + class A { + def b: Int = 123 + } + +compile it and then change the ``Test.scala`` file so it looks like:: + + class A { + def b: String = "abc" + } + +and run `compile` task again. Now if you run `last compile` you should see +the following lines in the debugging log + +.. code-block:: none + + > last compile + [...] + [debug] Detected a change in a public API: + [debug] --- /Users/grek/tmp/sbt-013/Test.scala + [debug] +++ /Users/grek/tmp/sbt-013/Test.scala + [debug] @@ -23,7 +23,7 @@ + [debug] ^inherited^ final def ##(): scala.this#Int + [debug] ^inherited^ final def synchronized[ java.lang.Object.T0 >: scala.this#Nothing <: scala.this#Any](x$1: ): + [debug] ^inherited^ final def $isInstanceOf[ java.lang.Object.T0 >: scala.this#Nothing <: scala.this#Any](): scala.this#Boolean + [debug] ^inherited^ final def $asInstanceOf[ java.lang.Object.T0 >: scala.this#Nothing <: scala.this#Any](): + [debug] def (): this#A + [debug] -def b: scala.this#Int + [debug] +def b: java.lang.this#String + [debug] } + +You can see an unified diff of two interface textual represetantions. As you can see, +the incremental compiler detected a change to the return type of `b` method. + How to take advantage of SBT heuristics ---------------------------------------