first cut at a F# compiler task

git-svn-id: https://svn.apache.org/repos/asf/ant/antlibs/dotnet/trunk@936234 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/changes.xml b/changes.xml
index adc380c..c266e4d 100644
--- a/changes.xml
+++ b/changes.xml
@@ -38,6 +38,9 @@
     </properties>
 
     <release version="SVN trunk" date="unpublished">
+      <action type="add">
+        A new F# compiler task has been added.
+      </action>
       <action type="add" issue="47078">
         A new tallow task has been added to ease creation of WiX built
         installers.
diff --git a/docs/fsc.html b/docs/fsc.html
new file mode 100644
index 0000000..0856e0b
--- /dev/null
+++ b/docs/fsc.html
@@ -0,0 +1,345 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+ 
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<html>
+  <head>
+    <meta http-equiv="Content-Language" content="en-us"></meta>
+    <link rel="stylesheet" type="text/css" href="style.css">
+    <title>Fsc Task</title>
+  </head>
+
+<body>
+
+    <h2>Fsc Task</h2>
+
+    <h3><a name="description">Description</a></h3>
+
+    <p>This task compiles F# source into executables or
+    modules. The task requires fsc.exe on the execute path, unless it
+    or an equivalent program is specified in the <tt>executable</tt>
+    parameter </p>
+
+    <p>All parameters are optional: <code>&lt;fsc/&gt;</code> should
+    suffice to produce a debug build of all *.fs files. </p>
+
+    <p>The task is a directory based task, so attributes like
+    <tt>includes=&quot;**\/*.fs&quot;</tt> and
+    <tt>excludes=&quot;broken.fs&quot;</tt> can be used to control the
+    files pulled in. By default, all *.fs files from the project
+    folder down are included in the command. When this happens the
+    destFile -if not specified- is taken as the first file in the
+    list, which may be somewhat hard to control. Specifying the output
+    file with <tt>destfile</tt> is prudent. </p> </p>
+
+    <p>Also, dependency checking only works if destfile is set. As
+    with <code>&lt;csc&gt;</code> nested <tt>src</tt> filesets of
+    source, reference filesets, definitions and resources can be
+    provided. </p>
+
+    <h3><a name="attributes">Parameters</a></h3>
+    <table>
+      <tr>
+        <td valign="top" align="left">
+          <b>Attribute</b>
+        </td>
+        <td valign="top" align="left">
+          <b>Description</b>
+        </td>
+        <td valign="top" align="left">
+          <b>Type</b>
+        </td>
+        <td valign="top" align="left">
+          <b>Requirement</b>
+        </td>
+      </tr>
+    
+      <tr>
+        <td valign="top" align="left">
+          additionalmodules
+        </td>
+        <td valign="top" align="left">
+          Semicolon separated list of modules to refer to.
+        </td>
+        <td valign="top" align="left">
+          String
+        </td>
+        <td valign="top" align="left" rowspan="24">
+          Optional
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          debug
+        </td>
+        <td valign="top" align="left">
+          set the debug flag on or off.
+        </td>
+        <td valign="top" align="left">
+          boolean
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          destdir
+        </td>
+        <td valign="top" align="left">
+          Set the destination directory of files to be compiled.
+        </td>
+        <td valign="top" align="left">
+          File
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          destfile
+        </td>
+        <td valign="top" align="left">
+          Set the name of exe/library to create.
+        </td>
+        <td valign="top" align="left">
+          File
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          executable
+        </td>
+        <td valign="top" align="left">
+          set the name of the program, overriding the defaults. Can be
+          used to set the full path to a program, or to switch to an
+          alternate implementation of the command -provided they use
+          the same command line arguments as the .NET framework
+          edition
+        </td>
+        <td valign="top" align="left">
+          String
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          extraoptions
+        </td>
+        <td valign="top" align="left">
+          Any extra options which are not explicitly supported by this task.
+        </td>
+        <td valign="top" align="left">
+          String
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          failonerror
+        </td>
+        <td valign="top" align="left">
+          If true, fail on compilation errors.
+        </td>
+        <td valign="top" align="left">
+          boolean
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          optimize
+        </td>
+        <td valign="top" align="left">
+          If true, enables optimization flag.
+        </td>
+        <td valign="top" align="left">
+          boolean
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          tailcalls
+        </td>
+        <td valign="top" align="left">
+          Whether to enable tailcalls
+        </td>
+        <td valign="top" align="left">
+          boolean, defaults to true
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          crossoptimize
+        </td>
+        <td valign="top" align="left">
+          Whether to enable cross-module optimizations.
+        </td>
+        <td valign="top" align="left">
+          boolean, defaults to false
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          standalone
+        </td>
+        <td valign="top" align="left">
+          Whether to statically link the F# library and all referenced
+          DLLs into the assembly.
+        </td>
+        <td valign="top" align="left">
+          boolean, defaults to false
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          references
+        </td>
+        <td valign="top" align="left">
+          Semicolon separated list of DLLs to refer to.
+        </td>
+        <td valign="top" align="left">
+          String
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          srcdir
+        </td>
+        <td valign="top" align="left">
+          Set the source directory of the files to be compiled.
+        </td>
+        <td valign="top" align="left">
+          File
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          targettype
+        </td>
+        <td valign="top" align="left">
+          set the target type to one of exe|library|module|winexe
+        </td>
+        <td valign="top" align="left">
+          "exe", "library", "module", "winexe"
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          utf8output
+        </td>
+        <td valign="top" align="left">
+          If true, require all compiler output to be in UTF8 format.
+        </td>
+        <td valign="top" align="left">
+          boolean
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          warnlevel
+        </td>
+        <td valign="top" align="left">
+          Level of warning currently between 1 and 4 with 4 being the
+          strictest.
+        </td>
+        <td valign="top" align="left">
+          int
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          win32icon
+        </td>
+        <td valign="top" align="left">
+          Set the filename of icon to include.
+        </td>
+        <td valign="top" align="left">
+          File
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top" align="left">
+          win32res
+        </td>
+        <td valign="top" align="left">
+          Sets the filename of a win32 resource (.RES) file to
+          include. This is not a .NET resource, but what Windows is
+          used to.
+        </td>
+        <td valign="top" align="left">
+          File
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="top">
+          useresponsefile
+        </td>
+        <td valign="top">
+          Sets whether a response file instead of a command line only
+          invocation should be used.  Defaults to false but Ant will
+          still use a response file if more than 64 command line
+          arguments would be used.
+        </td>
+        <td valign="top">
+          boolean
+        </td>
+      </tr>
+    </table>
+
+    <h3><a name="elements">Parameters as nested elements</a></h3>
+
+    <h4>define (org.apache.ant.dotnet.compile..DotnetDefine)</h4>
+
+    <p>add a define to the list of definitions</p>
+
+    <h4>reference (org.apache.tools.ant.types.FileSet)</h4>
+
+    <p>add a new reference fileset to the compilation</p>
+
+    <h4>resource (org.apache.ant.dotnet.compile.DotnetResource)</h4>
+
+    <p>link or embed a resource</p>
+
+    <h4>src (org.apache.tools.ant.types.FileSet)</h4>
+
+    <p>add a new source directory to the compile</p>
+
+    <h3>Examples</h3>
+
+<pre>&lt;fsc optimize=&quot;true&quot; debug=&quot;false&quot;
+  warnLevel=&quot;4&quot; targetType=&quot;exe&quot; definitions=&quot;RELEASE&quot;
+  excludes=&quot;src/unicode_class.fs&quot;
+  destFile=&quot;NetApp.exe&quot; tailcalls=&quot;true&quot; &gt;
+    &lt;reference file="${testCSC.dll}"/&gt;
+    &lt;define name="RELEASE"/&gt;
+    &lt;define name="DEBUG" if="debug.property"/&gt;
+    &lt;define name="def3" unless="def2.property"/&gt;
+&lt;/fsc&gt;
+</pre>
+</body>
+</html>
diff --git a/docs/index.html b/docs/index.html
index 5dfbab2..6c811ea 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -151,6 +151,8 @@
       is going to be used - defaults to Mono on non-Windows platforms
       and Microsoft's on Windows.</li>
 
+      <li><a href="fsc.html">fsc</a> - F# compiler task.</li>
+
       <li><a href="nant.html">nant</a> - execute the NAnt build
       tool.</li>
 
diff --git a/src/main/org/apache/ant/dotnet/antlib.xml b/src/main/org/apache/ant/dotnet/antlib.xml
index 627c743..b4dcb30 100644
--- a/src/main/org/apache/ant/dotnet/antlib.xml
+++ b/src/main/org/apache/ant/dotnet/antlib.xml
@@ -61,4 +61,7 @@
   <taskdef
     name="importtypelib"
     classname="org.apache.ant.dotnet.ImportTypelib"/>
+  <taskdef
+    name="fsc"
+    classname="org.apache.ant.dotnet.compile.FSharp"/>
 </antlib>
diff --git a/src/main/org/apache/ant/dotnet/compile/FSharp.java b/src/main/org/apache/ant/dotnet/compile/FSharp.java
new file mode 100644
index 0000000..0b45e27
--- /dev/null
+++ b/src/main/org/apache/ant/dotnet/compile/FSharp.java
@@ -0,0 +1,215 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.dotnet.compile;
+
+import org.apache.ant.dotnet.NetCommand;
+import org.apache.tools.ant.BuildException;
+
+
+/**
+ * This task compiles F# source into executables or modules.
+ * The task requires fsc.exe on the execute path, unless it or an equivalent
+ * program is specified in the <tt>executable</tt> parameter
+ *
+ * <p>
+ * All parameters are optional: &lt;fsc/&gt; should suffice to produce a debug
+ * build of all *.fs files.
+ *
+ * <p>
+
+ * The task is a directory based task, so attributes like
+ * <tt>includes=&quot;**\/*.fs&quot;</tt> and
+ * <tt>excludes=&quot;broken.fs&quot;</tt> can be used to control
+ * the files pulled in. By default,
+ * all *.fs files from the project folder down are included in the command.
+ * When this happens the destFile -if not specified-
+ * is taken as the first file in the list, which may be somewhat hard to control.
+   Specifying the output file with <tt>destfile</tt> is prudent.
+ </p>
+ <p>
+ * Also, dependency checking only works if destfile is set.
+ *
+ * <p>For historical reasons the pattern
+ * <code>**</code><code>/*.fs</code> is preset as includes list and
+ * you can not override it with an explicit includes attribute.  Use
+ * nested <code>&lt;src&gt;</code> elements instead of the basedir
+ * attribute if you need more control.</p>
+ *
+ * As with &lt;csc&gt; nested <tt>src</tt> filesets of source,
+ * reference filesets, definitions and resources can be provided.
+ *
+ * <p>
+ * Example
+ * </p>
+ * <pre>&lt;fsc
+ *   optimize=&quot;true&quot;
+ *   debug=&quot;false&quot;
+ *   warnLevel=&quot;4&quot;
+ *   targetType=&quot;exe&quot;
+ *   definitions=&quot;RELEASE&quot;
+ *   excludes=&quot;src/unicode_class.fs&quot;
+ *   destFile=&quot;NetApp.exe&quot;
+ *   tailcalls=&quot;true&quot;
+ *   references="System.Xml,System.Web.Xml"
+ *   &gt;
+ *          &lt;reference file="${testCSC.dll}" /&gt;
+ *          &lt;define name="RELEASE" /&gt;
+ *          &lt;define name="DEBUG" if="debug.property"/&gt;
+ *          &lt;define name="def3" unless="def2.property"/&gt;
+ *   &lt;/fsc&gt;
+ </pre>
+ * @ant.task    name="fsc" category="dotnet"
+ */
+
+public class FSharp extends DotnetCompile {
+
+    /**
+     * Compiler option to enable tailcalls.
+     */
+    private boolean tailcalls = true;
+
+    /**
+     * Compiler option to enable cross-module optimizations.
+     */
+    private boolean crossoptimize = false;
+
+    /**
+     * Compiler option to statically link the F# library and all
+     * referenced DLLs into the assembly.
+     */
+    private boolean standalone = false;
+
+    public FSharp() {
+        clear();
+    }
+
+    /**
+     *  reset all contents.
+     */
+    public void clear() {
+        super.clear();
+        tailcalls = true;
+        crossoptimize = false;
+        standalone = false;
+        setExecutable("fsc");
+    }
+
+    /**
+     * Whether to enable tailcalls.
+     */
+    public void setTailcalls(boolean b) {
+        tailcalls = b;
+    }
+
+    /**
+     * Whether to enable tailcalls.
+     * @return    true if flag is turned on
+     */
+    public boolean getTailcalls() {
+        return tailcalls;
+    }
+
+    /**
+     * Form the option string for tailcalls.
+     * @return The parameter string.
+     */
+    public String getTailcallsParameter() {
+        return "/tailcalls" + (tailcalls ? "+" : "-");
+    }
+
+    /**
+     * Whether to enable cross-module optimizations.
+     */
+    public void setCrossoptimize(boolean b) {
+        crossoptimize = b;
+    }
+
+    /**
+     * Whether to enable cross-module optimizations.
+     * @return    true if flag is turned on
+     */
+    public boolean getCrossoptimize() {
+        return crossoptimize;
+    }
+
+    /**
+     * Form the option string for cross-module optimizations.
+     * @return The parameter string.
+     */
+    public String getCrossoptimizeParameter() {
+        return "/crossoptimize" + (crossoptimize ? "+" : "-");
+    }
+
+    /**
+     * Whether to create a standalone assembly.
+     */
+    public void setStandalone(boolean b) {
+        standalone = b;
+    }
+
+    /**
+     * Whether to create a standalone assembly.
+     * @return    true if flag is turned on
+     */
+    public boolean getStandalone() {
+        return standalone;
+    }
+
+    /**
+     * Form the option string for standalone.
+     * @return The parameter string.
+     */
+    public String getStandaloneParameter() {
+        return standalone ? "/standalone" : null;
+    }
+
+    /**
+     * implement FSC commands
+     * @param command
+     */
+    protected void addCompilerSpecificOptions(NetCommand command) {
+        command.addArgument(getTailcallsParameter());
+        command.addArgument(getCrossoptimizeParameter());
+        String s = getStandaloneParameter();
+        if (s != null) {
+            command.addArgument(s);
+        }
+    }
+
+    /**
+     * Get the delimiter that the compiler uses between references.
+     */
+    public String getReferenceDelimiter() {
+        return ";";
+    }
+
+    /**
+     * Get the extension of filenames to compile.
+     * @return The string extension of files to compile.
+     */
+    public String getFileExtension() {
+        return "fs";
+    }
+
+    protected void createResourceParameter(NetCommand command,
+                                           DotnetResource resource) {
+        resource.getParameters(getProject(), command, false);
+    }
+
+}
diff --git a/src/tests/antunit/fsc-test.xml b/src/tests/antunit/fsc-test.xml
new file mode 100644
index 0000000..ff886ad
--- /dev/null
+++ b/src/tests/antunit/fsc-test.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>

