ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional IContract.java
Date Tue, 10 Apr 2001 05:06:47 GMT
donaldp     01/04/09 22:06:47

  Modified:    docs/manual/OptionalTasks icontract.html
               src/main/org/apache/tools/ant/taskdefs/optional
                        IContract.java
  Log:
  Updated icontract task
  
  Submitted By: aslak.hellesoy@bekk.no
  
  Revision  Changes    Path
  1.4       +94 -35    jakarta-ant/docs/manual/OptionalTasks/icontract.html
  
  Index: icontract.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/manual/OptionalTasks/icontract.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- icontract.html	2001/02/25 05:31:47	1.3
  +++ icontract.html	2001/04/10 05:06:46	1.4
  @@ -9,11 +9,18 @@
   
   <h2><a name="icontract">icontract</a></h2>
   <h3>Description</h3>
  -<p>Instruments Java classes with <a href="http://www.reliable-systems.com/tools/">iContract</a>
  -DBC preprocessor.
   
  +<P>
  +Instruments Java classes with <a href="http://www.reliable-systems.com/tools/">iContract</a>
  + DBC preprocessor.<br>
  + The task can generate a properties file for <a href="http://home.sol.no/~hellesoy/icplus.html">iControl</a>,
  + a graphical user interface that lets you turn on/off assertions. iControl generates a
control file that you can refer to
  + from this task using the controlfile attribute.
  + <p/>
  +&nbsp;
  +
   <h3>Parameters</h3>
  -<table border="1" cellpadding="2" cellspacing="0">
  + <table border="1" cellpadding="2" cellspacing="0">
      <tr>
        <td valign="top"><b>Attribute</b></td>
        <td valign="top"><b>Description</b></td>
  @@ -21,37 +28,54 @@
      </tr>
      <tr>
        <td valign="top">srcdir</td>
  -     <td valign="top">Location of the java files</td>
  +     <td valign="top">Location of the java files.</td>
        <td valign="top" align="center">Yes</td>
      </tr>
      <tr>
        <td valign="top">instrumentdir</td>
  -     <td valign="top">Indicates where the instrumented java and class files
  -       should go</td>
  +     <td valign="top">Indicates where the instrumented source files should go.</td>
        <td valign="top" align="center">Yes</td>
      </tr>
      <tr>
        <td valign="top">repositorydir</td>
  -     <td valign="top">Indicates where the repository java and class files should
  -       go</td>
  +     <td valign="top">Indicates where the repository source files should go.</td>
        <td valign="top" align="center">Yes</td>
      </tr>
      <tr>
  +     <td valign="top">builddir</td>
  +     <td valign="top">Indicates where the compiled instrumented classes should go.
  +       Defaults to the value of instrumentdir.
  +       </p>
  +       <em>NOTE:</em> Don't use the same directory for compiled instrumented
classes
  +       and uninstrumented classes. It will break the dependency checking. (Classes will
  +       not be reinstrumented if you change them).</td>
  +     <td valign="top" align="center">No</td>
  +   </tr>
  +   <tr>
  +     <td valign="top">repositorybuilddir</td>
  +     <td valign="top">Indicates where the compiled repository classes should go.
  +       Defaults to the value of repositorydir.</td>
  +     <td valign="top" align="center">No</td>
  +   </tr>
  +   <tr>
        <td valign="top">pre</td>
        <td valign="top">Indicates whether or not to instrument for preconditions.
  -       Defaults to <code>true</code></td>
  +       Defaults to <code>true</code> unless controlfile is specified, in which
case it
  +       defaults to <code>false</code>.</td>
        <td valign="top" align="center">No</td>
      </tr>
      <tr>
        <td valign="top">post</td>
        <td valign="top">Indicates whether or not to instrument for postconditions.
  -       Defaults to <code>true</code></td>
  +       Defaults to <code>true</code> unless controlfile is specified, in which
case it
  +       defaults to <code>false</code>.</td>
        <td valign="top" align="center">No</td>
      </tr>
      <tr>
        <td valign="top">invariant</td>
        <td valign="top">Indicates whether or not to instrument for invariants.
  -       Defaults to <code>true</code></td>
  +       Defaults to <code>true</code> unless controlfile is specified, in which
case it
  +       defaults to <code>false</code>.</td>
        <td valign="top" align="center">No</td>
      </tr>
      <tr>
  @@ -61,44 +85,79 @@
        <td valign="top" align="center">No</td>
      </tr>
      <tr>
  -     <td valign="top">controlfile</td>
  -     <td valign="top">The name of the control file to pass to iContract. Default
  -       is to not pass a file</td>
  +     <td valign="top">verbosity</td>
  +     <td valign="top">Indicates the verbosity level of iContract. Any combination
  +       of <code>error*,warning*,note*,info*,progress*,debug*</code> (comma
separated) can be
  +       used. Defaults to <code>error*</code></td>
        <td valign="top" align="center">No</td>
      </tr>
      <tr>
  -     <td valign="top">verbosity</td>
  -     <td valign="top">Indicates the verbosity level of iContract. Any combination
  -       of error*,warning*,note*,info*,progress*,debug* (comma separated) can be
  -       used. Defaults to <code>error*,warning*</code></td>
  +     <td valign="top">quiet</td>
  +     <td valign="top">Indicates if iContract should be quiet. Turn it off if many