+<!--

+   Licensed to the Apache Software Foundation (ASF) under one or more

+   contributor license agreements.  See the NOTICE file distributed with

+   this work for additional information regarding copyright ownership.

+   The ASF licenses this file to You under the Apache License, Version 2.0

+   (the "License"); you may not use this file except in compliance with

+   the License.  You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+   See the License for the specific language governing permissions and

+   limitations under the License.

+-->

+<project xmlns:dn="antlib:org.apache.ant.dotnet"

+         xmlns:au="antlib:org.apache.ant.antunit">

+

+  <property environment="env"/>

+  <property name="build.dir" location="${java.io.tmpdir}/build"/>

+  <property name="src.dir" location="src"/>

+

+  <target name="setUp">

+    <mkdir dir="${build.dir}"/>

+    <condition property="fsc.found">

+      <or>

+        <available file="fsc"     filepath="${env.PATH}" />

+        <available file="fsc.exe" filepath="${env.PATH}" />

+        <available file="fsc.exe" filepath="${env.Path}" />

+      </or>

+    </condition>

+  </target>

+

+  <target name="test-fsc" depends="setUp" if="fsc.found">

+    <property name="testFSC.exe"

+              location="${build.dir}/ExampleFsc.exe" />

+    <dn:fsc

+       destFile="${testFSC.exe}"

+       targetType="exe"

+       optimize="true"

+       srcDir="${src.dir}"

+      >

+    </dn:fsc>

+    <au:assertFileExists file="${testFSC.exe}"/>

+    <dn:dotnetexec executable="${testFSC.exe}" failonerror="true" />

+  </target>

+

+  <target name="tearDown">

+    <delete dir="${build.dir}" quiet="true"/>

+  </target>

+</project>

diff --git a/src/tests/antunit/src/example.fs b/src/tests/antunit/src/example.fs
new file mode 100644
index 0000000..594aff0
--- /dev/null
+++ b/src/tests/antunit/src/example.fs
@@ -0,0 +1,21 @@
+#light
+
+(*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *)
+
+printfn "hello, I look like ML, but I'm really .NET"