your classes extend uninstrumented classes
  +     and you don't want warnings about this. Defaults to <code>false</code></td>
        <td valign="top" align="center">No</td>
      </tr>
  +   <tr>
  +     <td valign="top">updateicontrol</td>
  +     <td valign="top">If set to true, it indicates that the properties file for
  +       iControl in the current directory should be updated (or created if it doesn't exist).
  +       Defaults to <code>false</code>.</td>
  +     <td valign="top" align="center">No</td>
  +   </tr>
  +   <tr>
  +     <td valign="top">controlfile</td>
  +     <td valign="top">The name of the control file to pass to iContract. Consider
using iControl to generate the file.
  +       Default is not to pass a file. </td>
  +     <td valign="top" align="center">Only if <code>updateicontrol=true</code></td>
  +   </tr>
  +   <tr>
  +     <td valign="top">classdir</td>
  +     <td valign="top">Indicates where compiled (unistrumented) classes are located.
  +       This is required in order to properly update the icontrol.properties file, not
  +       for instrumentation.</td>
  +     <td valign="top" align="center">Only if <code>updateicontrol=true</code></td>
  +   </tr>
  +   <tr>
  +     <td valign="top">targets</td>
  +     <td valign="top">Name of the file that will be generated by this task, which
lists all the
  +        classes that iContract will instrument. If specified, the file will not be deleted
after execution.
  +        If not specified, a file will still be created, but it will be deleted after execution.</td>
  +     <td valign="top" align="center">No</td>
  +   </tr>
    </table>
   
  +<p>
  + <b>Note:</b> iContract will use the java compiler indicated by the project's
  + <code>build.compiler</code> property. See documentation of the Javac task
for
  + more information. Nested includes and excludes are also supported.</p>
  +
  + <p><b>Example:</b></p>
  +
    <p/>
    <b>Note:</b> iContract will use the java compiler indicated by the project's
  - <code>build.compiler</code> property. See documentation for the Javac task
for
  + <code>build.compiler</code> property. See documentation of the Javac task
for
    more information.
  + <p/>
  + Nested includes and excludes can be done very much the same way as any subclass
  + of MatchingTask.
   
    <p><b>Example:</b></p>
   
    <pre>
  - &lt;!-- =================================================================== -->
  - &lt;!-- Instruments source codes with iContract                             -->
  - &lt;!-- =================================================================== -->
  - &lt;target name="instrument" depends="compile">
  -   &lt;icontract
  -     srcdir="${build.src}"
  -     instrumentdir="${instrumented.dir}"
  -     repositorydir="${repository.dir}"
  -   >
  -     &lt;classpath>
  -       &lt;fileset dir="./lib">
  -         &lt;include name="*.jar"/>
  -       &lt;/fileset>
  -     &lt;/classpath>
  -   &lt;/icontract>
  - &lt;/target>
  + &lt;icontract
  +    srcdir=&quot;${build.src}&quot;
  +    instrumentdir=&quot;${build.instrument}&quot;
  +    repositorydir=&quot;${build.repository}&quot;
  +    builddir=&quot;${build.instrclasses}&quot;
  +    updateicontrol=&quot;true&quot;
  +    classdir=&quot;${build.classes}&quot;
  +    controlfile=&quot;control&quot;
  +    targets=&quot;targets&quot;
  +    verbosity=&quot;error*,warning*&quot;
  +    quiet=&quot;true&quot;
  + &gt;
  +    &lt;classpath refid=&quot;compile-classpath&quot;/&gt;
  + &lt;/icontract&gt;
   </pre>
   
   <hr>
  
  
  
  1.3       +287 -138  jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/IContract.java
  
  Index: IContract.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/IContract.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- IContract.java	2001/02/27 02:26:28	1.2
  +++ IContract.java	2001/04/10 05:06:47	1.3
  @@ -57,6 +57,7 @@
   
   
   
  +
   import java.io.File;
   import java.io.FileInputStream;
   import java.io.FileOutputStream;
  @@ -69,16 +70,24 @@
   import org.apache.tools.ant.BuildListener;
   import org.apache.tools.ant.DirectoryScanner;
   import org.apache.tools.ant.Project;
  -import org.apache.tools.ant.Task;
   import org.apache.tools.ant.taskdefs.Java;
  +import org.apache.tools.ant.taskdefs.Javac;
  +import org.apache.tools.ant.taskdefs.MatchingTask;
   import org.apache.tools.ant.taskdefs.Mkdir;
  +import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter;
   import org.apache.tools.ant.types.FileSet;
   import org.apache.tools.ant.types.Path;
   import org.apache.tools.ant.types.Reference;
   
   /**
  - * Instruments Java classes with <a href="http://www.reliable-systems.com/tools/">iContract<a>
  + * Instruments Java classes with <a href="http://www.reliable-systems.com/tools/">iContract</a>
    * DBC preprocessor.
  + * <br/>
  + * The task can generate a properties file for <a href="http://hjem.sol.no/hellesoy/icontrol.html">iControl</a>,
  + * a graphical user interface that lets you turn on/off assertions. iControl generates
a control file that you can refer to
  + * from this task using the controlfile attribute.
  + * <p/>
  + * Thanks to Rainer Schmitz for enhancements and comments.
    *
    * @author <a href="mailto:aslak.hellesoy@bekk.no">Aslak Helles°y</a>
    *
  @@ -91,37 +100,54 @@
    *   </tr>
    *   <tr>
    *     <td valign="top">srcdir</td>
  - *     <td valign="top">Location of the java files</td>
  + *     <td valign="top">Location of the java files.</td>
    *     <td valign="top" align="center">Yes</td>
    *   </tr>
    *   <tr>
    *     <td valign="top">instrumentdir</td>
  - *     <td valign="top">Indicates where the instrumented java and class files
  - *       should go</td>
  + *     <td valign="top">Indicates where the instrumented source files should go.</td>
    *     <td valign="top" align="center">Yes</td>
    *   </tr>
    *   <tr>
    *     <td valign="top">repositorydir</td>
  - *     <td valign="top">Indicates where the repository java and class files should
  - *       go</td>
  + *     <td valign="top">Indicates where the repository source files should go.</td>
    *     <td valign="top" align="center">Yes</td>
    *   </tr>
    *   <tr>
  + *     <td valign="top">builddir</td>
  + *     <td valign="top">Indicates where the compiled instrumented classes should
go.
  + *       Defaults to the value of instrumentdir.
  + *       </p>
  + *       <em>NOTE:</em> Don't use the same directory for compiled instrumented
classes
  + *       and uninstrumented classes. It will break the dependency checking. (Classes will
  + *       not be reinstrumented if you change them).</td>
  + *     <td valign="top" align="center">No</td>
  + *   </tr>
  + *   <tr>
  + *     <td valign="top">repositorybuilddir</td>
  + *     <td valign="top">Indicates where the compiled repository classes should go.
  + *       Defaults to the value of repositorydir.</td>
  + *     <td valign="top" align="center">No</td>
  + *   </tr>
  + *   <tr>
    *     <td valign="top">pre</td>
    *     <td valign="top">Indicates whether or not to instrument for preconditions.
  - *       Defaults to <code>true</code></td>
  + *       Defaults to <code>true</code> unless controlfile is specified, in
which case it
  + *       defaults to <code>false</code>.</td>
    *     <td valign="top" align="center">No</td>
    *   </tr>
    *   <tr>
    *     <td valign="top">post</td>
    *     <td valign="top">Indicates whether or not to instrument for postconditions.
  - *       Defaults to <code>true</code></td>
  + *       Defaults to <code>true</code> unless controlfile is specified, in
which case it
  + *       defaults to <code>false</code>.</td>
    *     <td valign="top" align="center">No</td>
    *   </tr>
    *   <tr>
    *     <td valign="top">invariant</td>
    *     <td valign="top">Indicates whether or not to instrument for invariants.
  - *       Defaults to <code>true</code></td>
  + *       Defaults to <code>true</code> unless controlfile is specified, in
which case it
  + *       defaults to <code>false</code>.</td>
    *     <td valign="top" align="center">No</td>
    *   </tr>
    *   <tr>
  @@ -131,56 +157,81 @@
    *     <td valign="top" align="center">No</td>
    *   </tr>
    *   <tr>
  - *     <td valign="top">controlfile</td>
  - *     <td valign="top">The name of the control file to pass to iContract. Default
  - *       is to not pass a file</td>
  - *     <td valign="top" align="center">No</td>
  - *   </tr>
  - *   <tr>
    *     <td valign="top">verbosity</td>
    *     <td valign="top">Indicates the verbosity level of iContract. Any combination
  - *       of error*,warning*,note*,info*,progress*,debug* (comma separated) can be
  + *       of <code>error*,warning*,note*,info*,progress*,debug*</code> (comma
separated) can be
    *       used. Defaults to <code>error*</code></td>
    *     <td valign="top" align="center">No</td>
    *   </tr>
    *   <tr>
  + *     <td valign="top">quiet</td>
  + *     <td valign="top">Indicates if iContract should be quiet. Turn it off if many
your classes extend uninstrumented classes
  + *     and you don't want warnings about this. Defaults to <code>false</code></td>
  + *     <td valign="top" align="center">No</td>
  + *   </tr>
  + *   <tr>
    *     <td valign="top">updateicontrol</td>
    *     <td valign="top">If set to true, it indicates that the properties file for
  - *       icontrol in the current directory should be updated (or created if it doesn't
exist)</td>
  + *       iControl in the current directory should be updated (or created if it doesn't
exist).
  + *       Defaults to <code>false</code>.</td>
  + *     <td valign="top" align="center">No</td>
  + *   </tr>
  + *   <tr>
  + *     <td valign="top">controlfile</td>
  + *     <td valign="top">The name of the control file to pass to iContract. Consider
using iControl to generate the file.
  + *       Default is not to pass a file. </td>
  + *     <td valign="top" align="center">Only if <code>updateicontrol=true</code></td>
  + *   </tr>
  + *   <tr>
  + *     <td valign="top">classdir</td>
  + *     <td valign="top">Indicates where compiled (unistrumented) classes are located.
  + *       This is required in order to properly update the icontrol.properties file, not
  + *       for instrumentation.</td>
  + *     <td valign="top" align="center">Only if <code>updateicontrol=true</code></td>
  + *   </tr>
  + *   <tr>
  + *     <td valign="top">targets</td>
  + *     <td valign="top">Name of the file that will be generated by this task, which
lists all the
  + *        classes that iContract will instrument. If specified, the file will not be deleted
after execution.
  + *        If not specified, a file will still be created, but it will be deleted after
execution.</td>
    *     <td valign="top" align="center">No</td>
    *   </tr>
    * </table>
    *
    * <p/>
    * <b>Note:</b> iContract will use the java compiler indicated by the project's
  - * <code>build.compiler</code> property. See documentation for the Javac task
for
  + * <code>build.compiler</code> property. See documentation of the Javac task
for
    * more information.
  + * <p/>
  + * Nested includes and excludes are also supported.
    *
    * <p><b>Example:</b></p>
  - *
    * <pre>
  - * &lt;!-- =================================================================== -->
  - * &lt;!-- Instruments source codes with iContract                             -->
  - * &lt;!-- =================================================================== -->
  - * &lt;target name="instrument" depends="compile">
  - *   &lt;icontract
  - *     srcdir="${build.src}"
  - *     instrumentdir="${instrumented.dir}"
  - *     repositorydir="${repository.dir}"
  - *     updateicontrol="true"
  - *   >
  - *     &lt;classpath>
  - *       &lt;fileset dir="./lib">
  - *         &lt;include name="*.jar"/>
  - *       &lt;/fileset>
  - *     &lt;/classpath>
  - *   &lt;/icontract>
  - * &lt;/target>
  + * &lt;icontract
  + *    srcdir="${build.src}"
  + *    instrumentdir="${build.instrument}"
  + *    repositorydir="${build.repository}"
  + *    builddir="${build.instrclasses}"
  + *    updateicontrol="true"
  + *    classdir="${build.classes}"
  + *    controlfile="control"
  + *    targets="targets"
  + *    verbosity="error*,warning*"
  + *    quiet="true"
  + * >
  + *    &lt;classpath refid="compile-classpath"/>
  + * &lt;/icontract>
    * </pre>
    *
    */
  -public class IContract extends Task {
  +public class IContract extends MatchingTask {
   
  +    private static final String ICONTROL_PROPERTIES_HEADER =
  +        " You might want to set classRoot to point to your normal compilation class root
directory.";
  +
  +    private static final String ICONTROL_PROPERTIES_MESSAGE =
  +        "You should probably modify icontrol.properties' classRoot to where comiled (uninstrumented)
classes go.";
  +
       /** \ on windows, / on linux/unix */
       private static final String ps = System.getProperty( "path.separator" );
   
  @@ -199,12 +250,18 @@
       /** source file root */
       private File srcDir = null;
   
  -    /** instrumentation root */
  +    /** instrumentation src root */
       private File instrumentDir = null;
  +
  +    /** instrumentation build root */
  +    private File buildDir = null;
   
  -    /** repository root */
  +    /** repository src root */
       private File repositoryDir = null;
   
  +    /** repository build root */
  +    private File repBuildDir = null;
  +
       /** classpath */
       private Path classpath = null;
   
  @@ -214,6 +271,9 @@
       /** The -v option */
       private String verbosity = "error*";
   
  +    /** The -q option */
  +    private boolean quiet = false;
  +
       /** Indicates whether or not to use internal compilation */
       private boolean internalcompilation = false;
   
  @@ -222,16 +282,19 @@
   
       /** Indicates whether or not to instrument for preconditions */
       private boolean pre = true;
  +    private boolean preModified = false;
   
       /** Indicates whether or not to instrument for postconditions */
       private boolean post = true;
  +    private boolean postModified = false;
   
       /** Indicates whether or not to instrument for invariants */
       private boolean invariant = true;
  +    private boolean invariantModified = false;
   
       /** Indicates whether or not to instrument all files regardless of timestamp */
       // can't be explicitly set, is set if control file exists and is newer than any source
file
  -    private boolean instrumentall = true;
  +    private boolean instrumentall = false;
   
       /**
        * Indicates the name of a properties file (intentionally for iControl) where the classpath
  @@ -240,6 +303,11 @@
       private boolean updateIcontrol = false;
   
       /**
  +     * Regular compilation class root
  +     */
  +    private File classDir = null;
  +
  +    /**
        * Sets the source directory
        *
        * @param srcDir the source directory
  @@ -249,30 +317,64 @@
       }
   
       /**
  +     * Sets the class directory (uninstrumented classes)
  +     *
  +     * @param srcDir the source directory
  +     */
  +    public void setClassdir( File classDir ) {
  +        this.classDir = classDir;
  +    }
  +
  +    /**
        * Sets the instrumentation directory
        *
        * @param instrumentDir the source directory
        */
       public void setInstrumentdir( File instrumentDir ) {
           this.instrumentDir = instrumentDir;
  +        if ( this.buildDir == null ) {
  +            setBuilddir( instrumentDir );
  +        }
       }
   
       /**
  -     * Sets the repository directory
  +     * Sets the build directory for instrumented classes
        *
  +     * @param buildDir the build directory
  +     */
  +    public void setBuilddir( File buildDir ) {
  +        this.buildDir = buildDir;
  +    }
  +
  +    /**
  +     * Sets the build directory for repository classes
  +     *
        * @param repositoryDir the source directory
        */
       public void setRepositorydir( File repositoryDir ) {
           this.repositoryDir = repositoryDir;
  +        if( this.repBuildDir == null ) {
  +            setRepbuilddir( repositoryDir );
  +        }
       }
   
       /**
  +     * Sets the build directory for instrumented classes
  +     *
  +     * @param buildDir the build directory
  +     */
  +    public void setRepbuilddir( File repBuildDir ) {
  +        this.repBuildDir = repBuildDir;
  +    }
  +
  +    /**
        * Turns on/off precondition instrumentation
        *
        * @param pre true turns it on
        */
       public void setPre( boolean pre ) {
           this.pre = pre;
  +        preModified = true;
       }
   
       /**
  @@ -282,6 +384,7 @@
        */
       public void setPost( boolean post ) {
           this.post = post;
  +        postModified = true;
       }
   
       /**
  @@ -291,15 +394,16 @@
        */
       public void setInvariant( boolean invariant ) {
           this.invariant = invariant;
  +        invariantModified = true;
       }
   
       /**
        * Sets the Throwable (Exception) to be thrown on assertion violation
        *
  -     * @param clazz the Throwable class
  +     * @param clazz the fully qualified Throwable class name
        */
  -    public void setFailthrowable( Class clazz ) {
  -        this.failThrowable = clazz.getName();
  +    public void setFailthrowable( String clazz ) {
  +        this.failThrowable = clazz;
       }
   
       /**
  @@ -307,35 +411,40 @@
        * error*,warning*,note*,info*,progress*,debug* (comma separated)
        * can be used. Defaults to error*,warning*
        *
  -     * @param clazz the Throwable class
  +     * @param verbosity verbosity level
        */
       public void setVerbosity( String verbosity ) {
           this.verbosity = verbosity;
       }
   
       /**
  -     * Turns on/off internal compilation.
  -     * <br/>
  -     * If set to true, Sun's javac will be run within the same VM as Ant.
  -     * <br/>
  -     * If set to false, the compiler indicated by the project property
  -     * <code>build.compiler</code> will be used, defaulting to javac,
  -     * and run in a separate VM.
  -     *
  -     * @param internalcompilation set to true for internal compilation
  -     */
  -    /* FIXME: Doesn't work
  -       public void setInternalcompilation( boolean internalcompilation ) {
  -       this.internalcompilation = internalcompilation;
  -       }
  -    */
  +     * Tells iContract to be quiet.
  +     *
  +     * @param quiet true if iContract should be quiet.
  +     */
  +    public void setQuiet( boolean quiet ) {
  +        this.quiet = quiet;
  +    }
  +
  +    /**
  +     * Sets the name of the file where targets will be written.
  +     * That is the file that tells iContract what files to process.
  +     *
  +     * @param targets the targets file name
  +     */
  +    public void setTargets( File targets ) {
  +        this.targets = targets;
  +    }
   
       /**
        * Sets the control file to pass to iContract.
        *
  -     * @param clazz the Throwable class
  +     * @param controlFile the control file
        */
       public void setControlfile( File controlFile ) {
  +        if( !controlFile.exists() ) {
  +            log( "WARNING: Control file " + controlFile.getAbsolutePath() + " doesn't exist.
iContract will be run without control file." );
  +        }
           this.controlFile = controlFile;
       }
   
  @@ -387,6 +496,25 @@
           preconditions();
           scan();
           if( dirty ) {
  +
  +            // turn off assertions if we're using controlfile, unless they are not explicitly
set.
  +            boolean useControlFile = (controlFile != null) && controlFile.exists();
  +            if( useControlFile && !preModified ) {
  +                pre = false;
  +            }
  +            if( useControlFile && !postModified ) {
  +                post = false;
  +            }
  +            if( useControlFile && !invariantModified ) {
  +                invariant = false;
  +            }
  +            // issue warning if pre,post or invariant is used together with controlfile
  +            if( ( pre || post || invariant ) && controlFile != null ) {
  +                log( "WARNING: specifying pre,post or invariant will override control file
settings" );
  +            }
  +
  +
  +
               // We want to be notified if iContract jar is missing. This makes life easier
for the user
               // who didn't understand that iContract is a separate library (duh!)
               getProject().addBuildListener( new IContractPresenceDetector() );
  @@ -397,15 +525,19 @@
               Mkdir mkdir = (Mkdir) project.createTask( "mkdir" );
               mkdir.setDir( instrumentDir );
               mkdir.execute();
  +            mkdir.setDir( buildDir );
  +            mkdir.execute();
               mkdir.setDir( repositoryDir );
               mkdir.execute();
   
  -            // Set the compiler
  -            setCompiler();
  -
               // Set the classpath that is needed for regular Javac compilation
               Path baseClasspath = createClasspath();
   
  +            // Might need to add the core classes if we're not using Sun's Javac (like
Jikes)
  +            String compiler = project.getProperty("build.compiler");
  +            ClasspathHelper classpathHelper = new ClasspathHelper( compiler );
  +            classpathHelper.modify( baseClasspath );
  +
               // Create the classpath required to compile the sourcefiles BEFORE instrumentation
               Path beforeInstrumentationClasspath = ((Path) baseClasspath.clone());
               beforeInstrumentationClasspath.append( new Path( getProject(), srcDir.getAbsolutePath()
) );
  @@ -415,12 +547,14 @@
               afterInstrumentationClasspath.append( new Path( getProject(), instrumentDir.getAbsolutePath()
) );
               afterInstrumentationClasspath.append( new Path( getProject(), repositoryDir.getAbsolutePath()
) );
               afterInstrumentationClasspath.append( new Path( getProject(), srcDir.getAbsolutePath()
) );
  +            afterInstrumentationClasspath.append( new Path( getProject(), buildDir.getAbsolutePath()
) );
   
               // Create the classpath required to automatically compile the repository files
               Path repositoryClasspath = ((Path) baseClasspath.clone());
               repositoryClasspath.append( new Path( getProject(), instrumentDir.getAbsolutePath()
) );
               repositoryClasspath.append( new Path( getProject(), srcDir.getAbsolutePath()
) );
               repositoryClasspath.append( new Path( getProject(), repositoryDir.getAbsolutePath()
) );
  +            repositoryClasspath.append( new Path( getProject(), buildDir.getAbsolutePath()
) );
   
               // Create the classpath required for iContract itself
               Path iContractClasspath = ((Path) baseClasspath.clone());
  @@ -428,6 +562,7 @@
               iContractClasspath.append( new Path( getProject(), srcDir.getAbsolutePath()
) );
               iContractClasspath.append( new Path( getProject(), repositoryDir.getAbsolutePath()
) );
               iContractClasspath.append( new Path( getProject(), instrumentDir.getAbsolutePath()
) );
  +            iContractClasspath.append( new Path( getProject(), buildDir.getAbsolutePath()
) );
   
               // Create a forked java process
               Java iContract = (Java) project.createTask( "java" );
  @@ -440,17 +575,18 @@
               StringBuffer args = new StringBuffer();
               args.append( directiveString() );
               args.append( "-v" ).append( verbosity ).append( " " );
  -            args.append( "-b" ).append( icCompiler ).append( "\"" ).append( " -classpath
" ).append( beforeInstrumentationClasspath ).append( "\" " );
  -            args.append( "-c" ).append( icCompiler ).append( "\"" ).append( " -classpath
" ).append( afterInstrumentationClasspath ).append( "\" " );
  -            args.append( "-n" ).append( icCompiler ).append( "\"" ).append( " -classpath
" ).append( repositoryClasspath ).append( "\" " );
  +            args.append( "-b" ).append( "\"" ).append( icCompiler ).append( " -classpath
" ).append( beforeInstrumentationClasspath ).append( "\" " );
  +            args.append( "-c" ).append( "\"" ).append( icCompiler ).append( " -classpath
" ).append( afterInstrumentationClasspath ).append( " -d " ).append( buildDir ).append( "\"
" );
  +            args.append( "-n" ).append( "\"" ).append( icCompiler ).append( " -classpath
" ).append( repositoryClasspath ).append( "\" " );
               args.append( "-d" ).append( failThrowable ).append( " " );
               args.append( "-o" ).append( instrumentDir ).append( File.separator ).append(
"@p" ).append( File.separator ).append( "@f.@e " );
               args.append( "-k" ).append( repositoryDir ).append( File.separator ).append(
"@p " );
  -            args.append( instrumentall ? "-a " : "" ); // reinstrument everything if controlFile
exists and is newer than source
  +            args.append( quiet ? "-q " : "" );
  +            args.append( instrumentall ? "-a " : "" ); // reinstrument everything if controlFile
exists and is newer than any class
               args.append( "@" ).append( targets.getAbsolutePath() );
               iContract.createArg().setLine( args.toString() );
   
  -// System.out.println( "JAVA -classpath " + iContractClasspath + " com.reliablesystems.iContract.Tool
" + args.toString() );
  +//System.out.println( "JAVA -classpath " + iContractClasspath + " com.reliablesystems.iContract.Tool
" + args.toString() );
   
               // update iControlProperties if it's set.
               if( updateIcontrol ) {
  @@ -460,18 +596,21 @@
                   } catch( IOException e ) {
                       log( "File icontrol.properties not found. That's ok. Writing a default
one." );
                   }
  -                iControlProps.setProperty( "classRoot", srcDir.getAbsolutePath() );
  -                iControlProps.setProperty( "classpath", iContractClasspath.toString() );
  -                iControlProps.setProperty( "controlFile", "control" );
  +                iControlProps.setProperty( "sourceRoot", srcDir.getAbsolutePath() );
  +                iControlProps.setProperty( "classRoot", classDir.getAbsolutePath() );
  +                iControlProps.setProperty( "classpath", afterInstrumentationClasspath.toString()
);
  +                iControlProps.setProperty( "controlFile", controlFile.getAbsolutePath()
);
  +                iControlProps.setProperty( "targetsFile", targets.getAbsolutePath() );
   
                   try { // to read existing propertiesfile
  -                    iControlProps.store( new FileOutputStream( "icontrol.properties" ),
"Edit the classRoot and controlfile properties if you like" );
  -                    log( "Updated file icontrol.properties." );
  +                    iControlProps.store( new FileOutputStream( "icontrol.properties" ),
ICONTROL_PROPERTIES_HEADER );
  +                    log( "Updated icontrol.properties" );
                   } catch( IOException e ) {
                       log( "Couldn't write icontrol.properties." );
                   }
               }
   
  +            // do it!
               int result = iContract.executeJava();
               if( result != 0 ) {
                   if( iContractMissing ) {
  @@ -481,7 +620,8 @@
                   }
                   throw new BuildException( "iContract instrumentation failed. Code=" + result
);
               }
  -        } else {
  +
  +        } else { // not dirty
               //log( "Nothing to do. Everything up to date." );
           }
       }
  @@ -502,36 +642,54 @@
           if (repositoryDir == null) {
               throw new BuildException( "repositorydir attribute must be set!", location
);
           }
  +        if (updateIcontrol == true && classDir == null) {
  +            throw new BuildException( "classdir attribute must be specified when updateicontrol=true!",
location );
  +        }
  +        if( updateIcontrol == true && controlFile == null ) {
  +            throw new BuildException( "controlfile attribute must be specified when updateicontrol=true!",
location );
  +        }
       }
   
       /**
        * Verifies whether any of the source files have changed. Done by comparing date of
source/class files.
  -     * The whole lot is "dirty" if at least one source file is newer than the instrumented
files. If not dirty,
  -     * iContract will not be executed.
  +     * The whole lot is "dirty" if at least one source file or the control file is newer
than the instrumented
  +     * files. If not dirty, iContract will not be executed.
        * <br/>
        * Also creates a temporary file with a list of the source files, that will be deleted
upon exit.
        */
       private void scan() throws BuildException {
           long now = (new Date()).getTime();
   
  -        FileSet fileset = new FileSet();
  -        fileset.setDefaultexcludes( true );
  -        fileset.setDir( srcDir );
  -        DirectoryScanner ds = fileset.getDirectoryScanner( project );
  +        DirectoryScanner ds = null;
   
  +        ds = getDirectoryScanner( srcDir );
           String[] files = ds.getIncludedFiles();
   
  +        FileOutputStream targetOutputStream = null;
  +        PrintStream targetPrinter = null;
  +        boolean writeTargets = false;
           try {
  -            targets = File.createTempFile( "iContractTargets", "tmp", new File( System.getProperty(
"user.dir" ) ) );
  -            targets.deleteOnExit();
  -            FileOutputStream fos = new FileOutputStream( targets );
  -            PrintStream ps = new PrintStream( fos );
  +            if( targets == null ) {
  +                targets = new File( "targets" );
  +                log( "Warning: targets file not specified. generating file: " + targets.getName()
);
  +                writeTargets = true;
  +            } else if( !targets.exists() ) {
  +                log( "Specified targets file doesn't exist. generating file: " + targets.getName()
);
  +                writeTargets = true;
  +            }
  +            if( writeTargets ) {
  +                log( "You should consider using iControl to create a target file." );
  +                targetOutputStream = new FileOutputStream( targets );
  +                targetPrinter = new PrintStream( targetOutputStream );
  +            }
               for (int i = 0; i < files.length; i++ ) {
                   File srcFile = new File(srcDir, files[i]);
                   if (files[i].endsWith(".java")) {
  -                    ps.println( srcFile.getAbsolutePath() );
  -
  -                    File classFile = new File( instrumentDir, files[i].substring( 0, files[i].indexOf(
".java" ) ) + ".class" );
  +                    // print the target, while we're at here. (Only if generatetarget=true).
  +                    if( targetPrinter != null ) {
  +                        targetPrinter.println( srcFile.getAbsolutePath() );
  +                    }
  +                    File classFile = new File( buildDir, files[i].substring( 0, files[i].indexOf(
".java" ) ) + ".class" );
   
                       if (srcFile.lastModified() > now) {
                           log("Warning: file modified in the future: " +
  @@ -543,24 +701,25 @@
                           dirty = true;
                       }
                   }
  +            }
  +            if( targetPrinter != null ) {
  +                targetPrinter.flush();
  +                targetPrinter.close();
               }
  -            ps.flush();
  -            ps.close();
           } catch( IOException e ) {
  -            throw new BuildException( "Could not create temporary file:" + e.getMessage()
);
  +            throw new BuildException( "Could not create target file:" + e.getMessage()
);
           }
   
           // also, check controlFile timestamp
           long controlFileTime = -1;
           try {
               if( controlFile != null ) {
  -                if( controlFile.exists() && instrumentDir.exists() ) {
  +                if( controlFile.exists() && buildDir.exists() ) {
                       controlFileTime = controlFile.lastModified();
  -                    fileset.setDir( instrumentDir );
  -                    ds = fileset.getDirectoryScanner( project );
  +                    ds = getDirectoryScanner( buildDir );
                       files = ds.getIncludedFiles();
                       for( int i = 0; i < files.length; i++ ) {
  -                        File srcFile = new File(srcDir, files[i]);
  +                        File srcFile = new File( srcDir, files[i] );
                           if( files[i].endsWith( ".class" ) ) {
                               if( controlFileTime > srcFile.lastModified() ) {
                                   if( !dirty ) {
  @@ -574,8 +733,7 @@
                   }
               }
           } catch( Throwable t ) {
  -            System.out.println( "FATAL" );
  -            t.printStackTrace();
  +            throw new BuildException( "Got an interesting exception:" + t.getMessage()
);
           }
       }
   
  @@ -586,10 +744,12 @@
       private final String directiveString() {
           StringBuffer sb = new StringBuffer();
           boolean comma = false;
  -        if( (controlFile != null) || pre || post || invariant ) {
  +
  +        boolean useControlFile = (controlFile != null) && controlFile.exists();
  +        if( useControlFile || pre || post || invariant ) {
               sb.append( "-m" );
           }
  -        if(controlFile != null) {
  +        if( useControlFile ) {
               sb.append( "@" ).append( controlFile );
               comma = true;
           }
  @@ -612,50 +772,12 @@
                   sb.append( "," );
               }
               sb.append( "inv" );
  -            comma = true;
           }
           sb.append( " " );
           return sb.toString();
       }
   
       /**
  -     * Sets the compiler as specified by the project's build.compiler property
  -     * If the internalcompilation attribute is set to true, Sun's javac
  -     * will be run from the same VM as Ant.
  -     *
  -     * NOTE: This has not been tested, as I only have JDK.
  -     */
  -    private void setCompiler() {
  -        if( !internalcompilation ) {
  -            String compiler = project.getProperty("build.compiler");
  -            if (compiler == null) {
  -                if (Project.getJavaVersion().startsWith("1.3")) {
  -                    compiler = "modern";
  -                } else {
  -                    compiler = "classic";
  -                }
  -            }
  -
  -            if (compiler.equalsIgnoreCase("classic")) {
  -                icCompiler = "javac";
  -            } else if (compiler.equalsIgnoreCase("modern")) {
  -                icCompiler = "javac";
  -            } else if (compiler.equalsIgnoreCase("jikes")) {
  -                icCompiler = "jikes";
  -            } else if (compiler.equalsIgnoreCase("jvc")) {
  -                icCompiler = "jvc";
  -            } else {
  -                String msg = "Don't know how to use compiler " + compiler;
  -                throw new BuildException(msg, location);
  -            }
  -        } else {
  -            // This is how we tell iContract to use internal compiler
  -            // FIXME: Doesn't work
  -//                        icCompiler = ":";
  -        }
  -    }
  -
  -    /**
        * BuildListener that sets the iContractMissing flag to true if a
        * message about missing iContract is missing. Used to indicate
        * a more verbose error to the user, with advice about how to solve
  @@ -673,5 +795,32 @@
           public void targetStarted(BuildEvent event) {}
           public void taskFinished(BuildEvent event) {}
           public void taskStarted(BuildEvent event) {}
  +    }
  +
  +    /**
  +     * This class is a helper to set correct classpath for other compilers, like Jikes.
  +     * It reuses the logic from DefaultCompilerAdapter, which is protected, so we have
  +     * to subclass it.
  +     */
  +    private class ClasspathHelper extends DefaultCompilerAdapter {
  +        private final String compiler;
  +        public ClasspathHelper( String compiler ) {
  +            super();
  +            this.compiler = compiler;
  +        }
  +
  +        // make it public
  +        public void modify( Path path ) {
  +            // depending on what compiler to use, set the includeJavaRuntime flag
  +            if( "jikes".equals( compiler ) ) {
  +                icCompiler = compiler;
  +                includeJavaRuntime = true;
  +                path.append( getCompileClasspath() );
  +            }
  +        }
  +
  +        // dummy implementation. Never called
  +        public void setJavac( Javac javac ) {}
  +        public boolean execute() { return true; }
       }
   }
  
  
  

Mime
View raw message