diff options
45 files changed, 1953 insertions, 2561 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 4794666721..4f627780e6 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -158,6 +158,10 @@ filter { { matchName="scala.reflect.internal.Names#NameOps.name" problemName=MissingFieldProblem + }, + { + matchName="scala.reflect.internal.ClassfileConstants.xxxunusedxxxx" + problemName=MissingMethodProblem } ] } diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 529fab1e14..76e189653b 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -354,6 +354,22 @@ filter { { matchName="scala.reflect.internal.StdNames#TermNames.SelectFromTypeTree" problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.ClassfileConstants.CONSTANT_INVOKEDYNAMIC" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.ClassfileConstants.invokedynamic" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.ClassfileConstants.CONSTANT_METHODHANDLE" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.ClassfileConstants.CONSTANT_METHODTYPE" + problemName=MissingMethodProblem } ] } @@ -5,176 +5,71 @@ SuperSabbus for Scala core, builds the scala library and compiler. It can also package it as a simple distribution, tests it for stable bootstrapping and against the Scala test suite. </description> -<!-- =========================================================================== -END-USER TARGETS -============================================================================ --> - - <target name="build" depends="pack.done" - description="Builds the Scala compiler and library. Executables are in 'build/pack/bin'."/> - - <target name="build-opt" - description="Builds the optimised Scala compiler and library. Executables are in 'build/pack/bin'."> - <antcall target="build"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> - - <target name="clean" depends="quick.clean" - description="Removes binaries of compiler and library. Distributions are untouched."/> - - <target name="test" depends="test.done" - description="Runs test suite and bootstrapping test on Scala compiler and library."/> - - <target name="test-opt" - description="Runs test suite and bootstrapping test, everything is optimised (compiler, library, tests)."> - <antcall target="test"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> - - <target name="docs" depends="docs.done" - description="Builds documentation for the Scala library. Scaladoc is in 'build/scaladoc/library'."/> - - <target name="docscomp" depends="docs.comp" - description="Builds documentation for the Scala compiler and library. Scaladoc is in 'build/scaladoc'."/> - - <target name="docsclean" depends="docs.clean" - description="Removes generated documentation. Distributions are untouched."/> - - <target name="dist" - description="Makes a new distribution and tests it. Will remove existing binaries and documentation."> - <antcall target="locker.clean"/> - <antcall target="docs.clean"/> - <antcall target="all.done"/> - </target> - - <target name="dist-opt" - description="Makes a new optimised distribution and tests it. Will remove existing binaries and documentation."> - <antcall target="dist"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> - +<!-- USAGE FROM JENKINS SCRIPTS IS (CURRENTLY) AS FOLLOWS: +ant $antArgs $scalacArgs $targets - <target name="partialdist" depends="dist.partial" - description="Makes a new distribution without documentation, so just for testing."/> +antArgs tend to be: + -Darchives.skipxz=true + -Dscalac.args.optimise=-optimise - <target name="partialdist-opt" - description="Makes a new optimised distribution without testing it or removing partially build elements."> - <antcall target="partialdist"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> +scalacArgs examples: + "-Dscalac.args=\"-Yrangepos\" -Dpartest.scalac_opts=\"-Yrangepos\"" +targets exercised: + build-opt nightly test.suite test.continuations.suite test.scaladoc locker.done +--> - <target name="fastdist" depends="dist.done" - description="Makes a new distribution without testing it or removing partially build elements."/> - - <target name="fastdist-opt" - description="Makes a new optimised distribution without testing it or removing partially build elements."> - <antcall target="fastdist"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> - - <target name="distclean" depends="dist.clean" - description="Removes all distributions. Binaries and documentation are untouched."/> - - <target name="replacestarr" - description="Replaces the Starr compiler and library by fresh ones built from current sources and tests them."> - <fail message="This target is not available on Windows. Use 'ant replacestarrwin' instead."> - <condition> - <os family="windows"/> - </condition> - </fail> - <antcall target="locker.clean"/> - <antcall target="pack.done"/> - <antcall target="starr.done"/> - <antcall target="locker.clean"/> - <antcall target="test.done"/> - </target> - - <target name="replacestarr-opt" - description="Replaces the Starr compiler and library by fresh, optimised ones built from current sources and tests them."> - <antcall target="replacestarr"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> - - <!-- Ant on Windows is not able to delete jar files that are referenced in any <path>. - See ticket 1290 on trac. --> - <target name="replacestarrwin" - description="Creates a new Starr on Windows. Manually execute 'ant locker.clean build' first!"> - <fail message="This target is only available on Windows. Use 'ant replacestarr' instead."> - <condition> - <not><os family="windows"/></not> - </condition> - </fail> - <echo message="CAUTION: Make sure to execute 'ant locker.clean build' prior to calling 'replacestarrwin'."/> - <antcall target="starr.done"/> - <antcall target="locker.clean"/> - <antcall target="test.done"/> - </target> - - <target name="replacestarrwin-opt" - description="Creates a new Starr on Windows. Manually execute 'ant locker.clean build' first!"> - <antcall target="replacestarrwin"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> - <target name="replacelocker" - description="Replaces the Locker compiler and library by fresh ones built from current sources."> - <antcall target="palo.clean"/> - <antcall target="unlocklocker"/> - </target> - <target name="replacelocker-opt" - description="Replaces the Locker compiler and library by fresh, optimised ones built from current sources."> - <antcall target="replacelocker"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> - - <target name="unlocklocker" - description="Unlocks Locker, allowing its compiler and library to be rebuilt"> - <antcall target="locker.unlock"/> - <antcall target="palo.done"/> - </target> +<!-- =========================================================================== + END-USER TARGETS +============================================================================ --> + <target name="build" depends="pack.done" description="Builds the Scala compiler and library. Executables are in 'build/pack/bin'."/> + <target name="test" depends="test.done" description="Runs test suite and bootstrapping test on Scala compiler and library."/> + <target name="docs" depends="docs.done" description="Builds documentation for the Scala library. Scaladoc is in 'build/scaladoc/library'."/> + <target name="docscomp" depends="docs.comp" description="Builds documentation for the Scala compiler and library. Scaladoc is in 'build/scaladoc'."/> + <target name="dist" depends="all.clean, all.done" description="Cleans all and builds and tests a new distribution."/> + <target name="partialdist" depends="dist.partial" description="Makes a new distribution without documentation, so just for testing."/> + <target name="fastdist" depends="dist.done" description="Makes a new distribution without testing it or removing partially build elements."/> + + <target name="build-opt" description="Optimized version of build."> <optimized name="build"/></target> + <target name="test-opt" description="Optimized version of test."> <optimized name="test"/></target> + <target name="dist-opt" description="Optimized version of dist."> <optimized name="dist"/></target> + <target name="partialdist-opt" description="Optimized version of partialdist."> <optimized name="partialdist"/></target> + <target name="fastdist-opt" description="Optimized version of fastdist."> <optimized name="fastdist"/></target> + + <!-- packaging --> + <target name="distpack" depends="dist.done, docs.done"> + <ant antfile="${src.dir}/build/pack.xml" target="pack-all.done" inheritall="yes" inheritrefs="yes"/></target> + + <target name="distpack-maven" depends="dist.done, docs.done"> + <ant antfile="${src.dir}/build/pack.xml" target="pack-maven.done" inheritall="yes" inheritrefs="yes"/></target> + + <target name="distpack-opt" description="Builds an optimised distribution."> <optimized name="distpack"/></target> + <target name="distpack-maven-opt" description="Builds an optimised maven distribution."><optimized name="distpack-maven"/></target> - <target name="fastlocker.lib" - description="Buildlocker without extra fuss"> - <property name="fastlocker" value="true"/> - <antcall target="locker.unlock"/> - <antcall target="locker.lib"/> - </target> + <target name="all.done" depends="dist.done, test.done"/> - <target name="fastlocker.reflect" - description="Buildlocker without extra fuss"> - <property name="fastlocker" value="true"/> - <antcall target="locker.unlock"/> - <antcall target="locker.reflect"/> - </target> + <!-- must use depends for all.done, not antcall: need the properties defined in there (dist.dir) --> + <target name="nightly-nopt" depends="all.done, docs.done"> + <ant antfile="${src.dir}/build/pack.xml" target="pack-all.done" inheritall="yes" inheritrefs="yes"/></target> + <target name="nightly"><optimized name="nightly-nopt"/></target> - <target name="fastlocker.comp" - description="Buildlocker without extra fuss"> - <property name="fastlocker" value="true"/> - <antcall target="locker.unlock"/> - <antcall target="locker.comp"/> - </target> + <target name="nightly.checkall"> + <antcall target="nightly-nopt"> <param name="partest.scalac_opts" value="-Ycheck:all"/></antcall></target> - <target name="fastlocker" - description="Buildlocker without extra fuss"> - <antcall target="fastlocker.comp"/> - </target> + <target name="clean" depends="locker.clean" description="Removes binaries of compiler and library. Distributions are untouched."/> + <target name="docsclean" depends="docs.clean" description="Removes generated documentation. Distributions are untouched."/> + <target name="distclean" depends="dist.clean" description="Removes all distributions. Binaries and documentation are untouched."/> - <target name="buildlocker" - description="Does the same for locker as build does for quick"> - <antcall target="locker.unlock"/> - <antcall target="palo.bin"/> - </target> + <macrodef name="optimized" > + <attribute name="name"/> + <sequential> + <antcall target="@{name}"><param name="scalac.args.optimise" value="-optimise"/></antcall> + </sequential> + </macrodef> <!-- =========================================================================== -PROPERTIES + PROPERTIES ============================================================================ --> <property environment="env"/> @@ -184,10 +79,10 @@ PROPERTIES <!-- Defines the repository layout --> <property name="docs.dir" value="${basedir}/docs"/> <property name="lib.dir" value="${basedir}/lib"/> - <property name="lib-ant.dir" value="${lib.dir}/ant"/> <property name="src.dir" value="${basedir}/src"/> <property name="partest.dir" value="${basedir}/test"/> + <property name="lib-ant.dir" value="${lib.dir}/ant"/> <!-- For developers: any jars placed in this dir will be added to the classpath of all targets and copied into quick/pack/etc builds. --> <property name="lib-extra.dir" value="${lib.dir}/extra"/> @@ -197,15 +92,11 @@ PROPERTIES <!-- Generating version number --> <property file="${basedir}/build.number"/> - <!-- Additional command line arguments for scalac. They are added to all build targets --> - <property name="scalac.args" value=""/> - <property name="javac.args" value=""/> - <!-- Sets location of pre-compiled libraries --> - <property name="lib.starr.jar" value="${lib.dir}/scala-library.jar"/> - <property name="msil.starr.jar" value="${lib.dir}/msil.jar"/> + <property name="library.starr.jar" value="${lib.dir}/scala-library.jar"/> <property name="reflect.starr.jar" value="${lib.dir}/scala-reflect.jar"/> - <property name="comp.starr.jar" value="${lib.dir}/scala-compiler.jar"/> + <property name="compiler.starr.jar" value="${lib.dir}/scala-compiler.jar"/> + <property name="msil.starr.jar" value="${lib.dir}/msil.jar"/> <property name="jline.jar" value="${lib.dir}/jline.jar"/> <property name="ant.jar" value="${ant.home}/lib/ant.jar"/> <property name="scalacheck.jar" value="${lib.dir}/scalacheck.jar"/> @@ -223,6 +114,8 @@ PROPERTIES <property name="build-libs.dir" value="${build.dir}/libs"/> <property name="build-sbt.dir" value="${build.dir}/sbt-interface"/> + <property name="test.osgi.src" value="${partest.dir}/osgi/src"/> + <property name="test.osgi.classes" value="${build-osgi.dir}/classes"/> <property name="dists.dir" value="${basedir}/dists"/> @@ -238,126 +131,128 @@ PROPERTIES but if it is unset it will take this default value. --> <property name="env.ANT_OPTS" value="-Xms1536M -Xmx1536M -Xss1M -XX:MaxPermSize=192M -XX:+UseParallelGC" /> - <property - name="scalacfork.jvmargs" - value="${env.ANT_OPTS} ${jvm.opts}"/> + <property name="scalacfork.jvmargs" value="${env.ANT_OPTS} ${jvm.opts}"/> <!-- =========================================================================== -INITIALISATION + INITIALIZATION ============================================================================ --> + <target name="desired.jars.uptodate"> + <patternset id="desired.jars"> + <include name="lib/**/*.desired.sha1"/> + <include name="test/files/**/*.desired.sha1"/> + <include name="tools/**/*.desired.sha1"/> + </patternset> - <target name="init.jars.check"> <uptodate property="lib.jars.uptodate"> - <srcfiles dir="${basedir}"> - <include name="lib/**/*.desired.sha1"/> - <include name="test/files/**/*.desired.sha1"/> - <include name="tools/**/*.desired.sha1"/> - </srcfiles> + <srcfiles dir="${basedir}"><patternset refid="desired.jars"/></srcfiles> <mapper type="glob" from="*.desired.sha1" to="*"/> </uptodate> </target> - <target name="init.jars" depends="init.jars.check" unless="lib.jars.uptodate"> + <target name="boot" depends="desired.jars.uptodate" unless="lib.jars.uptodate"> <echo level="warn" message="Updating bootstrap libs. (To do this by hand, run ./pull-binary-libs.sh)"/> <exec osfamily="unix" vmlauncher="false" executable="./pull-binary-libs.sh" failifexecutionfails="true" /> <exec osfamily="windows" vmlauncher="false" executable="pull-binary-libs.sh" failifexecutionfails="true" /> <!-- uptodate task needs to know these are what's in the sha. --> <touch> - <fileset dir="${basedir}"> - <include name="lib/**/*.desired.sha1"/> - <include name="test/files/**/*.desired.sha1"/> - <include name="tools/**/*.desired.sha1"/> - </fileset> + <fileset dir="${basedir}"><patternset refid="desired.jars"/></fileset> <mapper type="glob" from="*.desired.sha1" to="*"/> </touch> </target> - <!-- Add our maven ant tasks --> - <target name="init.maven.tasks" depends="init.jars.check" unless="init.maven.tasks.finished"> - <path id="maven-ant-tasks.classpath" path="${lib.dir}/ant/maven-ant-tasks-2.1.1.jar" /> - <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" /> - - <property name="init.maven.tasks.finished" value="true" /> - </target> - - <target name="init.extra.tasks" depends="init.maven.tasks" unless="init.extra.tasks.finished"> - <artifact:dependencies pathId="extra.tasks.classpath" filesetId="extra.tasks.fileset"> - <dependency groupId="biz.aQute" artifactId="bnd" version="1.50.0"/> - </artifact:dependencies> - <!-- Pax runner --> - <property name="pax.exam.version" value="2.5.0"/> - <artifact:dependencies pathId="pax.exam.classpath" filesetId="pax.exam.fileset"> - <dependency groupId="org.ops4j.pax.exam" artifactId="pax-exam-container-native" version="${pax.exam.version}"/> - <dependency groupId="org.ops4j.pax.exam" artifactId="pax-exam-junit4" version="${pax.exam.version}"/> - <dependency groupId="org.ops4j.pax.exam" artifactId="pax-exam-link-assembly" version="${pax.exam.version}"/> - <dependency groupId="org.ops4j.pax.url" artifactId="pax-url-aether" version="1.4.0"/> - <dependency groupId="org.ops4j.pax.swissbox" artifactId="pax-swissbox-framework" version="1.5.1"/> - <dependency groupId="ch.qos.logback" artifactId="logback-core" version="0.9.20"/> - <dependency groupId="ch.qos.logback" artifactId="logback-classic" version="0.9.20"/> - <dependency groupId="junit" artifactId="junit" version="4.10"/> - <dependency groupId="org.apache.felix" artifactId="org.apache.felix.framework" version="3.2.2"/> - </artifact:dependencies> - <!-- BND support --> - <typedef resource="aQute/bnd/ant/taskdef.properties" classpathref="extra.tasks.classpath" /> - <property name="init.maven.tasks.finished" value="true" /> - </target> + <target name="init" depends="boot"> + <!-- Set up Ant contrib tasks so we can use <if><then><else> instead of the clunky `unless` attribute --> + <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib-ant.dir}/ant-contrib.jar"/> - <!-- Resolve maven dependencies --> - <target name="init.maven.jars" depends="init.maven.tasks"> - <!-- This target has an issue where if the user directory does not exist, we BOMB. ugh. --> - <mkdir dir="${user.home}/.m2/repository"/> - <artifact:dependencies pathId="dependency.classpath" filesetId="dependency.fileset"> - <!--<dependency groupId="com.typesafe" artifactId="config" version="0.4.0"/>--> - </artifact:dependencies> - </target> + <!-- Add our maven ant tasks --> + <path id="maven-ant-tasks.classpath" path="${lib-ant.dir}/maven-ant-tasks-2.1.1.jar" /> + <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" /> - <!-- Determines OSGi string + maven extension. --> - <target name="init.hasbuildnum"> - <condition property="version.hasbuildnum"> - <not><equals arg1="${version.bnum}" arg2="0"/></not> - </condition> - </target> - <target name="init.build.snapshot" unless="build.release"> + <!-- work around http://jira.codehaus.org/browse/MANTTASKS-203: + java.lang.ClassCastException: org.codehaus.plexus.DefaultPlexusContainer cannot be cast to org.codehaus.plexus.PlexusContainer + on repeated use of artifact:dependencies + --> + <if><not><isset property="maven-deps-done"></isset></not><then> + <artifact:dependencies pathId="extra.tasks.classpath" filesetId="extra.tasks.fileset"> + <dependency groupId="biz.aQute" artifactId="bnd" version="1.50.0"/> + </artifact:dependencies> + + <!-- Pax runner --> + <property name="pax.exam.version" value="2.5.0"/> + <artifact:dependencies pathId="pax.exam.classpath" filesetId="pax.exam.fileset"> + <dependency groupId="org.ops4j.pax.exam" artifactId="pax-exam-container-native" version="${pax.exam.version}"/> + <dependency groupId="org.ops4j.pax.exam" artifactId="pax-exam-junit4" version="${pax.exam.version}"/> + <dependency groupId="org.ops4j.pax.exam" artifactId="pax-exam-link-assembly" version="${pax.exam.version}"/> + <dependency groupId="org.ops4j.pax.url" artifactId="pax-url-aether" version="1.4.0"/> + <dependency groupId="org.ops4j.pax.swissbox" artifactId="pax-swissbox-framework" version="1.5.1"/> + <dependency groupId="ch.qos.logback" artifactId="logback-core" version="0.9.20"/> + <dependency groupId="ch.qos.logback" artifactId="logback-classic" version="0.9.20"/> + <dependency groupId="junit" artifactId="junit" version="4.10"/> + <dependency groupId="org.apache.felix" artifactId="org.apache.felix.framework" version="3.2.2"/> + </artifact:dependencies> + + <!-- BND support --> + <typedef resource="aQute/bnd/ant/taskdef.properties" classpathref="extra.tasks.classpath" /> + + <!-- Resolve maven dependencies --> + <mkdir dir="${user.home}/.m2/repository"/> + <!-- This task has an issue where if the user directory does not exist, so we create it above. UGH. --> + <artifact:dependencies pathId="dependency.classpath" filesetId="dependency.fileset"> + <!--<dependency groupId="com.typesafe" artifactId="config" version="0.4.0"/>--> + </artifact:dependencies> + + <!-- Download STARR via maven if `starr.version` is specified. + Want to slow down STARR changes, using only released versions. --> + <if><isset property="starr.version"/><then> + <artifact:dependencies pathId="starr.core.path"> + <dependency groupId="org.scala-lang" artifactId="scala-library" version="${starr.version}"/> + <dependency groupId="org.scala-lang" artifactId="scala-reflect" version="${starr.version}"/> + <dependency groupId="org.scala-lang" artifactId="scala-compiler" version="${starr.version}"/> + </artifact:dependencies> + </then></if> + + <property name="maven-deps-done" value="yep!"/> + </then></if> + + <!-- NOTE: ant properties are write-once: second writes are silently discarded; the logic below relies on this --> + + <!-- Compute defaults (i.e., if not specified on command-line) for OSGi/maven version suffixes. + Try to establish the invariant (verified below): + `version.suffix == maven.version.suffix == osgi.version.suffix`, + except for: + - snapshot builds, where: + - `maven.suffix == "-SNAPSHOT"` + - `version.suffix == osgi.version.suffix == ""` + - final builds, where: + - `osgi.suffix == "-VFINAL"` + - `version.suffix == maven.version.suffix == ""` + --> + <if><not><equals arg1="${version.bnum}" arg2="0"/></not><then> + <property name="version.suffix" value="-${version.bnum}"/> + </then></if> + + <if><or><not><isset property="version.suffix"/></not><equals arg1="${version.suffix}" arg2=""/></or><then> + <if><isset property="build.release"/><then> + <property name="maven.version.suffix" value=""/> + <property name="version.suffix" value="${maven.version.suffix}"/> + <if><equals arg1="${maven.version.suffix}" arg2=""/><then> + <property name="osgi.version.suffix" value="-VFINAL"/></then> + <else> + <property name="osgi.version.suffix" value="${maven.version.suffix}"/></else></if></then></if></then> + <else> <!-- version.suffix set and not empty --> + <property name="maven.version.suffix" value="${version.suffix}"/> + <property name="osgi.version.suffix" value="${version.suffix}"/></else></if> + + <!-- not building a release and no version.suffix specified --> <property name="maven.version.suffix" value="-SNAPSHOT"/> - </target> - <target name="init.build.release" if="build.release" depends="init.hasbuildnum, init.build.snapshot"> - <property name="maven.version.suffix" value=""/> - </target> - <target name="init.build.nopatch.release" unless="version.hasbuildnum" depends="init.hasbuildnum"> - <property name="version.suffix" value=""/> - </target> - <!-- funny thing, ant is. Can only specify *one* property in if check. Guaranteed that both are true here, - since properties are immutable. --> - <target name="init.build.patch.release" if="version.hasbuildnum" depends="init.build.nopatch.release"> - <property name="version.suffix" value="-${version.bnum}"/> - </target> - <target name="init.hasmavensuffix" if="build.release" depends="init.build.patch.release, init.build.release"> - <condition property="version.hasmavensuffix"> - <not><equals arg1="${maven.version.suffix}" arg2=""/></not> - </condition> - </target> - - <target name="init.osgi.suffix" if="version.hasmavensuffix" depends="init.hasmavensuffix"> - <property name="osgi.version.suffix" value="${maven.version.suffix}"/> - </target> - - <target name="init.osgi.suffix.final" if="build.release" unless="version.hasmavensuffix" depends="init.hasmavensuffix"> - <property name="osgi.version.suffix" value="-VFINAL"/> - </target> - - - <target name="init.osgi.suffix.snapshot" unless="build.release" depends="init.hasmavensuffix"> - <property name="osgi.version.suffix" value=""/> - </target> - - <target name="init.build.suffix.done" depends="init.build.release, init.build.patch.release, init.osgi.suffix, init.osgi.suffix.final, init.osgi.suffix.snapshot"/> + <if><equals arg1="${maven.version.suffix}" arg2="-SNAPSHOT"/><then> + <property name="osgi.version.suffix" value=""/> + <property name="version.suffix" value=""/></then> + <else> + <property name="osgi.version.suffix" value="${maven.version.suffix}"/> + <property name="version.suffix" value="${maven.version.suffix}"/></else></if> - <target name="init.version.git" depends="init.build.suffix.done"> - <!-- Find out whether we are running on Windows --> - <condition property="os.win"> - <os family="windows"/> - </condition> <exec osfamily="unix" executable="tools/get-scala-commit-sha" outputproperty="git.commit.sha" failifexecutionfails="false" /> <exec osfamily="windows" executable="cmd.exe" outputproperty="git.commit.sha" failifexecutionfails="false"> @@ -371,71 +266,68 @@ INITIALISATION <arg value="tools\get-scala-commit-date.bat"/> <arg value="-p"/> </exec> + <!-- some default in case something went wrong getting the revision --> <property name="git.commit.sha" value="unknown"/> <property name="git.commit.date" value="unknown"/> <!-- We use the git describe to determine the OSGi modifier for our build. --> - <property - name="maven.version.number" - value="${version.major}.${version.minor}.${version.patch}${version.suffix}${maven.version.suffix}"/> - <property - name="osgi.version.number" - value="${version.major}.${version.minor}.${version.patch}.v${git.commit.date}${version.suffix}${osgi.version.suffix}-${git.commit.sha}"/> - </target> + <property name="maven.version.number" + value="${version.major}.${version.minor}.${version.patch}${maven.version.suffix}"/> + <property name="osgi.version.number" + value="${version.major}.${version.minor}.${version.patch}.v${git.commit.date}${osgi.version.suffix}-${git.commit.sha}"/> + + <if><isset property="build.release"/><then> + <property name="version.number" value="${maven.version.number}"/> + </then><else> + <property name="version.number" value="${version.major}.${version.minor}.${version.patch}${version.suffix}-${git.commit.date}-${git.commit.sha}"/> + </else></if> + + <condition property="has.java6"> + <equals arg1="${ant.java.version}" arg2="1.6"/> + </condition> + <condition property="has.java7"> + <equals arg1="${ant.java.version}" arg2="1.7"/> + </condition> + <condition property="has.unsupported.jdk"> + <not><or> + <isset property="has.java7" /> + <isset property="has.java6" /> + </or></not> + </condition> - <target name="init.version.snapshot" unless="build.release" depends="init.version.git"> - <property - name="version.number" - value="${version.major}.${version.minor}.${version.patch}${version.suffix}-${git.commit.date}-${git.commit.sha}"/> - </target> + <fail if="has.unsupported.jdk" message="JDK ${ant.java.version} is not supported by this build!"/> - <target name="init.version.release" if="build.release" depends="init.version.git"> - <property - name="version.number" - value="${maven.version.number}"/> - </target> + <if><isset property="has.java7"/><then> + <echo level="warning"> You are using JDK7 for this build. + While this will be able to build most of Scala, it will not build the Swing project. + You will be unable to create a distribution. + </echo> + </then></if> - <target name="init.version.done" depends="init.version.release, init.version.snapshot"/> + <!-- Allow this to be overridden simply --> + <property name="sbt.latest.version" value="0.12.2"/> - <target name="init.testjava6"> - <condition property="has.java6"> - <equals arg1="${ant.java.version}" arg2="1.6"/> - </condition> - <condition property="has.java7"> - <equals arg1="${ant.java.version}" arg2="1.7"/> - </condition> - <condition property="has.unsupported.jdk"> - <not><or> - <isset property="has.java7" /> - <isset property="has.java6" /> - </or></not> - </condition> - </target> + <property name="sbt.src.dir" value="${build-sbt.dir}/${sbt.latest.version}/src"/> + <property name="sbt.lib.dir" value="${build-sbt.dir}/${sbt.latest.version}/lib"/> - <target name="init.fail.bad.jdk" depends="init.testjava6"> - <fail if="has.unsupported.jdk" - message="JDK ${ant.java.version} is not supported by this build!"/> - </target> - <target name="init.warn.jdk7" depends="init.testjava6" if="has.java7"> - <echo level="warning"> You are using JDK7 for this build. While this will be able to build most of Scala, it will - not build the Swing project. You will be unable to create a distribution. - </echo> - </target> + <property name="sbt.interface.jar" value="${sbt.lib.dir}/interface.jar"/> + <property name="sbt.interface.url" value="http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/interface/${sbt.latest.version}/jars/interface.jar"/> + <property name="sbt.interface.src.jar" value="${sbt.src.dir}/compiler-interface-src.jar"/> + <property name="sbt.interface.src.url" value="http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/compiler-interface/${sbt.latest.version}/jars/compiler-interface-src.jar"/> - <target name="init" depends="init.jars, init.maven.jars, init.version.done, init.fail.bad.jdk, init.warn.jdk7, init.extra.tasks"> - <property name="scalac.args.always" value="-Yreify-copypaste" /> - <!-- scalac.args.optimise is selectively overridden in certain antcall tasks. --> - <property name="scalac.args.optimise" value=""/> - <!-- scalac.args.quickonly are added to quick.* targets but not others (particularly, locker.) - This is to facilitate testing new command line options which do not yet exist in starr. - Note: These are also used by strap since they may affect JVM target or other and we'd like - to be able to test binary stability of features. --> - <property name="scalac.args.quickonly" value=""/> + + <!-- Additional command line arguments for scalac. They are added to all build targets --> + <property name="scalac.args" value=""/> + <property name="javac.args" value=""/> + + <property name="scalac.args.always" value="" /> + <property name="scalac.args.optimise" value=""/> <!-- scalac.args.optimise is selectively overridden in certain antcall tasks. --> <property name="scalac.args.all" value="${scalac.args.always} ${scalac.args} ${scalac.args.optimise}"/> - <property name="scalac.args.quick" value="${scalac.args.all} ${scalac.args.quickonly}"/> - <!-- Setting-up Ant contrib tasks --> - <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant/ant-contrib.jar"/> + <property name="scalac.args.locker" value="${scalac.args.all}"/> + <property name="scalac.args.quick" value="${scalac.args.all}"/> + <property name="scalac.args.strap" value="${scalac.args.quick}"/> + <!-- This is the start time for the distribution --> <tstamp prefix="time"> <format property="human" pattern="d MMMM yyyy, HH:mm:ss" locale="en,US"/> @@ -446,30 +338,17 @@ INITIALISATION <property name="version.number" value="-unknown-"/> <property name="init.avail" value="yes"/> - <!-- Local libs (developer use.) --> <mkdir dir="${lib-extra.dir}"/> - <path id="lib.extra"> + <!-- Auxiliary libs placed on every classpath. --> + <path id="aux.libs"> + <pathelement location="${ant.jar}"/> <!-- needs ant 1.7.1 --> <!-- <fileset dir="${lib-extra.dir}" erroronmissingdir="false"> --> <fileset dir="${lib-extra.dir}"> <include name="**/*.jar"/> </fileset> - </path> - - <!-- Libraries only used for STARR --> - <path id="starr.dep.libs"> - <fileset dir="${lib.dir}"> - <include name="fjbg.jar"/> - <include name="forkjoin.jar"/> - <include name="msil.jar"/> - </fileset> - </path> - <!-- Auxiliary libs placed on every classpath. --> - <path id="aux.libs"> - <pathelement location="${ant.jar}"/> - <path refid="lib.extra"/> <path refid="dependency.classpath"/> </path> @@ -486,1195 +365,877 @@ INITIALISATION <echo message=" OSGi version: ${osgi.version.number}" /> <echo message="canonical version: ${version.number}" /> - <!-- Define tasks that can be run with Starr --> - <path id="starr.classpath"> - <pathelement location="${lib.starr.jar}"/> - <pathelement location="${reflect.starr.jar}"/> - <pathelement location="${comp.starr.jar}"/> + <!-- validate version suffixes --> + <if><equals arg1="${maven.version.suffix}" arg2="-SNAPSHOT"/><then> + <condition property="version.suffixes.consistent"><and> + <equals arg1="${osgi.version.suffix}" arg2=""/> + <equals arg1="${version.suffix}" arg2=""/> + </and></condition></then> + <else> + <if><equals arg1="${osgi.version.suffix}" arg2="-VFINAL"/><then> + <condition property="version.suffixes.consistent"><and> + <equals arg1="${maven.version.suffix}" arg2=""/> + <equals arg1="${version.suffix}" arg2=""/> + </and></condition></then> + <else> + <condition property="version.suffixes.consistent"><and> + <equals arg1="${osgi.version.suffix}" arg2="${maven.version.suffix}"/> + <equals arg1="${version.suffix}" arg2="${maven.version.suffix}"/> + </and></condition></else></if></else></if> + + <!-- <echo message=" maven suffix: ${maven.version.suffix}"/> + <echo message=" OSGi suffix: ${osgi.version.suffix}" /> + <echo message="canonical suffix: ${version.suffix}" /> --> + <fail unless="version.suffixes.consistent" message="Version suffixes inconsistent!"/> + + <path id="forkjoin.classpath" path="${build-libs.dir}/classes/forkjoin"/> + <path id="fjbg.classpath" path="${build-libs.dir}/classes/fjbg"/> + <path id="asm.classpath" path="${build-asm.dir}/classes/"/> + + <!-- Compilers to use for the various stages. + + There must be a variable of the shape @{stage}.compiler.path for all @{stage} in starr, locker, quick, strap. + --> + <path id="starr.compiler.path"> + <path refid="starr.core.path"/> + <pathelement location="${lib.dir}/forkjoin.jar"/> <path refid="aux.libs"/> - <path refid="starr.dep.libs"/> - </path> - <!-- What to have on the compilation path when compiling during certain phases --> - <path id="quick.compilation.path"> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-libs.dir}/classes/forkjoin"/> - <path refid="lib.extra"/> </path> - <path id="strap.compilation.path"> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-libs.dir}/classes/forkjoin"/> - <path refid="lib.extra"/> - </path> - <taskdef resource="scala/tools/ant/sabbus/antlib.xml" classpathref="starr.classpath"/> - </target> -<!-- =========================================================================== -LOCAL DEPENDENCY (Adapted ASM) -============================================================================ --> + <!-- Download STARR (see above) via maven if `starr.version` is specified. + Want to slow down STARR changes, using only released versions. --> + <if><isset property="starr.version"/><then> + <property name="strr" refid="starr.compiler.path"/> + <echo message="Using Scala ${starr.version} for STARR."/> + <!-- <echo message="STARR classpath: ${strr}"/> --> + </then><else> + <path id="starr.core.path"> + <pathelement location="${library.starr.jar}"/> + <pathelement location="${reflect.starr.jar}"/> + <pathelement location="${compiler.starr.jar}"/> + <pathelement location="${msil.starr.jar}"/> + </path> + </else></if> - <target name="asm.start" depends="init"> - <condition property="asm.available"> - <available file="${build-asm.dir}/asm.complete"/> - </condition> - </target> + <!-- Skip locker with -Dlocker.skip=YESSIR. Uses STARR instead. --> + <if><isset property="locker.skip"/><then> + <echo message="Skipping locker! Using STARR instead."/> + <path id="locker.compiler.path"><path refid="starr.compiler.path"/></path> + <property name="locker.locked" value="locker skipped"/></then> + <else> + <path id="locker.compiler.path"><path refid="locker.compiler.build.path"/></path></else></if> - <target name="asm.lib" depends="asm.start" unless="asm.available"> - <stopwatch name="asm.lib.timer"/> - <mkdir dir="${build-asm.dir}/classes/"/> - <javac - srcdir="${src.dir}/asm" - destdir="${build-asm.dir}/classes" - classpath="${build-asm.dir}/classes" - includes="**/*.java" - target="1.6" source="1.5"> - <compilerarg line="${javac.args} -XDignore.symbol.file"/> - </javac> - <touch file="${build-asm.dir}/asm.complete" verbose="no"/> - <stopwatch name="asm.lib.timer" action="total"/> - </target> + <!-- compilerpathref for compiling with quick --> + <path id="quick.compiler.path"> <path refid="quick.compiler.build.path"/></path> - <target name="asm.done" depends="asm.lib"> - <path id="asm.classpath"> - <pathelement location="${build-asm.dir}/classes/"/> - </path> - </target> + <!-- What to have on the compilation path when compiling during certain phases. - <target name="asm.clean" depends="init"> - <delete dir="${build-asm.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> - -<!-- =========================================================================== -LOCAL DEPENDENCY (FORKJOIN) -============================================================================ --> - <target name="forkjoin.start" depends="init"> - <uptodate property="forkjoin.available" targetfile="${build-libs.dir}/forkjoin.complete"> - <srcfiles dir="${src.dir}/forkjoin"> - <include name="**/*.java"/> - <include name="**/*.scala"/> - </srcfiles> - </uptodate> - </target> + There must be a variable of the shape @{stage}.@{project}.build.path + for all @{stage} in locker, quick, strap + and all @{project} in library, reflect, compiler + when stage is quick, @{project} also includes: actors, swing, plugins, scalacheck, partest, scalap + --> - <target name="forkjoin.lib" depends="forkjoin.start" unless="forkjoin.available"> - <stopwatch name="forkjoin.lib.timer"/> - <mkdir dir="${build-libs.dir}/classes/forkjoin"/> - <javac - fork="yes" - compiler="javac1.6" - srcdir="${src.dir}/forkjoin" - destdir="${build-libs.dir}/classes/forkjoin" - classpath="${build-libs.dir}/classes/forkjoin" - includes="**/*.java" - debug="true" - target="1.6" source="1.5"> - <compilerarg line="${javac.args} -XDignore.symbol.file"/> - </javac> - <touch file="${build-libs.dir}/forkjoin.complete" verbose="no"/> - <stopwatch name="forkjoin.lib.timer" action="total"/> - </target> - - <target name="forkjoin.pack" depends="forkjoin.lib"> - <jar destfile="${build-libs.dir}/forkjoin.jar"> - <fileset dir="${build-libs.dir}/classes/forkjoin"/> - </jar> - </target> + <!-- LOCKER --> + <path id="locker.library.build.path"> + <pathelement location="${build-locker.dir}/classes/library"/> + <path refid="forkjoin.classpath"/> + <path refid="aux.libs"/> + </path> - <target name="forkjoin.done" depends="forkjoin.pack"> - <!-- TODO - jar or classfiles? --> - <path id="forkjoin.classpath"> - <pathelement location="${build-libs.dir}/classes/forkjoin"/> + <path id="locker.reflect.build.path"> + <path refid="locker.library.build.path"/> + <pathelement location="${build-locker.dir}/classes/reflect"/> </path> - </target> - <target name="forkjoin.clean" depends="init"> - <delete dir="${build-libs.dir}/classes/forkjoin" includeemptydirs="yes" quiet="yes" failonerror="no"/> - <delete file="${build-libs.dir}/forkjoin.complete" quiet="yes" failonerror="no"/> - </target> + <path id="locker.compiler.build.path"> + <path refid="locker.reflect.build.path"/> + <pathelement location="${build-locker.dir}/classes/compiler"/> + <path refid="asm.classpath"/> + <path refid="fjbg.classpath"/> + <pathelement location="${jline.jar}"/> + </path> -<!-- =========================================================================== -LOCAL DEPENDENCY (FJBG) -============================================================================ --> + <path id="locker.msil.build.path" refid="locker.compiler.build.path"/> - <target name="fjbg.init" depends="init"> - <uptodate property="fjbg.available" targetfile="${build-libs.dir}/fjbg.complete"> - <srcfiles dir="${src.dir}/fjbg"> - <include name="**/*.java"/> - <include name="**/*.scala"/> - </srcfiles> - </uptodate> - </target> + <!-- QUICK --> + <path id="quick.library.build.path"> + <pathelement location="${build-quick.dir}/classes/library"/> + <path refid="forkjoin.classpath"/> + <path refid="aux.libs"/> + </path> - <target name="fjbg.lib" depends="fjbg.init" unless="fjbg.available"> - <stopwatch name="fjbg.lib.timer" /> - <mkdir dir="${build-libs.dir}/classes/fjbg"/> - <javac - srcdir="${src.dir}/fjbg" - destdir="${build-libs.dir}/classes/fjbg" - classpath="${build-libs.dir}/classes/fjbg" - includes="**/*.java" - debug="true" - target="1.6" source="1.4"> - <compilerarg line="${javac.args} -XDignore.symbol.file"/> - </javac> - <touch file="${build-libs.dir}/fjbg.complete" verbose="no"/> - <stopwatch name="fjbg.lib.timer" action="total"/> - </target> - - <target name="fjbg.pack" depends="fjbg.lib"> - <jar destfile="${build-libs.dir}/fjbg.jar"> - <fileset dir="${build-libs.dir}/classes/fjbg"/> - </jar> - </target> + <path id="quick.actors.build.path"><path refid="quick.library.build.path"/></path> - <target name="fjbg.done" depends="fjbg.pack"> - <!-- TODO - jar or classfiles? --> - <path id="fjbg.classpath"> - <pathelement location="${build-libs.dir}/classes/fjbg"/> + <path id="quick.reflect.build.path"> + <path refid="quick.library.build.path"/> + <pathelement location="${build-quick.dir}/classes/reflect"/> </path> - </target> - <target name="fjbg.clean" depends="init"> - <delete dir="${build-libs.dir}/classes/fjbg" includeemptydirs="yes" quiet="yes" failonerror="no"/> - <delete file="${build-libs.dir}/fjbg.complete" quiet="yes" failonerror="no"/> - </target> - -<!-- =========================================================================== -LOCAL REFERENCE BUILD (LOCKER) -============================================================================ --> + <path id="quick.compiler.build.path"> + <path refid="quick.reflect.build.path"/> + <pathelement location="${build-quick.dir}/classes/compiler"/> + <path refid="asm.classpath"/> + <path refid="fjbg.classpath"/> + <pathelement location="${jline.jar}"/> + </path> - <target name="locker.start" depends="asm.done, forkjoin.done, fjbg.done"> - <condition property="locker.available"> - <available file="${build-locker.dir}/all.complete"/> - </condition> - </target> + <path id="quick.swing.build.path" refid="quick.library.build.path"/> + <path id="quick.msil.build.path" refid="quick.compiler.build.path"/> - <target name="locker.pre-lib" depends="locker.start" unless="locker.available"> - <condition property="locker.lib.needed"> - <not><available file="${build-locker.dir}/library.complete"/></not> - </condition> - </target> + <path id="quick.plugins.build.path"> + <path refid="quick.compiler.build.path"/> + <pathelement location="${build-quick.dir}/classes/continuations-plugin"/> + </path> - <target name="locker.lib" depends="locker.pre-lib" if="locker.lib.needed"> - <stopwatch name="locker.lib.timer"/> - <mkdir dir="${build-locker.dir}/classes/library"/> - <javac - srcdir="${src.dir}/library" - destdir="${build-locker.dir}/classes/library" - includes="**/*.java" - target="1.6" source="1.5"> - <compilerarg line="${javac.args} -XDignore.symbol.file"/> - <classpath> - <path refid="forkjoin.classpath"/> - <pathelement location="${build-locker.dir}/classes/library"/> - </classpath> - </javac> - <!-- NOTE: Potential problem with maximal command line length on Windows - (32768 characters for XP, since executed with Java's "exec"). See - src/build/msil.xml in msil branch for more details. --> - <scalacfork - destdir="${build-locker.dir}/classes/library" - compilerpathref="starr.classpath" - srcpath="${src.dir}/library" - params="${scalac.args.all}" - srcdir="${src.dir}/library" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-locker.dir}/classes/library"/> - <path refid="forkjoin.classpath"/> - </compilationpath> - </scalacfork> - <propertyfile file="${build-locker.dir}/classes/library/library.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-locker.dir}/classes/library"> - <fileset dir="${src.dir}/library"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.css"/> - </fileset> - </copy> - <touch file="${build-locker.dir}/library.complete" verbose="no"/> - <stopwatch name="locker.lib.timer" action="total"/> - </target> + <path id="quick.scalacheck.build.path"> + <pathelement location="${build-quick.dir}/classes/library"/> + <pathelement location="${build-quick.dir}/classes/scalacheck"/> + </path> + <path id="quick.scalap.build.path"> + <path refid="quick.compiler.build.path"/> + <pathelement location="${build-quick.dir}/classes/scalap"/> + <pathelement location="${build-quick.dir}/classes/partest"/> + </path> - <target name="locker.pre-reflect" depends="locker.lib" unless="locker.available"> - <condition property="locker.reflect.needed"> - <not><available file="${build-locker.dir}/reflect.complete"/></not> - </condition> - </target> + <path id="quick.partest.build.path"> + <path refid="quick.scalap.build.path"/> + <pathelement location="${scalacheck.jar}"/> + </path> - <target name="locker.reflect" depends="locker.pre-reflect" if="locker.reflect.needed"> - <stopwatch name="locker.reflect.timer"/> - <mkdir dir="${build-locker.dir}/classes/reflect"/> - <scalacfork - destdir="${build-locker.dir}/classes/reflect" - compilerpathref="starr.classpath" - params="${scalac.args.all}" - srcdir="${src.dir}/reflect" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-locker.dir}/classes/library"/> - <pathelement location="${build-locker.dir}/classes/reflect"/> - <path refid="aux.libs"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <!-- TODO - needed? --> - <propertyfile file="${build-locker.dir}/classes/reflect/reflect.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-locker.dir}/classes/reflect"> - <fileset dir="${src.dir}/reflect"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.html"/> - <include name="**/*.css"/> - <include name="**/*.properties"/> - <include name="**/*.swf"/> - <include name="**/*.png"/> - <include name="**/*.gif"/> - </fileset> - </copy> - <touch file="${build-locker.dir}/reflect.complete" verbose="no"/> - <stopwatch name="locker.reflect.timer" action="total"/> - </target> + <path id="quick.bin.tool.path"> + <pathelement location="${build-quick.dir}/classes/library"/> + <pathelement location="${build-quick.dir}/classes/reflect"/> + <pathelement location="${build-quick.dir}/classes/compiler"/> + <pathelement location="${build-quick.dir}/classes/scalap"/> + <pathelement location="${build-quick.dir}/classes/continuations-library"/> + <pathelement location="${jline.jar}"/> + <path refid="asm.classpath"/> + <path refid="forkjoin.classpath"/> + <path refid="aux.libs"/> + </path> - <target name="locker.pre-comp" depends="locker.reflect" unless="locker.available"> - <condition property="locker.comp.needed"> - <not><available file="${build-locker.dir}/compiler.complete"/></not> - </condition> - </target> + <!-- PACK --> + <path id="pack.compiler.path"> + <pathelement location="${build-pack.dir}/lib/scala-library.jar"/> + <pathelement location="${build-pack.dir}/lib/scala-reflect.jar"/> + <pathelement location="${build-pack.dir}/lib/scala-compiler.jar"/> + <pathelement location="${build-pack.dir}/lib/scala-partest.jar"/> + <pathelement location="${build-pack.dir}/lib/scalap.jar"/> + <pathelement location="${build-pack.dir}/lib/scala-actors.jar"/> + <pathelement location="${ant.jar}"/> + <pathelement location="${jline.jar}"/> + <path refid="aux.libs"/> + </path> + <path id="pack.bin.tool.path"> + <pathelement location="${build-pack.dir}/lib/scala-library.jar"/> + <pathelement location="${build-pack.dir}/lib/scala-reflect.jar"/> + <pathelement location="${build-pack.dir}/lib/scala-compiler.jar"/> + <pathelement location="${build-pack.dir}/lib/scalap.jar"/> + <pathelement location="${build-pack.dir}/lib/jline.jar"/> + <path refid="aux.libs"/> + </path> - <target name="locker.comp" depends="locker.pre-comp" if="locker.comp.needed"> - <stopwatch name="locker.comp.timer"/> - <mkdir dir="${build-locker.dir}/classes/compiler"/> - <if> - <equals arg1="${fastlocker}" arg2="true" /> - <then> - <!-- Fastlocker build: don't compile MSIL, use its starr version.... --> - <property name="locker.comp.msil" value="${msil.starr.jar}"/> - </then> - <else> - <!-- Regular build: Compile MSIL inside of locker.... --> - <javac - srcdir="${src.dir}/msil" - destdir="${build-locker.dir}/classes/compiler" - classpath="${build-locker.dir}/classes/compiler" - includes="**/*.java" - excludes="**/tests/**" - debug="true" - target="1.6" source="1.4"> - <compilerarg line="${javac.args}"/> - </javac> - <scalacfork - destdir="${build-locker.dir}/classes/compiler" - compilerpathref="starr.classpath" - params="${scalac.args.all}" - srcdir="${src.dir}/msil" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-locker.dir}/classes/library"/> - <pathelement location="${build-locker.dir}/classes/reflect"/> - <pathelement location="${build-locker.dir}/classes/compiler"/> - <path refid="fjbg.classpath"/> - <path refid="aux.libs"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <property name="locker.comp.msil" value="${build-locker.dir}/classes/compiler"/> - </else> - </if> - <scalacfork - destdir="${build-locker.dir}/classes/compiler" - compilerpathref="starr.classpath" - params="${scalac.args.all}" - srcdir="${src.dir}/compiler" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-locker.dir}/classes/library"/> - <pathelement location="${build-locker.dir}/classes/reflect"/> - <pathelement location="${build-locker.dir}/classes/compiler"/> - <path refid="fjbg.classpath"/> - <path refid="aux.libs"/> - <path refid="asm.classpath"/> - <pathelement location="${locker.comp.msil}" /> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <propertyfile file="${build-locker.dir}/classes/compiler/compiler.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-locker.dir}/classes/compiler"> - <fileset dir="${src.dir}/compiler"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.html"/> - <include name="**/*.css"/> - <include name="**/*.properties"/> - <include name="**/*.swf"/> - <include name="**/*.png"/> - <include name="**/*.gif"/> - </fileset> - </copy> - <touch file="${build-locker.dir}/compiler.complete" verbose="no"/> - <stopwatch name="locker.comp.timer" action="total"/> - </target> - <target name="locker.done" depends="locker.comp"> - <touch file="${build-locker.dir}/all.complete" verbose="no"/> - <path id="locker.classpath"> - <pathelement location="${build-locker.dir}/classes/library"/> - <pathelement location="${build-locker.dir}/classes/reflect"/> - <pathelement location="${build-locker.dir}/classes/compiler"/> - <path refid="fjbg.classpath"/> + <!-- STRAP --> + <path id="strap.library.build.path"> + <pathelement location="${build-strap.dir}/classes/library"/> <path refid="forkjoin.classpath"/> - <path refid="asm.classpath"/> <path refid="aux.libs"/> </path> - <!-- TODO - Why is this *here* ? --> - <path id="quick.classpath"> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> + <path id="strap.actors.build.path" refid="strap.library.build.path"/> + <path id="strap.msil.build.path" refid="strap.compiler.build.path"/> + + <path id="strap.reflect.build.path"> + <path refid="strap.library.build.path"/> + <pathelement location="${build-strap.dir}/classes/reflect"/> + </path> + + <path id="strap.compiler.build.path"> + <path refid="strap.reflect.build.path"/> + <pathelement location="${build-strap.dir}/classes/compiler"/> + <path refid="asm.classpath"/> <path refid="fjbg.classpath"/> + <pathelement location="${jline.jar}"/> + </path> + + <!-- MISC --> + <path id="sbt.compile.build.path"> + <path refid="quick.compiler.build.path"/> + <pathelement location="${sbt.interface.jar}"/> + </path> + + <path id="manual.classpath"> + <pathelement location="${build-pack.dir}/lib/scala-library.jar"/> + <pathelement location="${build.dir}/manmaker/classes"/> + </path> + + <path id="partest.classpath"> + <path refid="pack.compiler.path"/> + <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> + <pathelement location="${pack.dir}/lib/scala-swing.jar"/> <!-- TODO - segregate swing tests (there can't be many) --> + </path> + + <path id="test.osgi.compiler.build.path"> + <pathelement location="${test.osgi.classes}"/> + <pathelement location="${build-osgi.dir}/org.scala-lang.scala-library.jar"/> + <pathelement location="${build-osgi.dir}/org.scala-lang.scala-reflect.jar"/> + <pathelement location="${build-osgi.dir}/org.scala-lang.scala-compiler.jar"/> + <pathelement location="${build-osgi.dir}/org.scala-lang.scala-actors.jar"/> + <path refid="pax.exam.classpath"/> <path refid="forkjoin.classpath"/> - <path refid="asm.classpath"/> - <path refid="aux.libs"/> </path> - </target> - <target name="locker.clean" depends="palo.clean"> - <delete dir="${build-locker.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> + <path id="palo.bin.tool.path"> + <pathelement location="${build-palo.dir}/lib/scala-library.jar"/> + <pathelement location="${build-palo.dir}/lib/scala-reflect.jar"/> + <pathelement location="${build-palo.dir}/lib/scala-compiler.jar"/> + <pathelement location="${build-palo.dir}/lib/jline.jar"/> + </path> - <target name="locker.unlock.pre-lib"> - <uptodate property="locker.lib.available" targetfile="${build-locker.dir}/library.complete"> - <srcfiles dir="${src.dir}"> - <include name="library/**"/> - </srcfiles> - </uptodate> + <path id="test.positions.sub.build.path" path="${build-quick.dir}/classes/library"/> + + <!-- TODO: consolidate *.includes --> + <patternset id="partest.includes"> + <include name="**/*.xml"/> + </patternset> + + <patternset id="lib.includes"> + <include name="**/*.tmpl"/> + <include name="**/*.xml"/> + <include name="**/*.js"/> + <include name="**/*.css"/> + </patternset> + + <patternset id="lib.rootdoc.includes"> + <include name="**/*.tmpl"/> + <include name="**/*.xml"/> + <include name="**/*.js"/> + <include name="**/*.css"/> + <include name="rootdoc.txt"/> + </patternset> + + <patternset id="comp.includes"> + <include name="**/*.tmpl"/> + <include name="**/*.xml"/> + <include name="**/*.js"/> + <include name="**/*.css"/> + <include name="**/*.html"/> + <include name="**/*.properties"/> + <include name="**/*.swf"/> + <include name="**/*.png"/> + <include name="**/*.gif"/> + <include name="**/*.txt"/> + </patternset> + + <taskdef resource="scala/tools/ant/sabbus/antlib.xml" classpathref="starr.compiler.path"/> </target> - <target name="locker.unlock.lib" depends="locker.unlock.pre-lib" unless="locker.lib.available"> - <delete file="${build-locker.dir}/library.complete"/> - </target> +<!-- =========================================================================== + CLEANLINESS +=============================================================================--> + <target name="libs.clean"> <clean build="libs"/> <clean build="asm"/> </target> + <target name="quick.clean" depends="libs.clean"> <clean build="quick"/> <clean build="pack"/> <clean build="strap"/> </target> + <target name="palo.clean" depends="quick.clean"> <clean build="palo"/> </target> + <target name="locker.clean" depends="palo.clean"> <clean build="locker"/> </target> - <target name="locker.unlock.pre-reflect" depends="locker.unlock.lib"> - <uptodate property="locker.reflect.available" targetfile="${build-locker.dir}/reflect.complete"> - <srcfiles dir="${src.dir}"> - <include name="reflect/**"/> - </srcfiles> - </uptodate> - </target> + <target name="docs.clean"> <clean build="docs"/> <delete dir="${build.dir}/manmaker" includeemptydirs="yes" quiet="yes" failonerror="no"/> </target> + <target name="dist.clean"> <delete dir="${dists.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> </target> - <target name="locker.unlock.reflect" depends="locker.unlock.pre-reflect" unless="locker.reflect.available"> - <delete file="${build-locker.dir}/reflect.complete"/> - </target> + <target name="all.clean" depends="locker.clean, docs.clean"> <clean build="sbt"/> <clean build="osgi"/> </target> - <target name="locker.unlock.pre-comp" depends="locker.unlock.reflect"> - <uptodate property="locker.comp.available" targetfile="${build-locker.dir}/compiler.complete"> - <srcfiles dir="${src.dir}"> - <include name="compiler/**"/> - </srcfiles> - </uptodate> + <!-- Used by the scala-installer script --> + <target name="allallclean" depends="all.clean, dist.clean"/> + + <macrodef name="clean"> + <attribute name="build"/> + <sequential> + <delete dir="${build-@{build}.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> + </sequential> + </macrodef> + +<!-- =========================================================================== + LOCAL DEPENDENCY (FJBG) +============================================================================ --> + <target name="fjbg.done" depends="init"> + <uptodate property="fjbg.available" targetfile="${build-libs.dir}/fjbg.complete"> + <srcfiles dir="${src.dir}/forkjoin"/></uptodate> + <if><not><isset property="fjbg.available"/></not><then> + <stopwatch name="fjbg.lib.timer"/> + <mkdir dir="${build-libs.dir}/classes/fjbg"/> + <javac + srcdir="${src.dir}/fjbg" + destdir="${build-libs.dir}/classes/fjbg" + classpath="${build-libs.dir}/classes/fjbg" + includes="**/*.java" + target="1.6" source="1.5"> + <compilerarg line="${javac.args}"/> + </javac> + <jar whenmanifestonly="fail" destfile="${build-libs.dir}/fjbg.jar" basedir="${build-libs.dir}/classes/fjbg"/> + <stopwatch name="fjbg.lib.timer" action="total"/> + <touch file="${build-libs.dir}/fjbg.complete" verbose="no"/> + </then></if> </target> - <target name="locker.unlock.comp" depends="locker.unlock.pre-comp" unless="locker.comp.available"> - <delete file="${build-locker.dir}/compiler.complete"/> +<!-- =========================================================================== + LOCAL DEPENDENCY (Adapted ASM) +============================================================================ --> + <target name="asm.done" depends="init"> + <available file="${build-asm.dir}/asm.complete" property="asm.available"/> + <if><not><isset property="asm.available"/></not><then> + <stopwatch name="asm.lib.timer"/> + <mkdir dir="${build-asm.dir}/classes/"/> + <javac + srcdir="${src.dir}/asm" + destdir="${build-asm.dir}/classes" + classpath="${build-asm.dir}/classes" + includes="**/*.java" + target="1.6" source="1.5"> + <compilerarg line="${javac.args} -XDignore.symbol.file"/> + </javac> + <stopwatch name="asm.lib.timer" action="total"/> + <touch file="${build-asm.dir}/asm.complete" verbose="no"/> + </then></if> </target> - <target name="locker.unlock" depends="locker.unlock.comp"> - <delete file="${build-locker.dir}/all.complete" /> +<!-- =========================================================================== + LOCAL DEPENDENCY (FORKJOIN) +============================================================================ --> + <target name="forkjoin.done" depends="init"> + <uptodate property="forkjoin.available" targetfile="${build-libs.dir}/forkjoin.complete"> + <srcfiles dir="${src.dir}/forkjoin"/></uptodate> + <if><not><isset property="forkjoin.available"/></not><then> + <stopwatch name="forkjoin.lib.timer"/> + <mkdir dir="${build-libs.dir}/classes/forkjoin"/> + <javac + fork="yes" + compiler="javac1.6" + srcdir="${src.dir}/forkjoin" + destdir="${build-libs.dir}/classes/forkjoin" + classpath="${build-libs.dir}/classes/forkjoin" + includes="**/*.java" + debug="true" + target="1.6" source="1.5"> + <compilerarg line="${javac.args} -XDignore.symbol.file"/> + </javac> + <jar whenmanifestonly="fail" destfile="${build-libs.dir}/forkjoin.jar" basedir="${build-libs.dir}/classes/forkjoin"/> + <stopwatch name="forkjoin.lib.timer" action="total"/> + <touch file="${build-libs.dir}/forkjoin.complete" verbose="no"/> + </then></if> </target> <!-- =========================================================================== -PACKED LOCKER BUILD (PALO) + STAGED COMPILATION MACROS ============================================================================ --> + <macrodef name="staged-javac" > + <attribute name="stage"/> <!-- current stage (locker, quick, strap) --> + <attribute name="project"/> <!-- project: library/reflect/compiler/actors --> + <attribute name="destproject" default="@{project}"/> <!-- overrides the output directory; used when building multiple projects into the same directory--> + <attribute name="args" default=""/> + <attribute name="excludes" default=""/> - <target name="palo.start" depends="locker.done"/> + <sequential> + <javac + srcdir="${src.dir}/@{project}" + destdir="${build-@{stage}.dir}/classes/@{destproject}" + includes="**/*.java" + excludes="@{excludes}" + target="1.6" source="1.5"> + <compilerarg line="${javac.args} @{args}"/> + <classpath refid="@{stage}.@{destproject}.build.path"/> + </javac> + </sequential> + </macrodef> - <target name="palo.pre-lib" depends="palo.start"> - <uptodate - property="palo.lib.available" - targetfile="${build-palo.dir}/lib/scala-library.jar" - srcfile="${build-locker.dir}/library.complete"/> - </target> + <macrodef name="staged-scalac" > + <attribute name="with"/> <!-- will use path `@{with}.compiler.path` to locate scalac --> + <attribute name="stage"/> <!-- current stage (locker, quick, strap) --> + <attribute name="project"/> <!-- project: library/reflect/compiler/actors --> + <attribute name="srcpath" default="NOT SET"/> <!-- needed to compile the library --> + <attribute name="args" default=""/> <!-- additional args --> + <attribute name="destproject" default="@{project}"/> <!-- overrides the output directory; used when building multiple projects into the same directory--> + <attribute name="srcdir" default="@{project}"/> + <element name="args" implicit="true" optional="true"/> - <target name="palo.lib" depends="palo.pre-lib" unless="palo.lib.available"> - <mkdir dir="${build-palo.dir}/lib"/> - <jar destfile="${build-palo.dir}/lib/scala-library.jar"> - <fileset dir="${build-locker.dir}/classes/library"/> - <fileset dir="${build-libs.dir}/classes/forkjoin"/> - </jar> - </target> + <sequential> + <if><equals arg1="@{srcpath}" arg2="NOT SET"/><then> + <scalacfork taskname="@{stage}.@{project}" + destdir="${build-@{stage}.dir}/classes/@{destproject}" + compilerpathref="@{with}.compiler.path" + params="${scalac.args.@{stage}} @{args}" + srcdir="${src.dir}/@{srcdir}" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath refid="@{stage}.@{project}.build.path"/> + <args/> + </scalacfork></then> + <else> + <scalacfork taskname="@{stage}.@{project}" + destdir="${build-@{stage}.dir}/classes/@{destproject}" + compilerpathref="@{with}.compiler.path" + srcpath="@{srcpath}" + params="${scalac.args.@{stage}} @{args}" + srcdir="${src.dir}/@{srcdir}" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath refid="@{stage}.@{project}.build.path"/> + <args/> + </scalacfork></else> + </if> + </sequential> + </macrodef> - <target name="palo.pre-reflect" depends="palo.lib"> - <uptodate - property="palo.reflect.available" - targetfile="${build-palo.dir}/lib/scala-reflect.jar" - srcfile="${build-locker.dir}/reflect.complete"/> - </target> + <macrodef name="staged-uptodate" > + <attribute name="stage"/> + <attribute name="project"/> + <element name="check"/> + <element name="do"/> - <target name="palo.reflect" depends="palo.pre-reflect" unless="palo.reflect.available"> - <mkdir dir="${build-palo.dir}/lib"/> - <jar destfile="${build-palo.dir}/lib/scala-reflect.jar" manifest="${basedir}/META-INF/MANIFEST.MF"> - <fileset dir="${build-locker.dir}/classes/reflect"/> - </jar> - </target> + <sequential> + <uptodate property="@{stage}.@{project}.available" targetfile="${build-@{stage}.dir}/@{project}.complete"> + <check/> + </uptodate> + <if><not><isset property="@{stage}.@{project}.available"/></not><then> + <do/> + <touch file="${build-@{stage}.dir}/@{project}.complete" verbose="no"/> + </then></if> + </sequential> + </macrodef> - <target name="palo.pre-comp" depends="palo.reflect"> - <uptodate - property="palo.comp.available" - targetfile="${build-palo.dir}/lib/scala-compiler.jar" - srcfile="${build-locker.dir}/compiler.complete"/> - </target> + <macrodef name="staged-build" > + <attribute name="with"/> <!-- will use path `@{with}.compiler.path` to locate scalac --> + <attribute name="stage"/> <!-- current stage (locker, quick, strap) --> + <attribute name="project"/> <!-- project: library/reflect/compiler/actors --> + <attribute name="srcpath" default="NOT SET"/> <!-- needed to compile the library --> + <attribute name="args" default=""/> <!-- additional args --> + <attribute name="includes" default="comp.includes"/> + <attribute name="version" default=""/> <!-- non-empty for partest and scaladoc: use @{version}.version.number in property file--> - <target name="palo.comp" depends="palo.pre-comp" unless="palo.comp.available"> - <mkdir dir="${build-palo.dir}/lib"/> - <jar destfile="${build-palo.dir}/lib/scala-compiler.jar" manifest="${basedir}/META-INF/MANIFEST.MF"> - <fileset dir="${build-locker.dir}/classes/compiler"/> - <fileset dir="${build-asm.dir}/classes/"/> - <fileset dir="${build-libs.dir}/classes/fjbg"/> - </jar> - <copy file="${jline.jar}" toDir="${build-palo.dir}/lib"/> - </target> + <element name="pre" optional="true"/> + <element name="post" optional="true"/> - <target name="palo.done" depends="palo.comp"> - </target> + <sequential> + <staged-uptodate stage="@{stage}" project="@{project}"> + <check><srcfiles dir="${src.dir}/@{project}"/></check> + <do> + <stopwatch name="@{stage}.@{project}.timer"/> + <mkdir dir="${build-@{stage}.dir}/classes/@{project}"/> + <pre/> + <staged-scalac with="@{with}" stage="@{stage}" project="@{project}" srcpath="@{srcpath}" args="@{args}"/> + <post/> + <if><equals arg1="@{version}" arg2=""/><then> + <propertyfile file = "${build-@{stage}.dir}/classes/@{project}/@{project}.properties"> + <entry key = "version.number" value="${version.number}"/> + <entry key = "maven.version.number" value="${maven.version.number}"/> + <entry key = "osgi.version.number" value="${osgi.version.number}"/> + <entry key = "copyright.string" value="${copyright.string}"/> + </propertyfile> + </then><else> + <propertyfile file = "${build-@{stage}.dir}/classes/@{project}/@{project}.properties"> + <entry key = "version.number" value="${@{version}.version.number}"/> + <entry key = "copyright.string" value="${copyright.string}"/> + </propertyfile> + </else></if> + <copy todir="${build-@{stage}.dir}/classes/@{project}"> + <fileset dir="${src.dir}/@{project}"> + <patternset refid="@{includes}"/> + </fileset> + </copy> + <stopwatch name="@{stage}.@{project}.timer" action="total"/> + </do> + </staged-uptodate> + </sequential> + </macrodef> - <target name="palo.clean" depends="quick.clean"> - <delete dir="${build-palo.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> + <macrodef name="staged-bin"> + <attribute name="stage"/> + <attribute name="classpathref" default="NOT SET"/> + <sequential> + <staged-uptodate stage="@{stage}" project="bin"> + <check> + <srcfiles dir="${src.dir}"> + <include name="compiler/scala/tools/ant/templates/**"/> + </srcfiles> + </check> + <do> + <taskdef name="mk-bin" classname="scala.tools.ant.ScalaTool" classpathref="@{stage}.bin.tool.path"/> + <mkdir dir="${build-@{stage}.dir}/bin"/> + <if><equals arg1="@{classpathref}" arg2="NOT SET"/><then> + <mk-bin file="${build-@{stage}.dir}/bin/scala" class="scala.tools.nsc.MainGenericRunner" javaFlags="${java.flags}"/> + <mk-bin file="${build-@{stage}.dir}/bin/scalac" class="scala.tools.nsc.Main" javaFlags="${java.flags}"/> + <mk-bin file="${build-@{stage}.dir}/bin/scaladoc" class="scala.tools.nsc.ScalaDoc" javaFlags="${java.flags}"/> + <mk-bin file="${build-@{stage}.dir}/bin/fsc" class="scala.tools.nsc.CompileClient" javaFlags="${java.flags}"/> + <mk-bin file="${build-@{stage}.dir}/bin/scalap" class="scala.tools.scalap.Main" javaFlags="${java.flags}"/> + </then><else> + <mk-bin file="${build-@{stage}.dir}/bin/scala" class="scala.tools.nsc.MainGenericRunner" javaFlags="${java.flags}" classpathref="@{classpathref}"/> + <mk-bin file="${build-@{stage}.dir}/bin/scalac" class="scala.tools.nsc.Main" javaFlags="${java.flags}" classpathref="@{classpathref}"/> + <mk-bin file="${build-@{stage}.dir}/bin/scaladoc" class="scala.tools.nsc.ScalaDoc" javaFlags="${java.flags}" classpathref="@{classpathref}"/> + <mk-bin file="${build-@{stage}.dir}/bin/fsc" class="scala.tools.nsc.CompileClient" javaFlags="${java.flags}" classpathref="@{classpathref}"/> + <mk-bin file="${build-@{stage}.dir}/bin/scalap" class="scala.tools.scalap.Main" javaFlags="${java.flags}" classpathref="@{classpathref}"/> + </else></if> + <chmod perm="ugo+rx" file="${build-@{stage}.dir}/bin/scala"/> + <chmod perm="ugo+rx" file="${build-@{stage}.dir}/bin/scalac"/> + <chmod perm="ugo+rx" file="${build-@{stage}.dir}/bin/scaladoc"/> + <chmod perm="ugo+rx" file="${build-@{stage}.dir}/bin/fsc"/> + <chmod perm="ugo+rx" file="${build-@{stage}.dir}/bin/scalap"/> + </do> + </staged-uptodate> + </sequential> + </macrodef> - <target name="palo.pre-bin" depends="palo.comp"> - <uptodate property="palo.bin.available" targetfile="${build-locker.dir}/bin.complete"> - <srcfiles dir="${src.dir}"> - <include name="compiler/scala/tools/ant/templates/**"/> - </srcfiles> - </uptodate> - </target> + <macrodef name="staged-pack"> + <attribute name="project"/> + <attribute name="targetdir" default="lib"/> + <attribute name="targetjar" default="scala-@{project}.jar"/> + <element name="do" implicit="true"/> - <target name="palo.bin" depends="palo.pre-bin" unless="palo.bin.available"> - <taskdef name="palo-bin" classname="scala.tools.ant.ScalaTool"> - <classpath> - <pathelement location="${build-palo.dir}/lib/scala-library.jar"/> - <pathelement location="${build-palo.dir}/lib/scala-reflect.jar"/> - <pathelement location="${build-palo.dir}/lib/scala-compiler.jar"/> - <pathelement location="${build-palo.dir}/lib/jline.jar"/> - </classpath> - </taskdef> - <mkdir dir="${build-palo.dir}/bin"/> - <palo-bin - file="${build-palo.dir}/bin/scala" - class="scala.tools.nsc.MainGenericRunner" - javaFlags="${java.flags}"/> - <palo-bin - file="${build-palo.dir}/bin/scalac" - class="scala.tools.nsc.Main" - javaFlags="${java.flags}"/> - <palo-bin - file="${build-palo.dir}/bin/scaladoc" - class="scala.tools.nsc.ScalaDoc" - javaFlags="${java.flags}"/> - <palo-bin - file="${build-palo.dir}/bin/fsc" - class="scala.tools.nsc.CompileClient" - javaFlags="${java.flags}"/> - <palo-bin - file="${build-palo.dir}/bin/scalap" - class="scala.tools.scalap.Main" - javaFlags="${java.flags}"/> - <chmod perm="ugo+rx" file="${build-palo.dir}/bin/scala"/> - <chmod perm="ugo+rx" file="${build-palo.dir}/bin/scalac"/> - <chmod perm="ugo+rx" file="${build-palo.dir}/bin/scaladoc"/> - <chmod perm="ugo+rx" file="${build-palo.dir}/bin/fsc"/> - <chmod perm="ugo+rx" file="${build-palo.dir}/bin/scalap"/> - <touch file="${build-locker.dir}/bin.complete" verbose="no"/> - </target> + <sequential> + <uptodate property="pack.@{project}.available" + targetfile="${build-pack.dir}/@{targetdir}/@{targetjar}" + srcfile="${build-quick.dir}/@{project}.complete"/> + <if><not><isset property="pack.@{project}.available"/></not><then> + <mkdir dir="${build-pack.dir}/@{targetdir}"/> + <do/> + </then></if> + </sequential> + </macrodef> + + <macrodef name="staged-docs"> + <attribute name="project"/> + <attribute name="dir" default="@{project}"/> + <attribute name="title"/> + <attribute name="docroot" default="NOT SET"/> + <element name="includes" implicit="true"/> + + <sequential> + <staged-uptodate stage="docs" project="@{project}"> + <check><srcfiles dir="${src.dir}/@{dir}"/></check> + <do> + <stopwatch name="docs.@{project}.timer"/> + <mkdir dir="${build-docs.dir}/@{project}"/> + <if><equals arg1="@{docroot}" arg2="NOT SET"/><then> + <scaladoc + destdir="${build-docs.dir}/@{project}" + doctitle="@{title}" + docversion="${version.number}" + sourcepath="${src.dir}" + classpathref="pack.compiler.path" + srcdir="${src.dir}/@{dir}" + addparams="${scalac.args.all}" + implicits="on" + diagrams="on" + groups="on" + rawOutput="${scaladoc.raw.output}" + noPrefixes="${scaladoc.no.prefixes}"> + <includes/> + </scaladoc> + </then><else> + <scaladoc + destdir="${build-docs.dir}/@{project}" + doctitle="@{title}" + docversion="${version.number}" + sourcepath="${src.dir}" + classpathref="pack.compiler.path" + srcdir="${src.dir}/@{dir}" + docRootContent="${src.dir}/@{project}/@{docroot}" + addparams="${scalac.args.all}" + implicits="on" + diagrams="on" + groups="on" + rawOutput="${scaladoc.raw.output}" + noPrefixes="${scaladoc.no.prefixes}"> + <includes/> + </scaladoc> + </else></if> + <stopwatch name="docs.@{project}.timer" action="total"/> + </do> + </staged-uptodate> + </sequential> + </macrodef> <!-- =========================================================================== -QUICK BUILD (QUICK) + LOCAL REFERENCE BUILD (LOCKER) ============================================================================ --> + <target name="locker.start" depends="asm.done, forkjoin.done, fjbg.done"> + <condition property="locker.locked"><available file="${build-locker.dir}/locker.locked"/></condition></target> - <target name="quick.start" depends="locker.done"/> - - <target name="quick.pre-lib" depends="quick.start"> - <uptodate property="quick.lib.available" targetfile="${build-quick.dir}/library.complete"> - <srcfiles dir="${src.dir}"> - <include name="library/**"/> - <include name="continuations/**"/> - <include name="swing/**"/> - <include name="actors/**"/> - </srcfiles> - </uptodate> - </target> + <target name="locker.lib" depends="locker.start" unless="locker.locked"> + <staged-build with="starr" stage="locker" project="library" srcpath="${src.dir}/library" includes="lib.includes"> + <pre><staged-javac stage="locker" project="library" args="-XDignore.symbol.file"/></pre></staged-build></target> + <!-- TODO: args="-XDignore.symbol.file" necessary?? --> - <target name="quick.lib" depends="quick.pre-lib" unless="quick.lib.available"> - <stopwatch name="quick.lib.timer"/> - <mkdir dir="${build-quick.dir}/classes/library"/> - <javac - srcdir="${src.dir}/library" - destdir="${build-quick.dir}/classes/library" - includes="**/*.java" - target="1.6" source="1.5"> - <compilerarg line="${javac.args} -XDignore.symbol.file"/> - <classpath> - <path refid="forkjoin.classpath"/> - <pathelement location="${build-quick.dir}/classes/library"/> - </classpath> - </javac> - <javac - srcdir="${src.dir}/actors" - destdir="${build-quick.dir}/classes/library" - includes="**/*.java" - target="1.6" source="1.5"> - <compilerarg line="${javac.args}"/> - <classpath> - <path refid="forkjoin.classpath"/> - <pathelement location="${build-quick.dir}/classes/library"/> - </classpath> - </javac> - <scalacfork - destdir="${build-quick.dir}/classes/library" - compilerpathref="locker.classpath" - srcpath="${src.dir}/library" - params="${scalac.args.quick}" - srcdir="${src.dir}/library" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="quick.compilation.path"/> - </scalacfork> - <scalacfork - destdir="${build-quick.dir}/classes/library" - compilerpathref="locker.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/actors" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="quick.compilation.path"/> - </scalacfork> - <propertyfile file="${build-quick.dir}/classes/library/library.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-quick.dir}/classes/library"> - <fileset dir="${src.dir}/library"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.css"/> - </fileset> - </copy> + <target name="locker.reflect" depends="locker.lib" unless="locker.locked"> <staged-build with="starr" stage="locker" project="reflect"/></target> + <target name="locker.comp" depends="locker.reflect" unless="locker.locked"> + <staged-build with="starr" stage="locker" project="compiler"> + <pre> + <staged-javac stage="locker" project="msil" destproject="compiler" excludes="**/tests/**"/> + <staged-scalac with="starr" stage="locker" project="msil" destproject="compiler"/> + </pre> + </staged-build> </target> - <target name="quick.swing" depends="quick.lib" if="has.java6" unless="quick.lib.available"> - <scalacfork - destdir="${build-quick.dir}/classes/library" - compilerpathref="locker.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/swing" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="quick.compilation.path"/> - </scalacfork> + <target name="locker.done" depends="locker.comp"> + <mkdir dir="${build-locker.dir}"/> + <touch file="${build-locker.dir}/locker.locked" verbose="no"/> </target> + <target name="locker.unlock"> <delete file="${build-locker.dir}/locker.locked"/> + <delete file="${build-locker.dir}/*.complete"/></target> - <target name="quick.lib.done" depends="quick.swing, quick.lib"> - <stopwatch name="quick.lib.timer" action="total"/> - <touch file="${build-quick.dir}/library.complete" verbose="no"/> - </target> +<!-- =========================================================================== + QUICK BUILD (QUICK) +============================================================================ --> + <target name="quick.start" depends="locker.done"/> - <target name="quick.pre-reflect" depends="quick.lib.done"> - <uptodate property="quick.reflect.available" targetfile="${build-quick.dir}/reflect.complete"> - <srcfiles dir="${src.dir}"> - <include name="reflect/**"/> - </srcfiles> - </uptodate> + <target name="quick.lib" depends="quick.start"> + <staged-build with="locker" stage="quick" project="library" srcpath="${src.dir}/library" includes="lib.rootdoc.includes"> + <pre> + <staged-javac stage="quick" project="library" args="-XDignore.symbol.file"/> <!-- TODO: args="-XDignore.symbol.file" necessary?? --> + <staged-javac stage="quick" project="actors" destproject="library"/> + </pre> + <post> + <staged-scalac with="locker" stage="quick" project="actors" destproject="library"/> + </post> + </staged-build> </target> - <target name="quick.reflect" depends="quick.pre-reflect" unless="quick.reflect.available"> - <stopwatch name="quick.reflect.timer"/> - <mkdir dir="${build-quick.dir}/classes/reflect"/> - <scalacfork - destdir="${build-quick.dir}/classes/reflect" - compilerpathref="locker.classpath" - params="${scalac.args.all}" - srcdir="${src.dir}/reflect" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <path refid="aux.libs"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <!-- TODO - needed? --> - <propertyfile file="${build-quick.dir}/classes/reflect/reflect.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-quick.dir}/classes/reflect"> - <fileset dir="${src.dir}/reflect"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.html"/> - <include name="**/*.css"/> - <include name="**/*.properties"/> - <include name="**/*.swf"/> - <include name="**/*.png"/> - <include name="**/*.gif"/> - </fileset> - </copy> - <touch file="${build-quick.dir}/reflect.complete" verbose="no"/> - <stopwatch name="quick.reflect.timer" action="total"/> - </target> + <target name="quick.reflect" depends="quick.lib"> <staged-build with="locker" stage="quick" project="reflect"/> </target> - <target name="quick.pre-comp" depends="quick.reflect"> - <uptodate property="quick.comp.available" targetfile="${build-quick.dir}/compiler.complete"> - <srcfiles dir="${src.dir}/compiler"/> - </uptodate> + <target name="quick.comp" depends="quick.reflect"> + <staged-build with="locker" stage="quick" project="compiler"> + <pre> + <staged-javac stage="quick" project="msil" destproject="compiler" excludes="**/tests/**"/> + <staged-scalac with="locker" stage="quick" project="msil" destproject="compiler"/> + </pre> + </staged-build> </target> - <target name="quick.comp" depends="quick.pre-comp" unless="quick.comp.available"> - <stopwatch name="quick.comp.timer"/> - <mkdir dir="${build-quick.dir}/classes/compiler"/> - <!-- Compile MSIL inside of quick.... --> - <javac - srcdir="${src.dir}/msil" - destdir="${build-quick.dir}/classes/compiler" - classpath="${build-quick.dir}/classes/compiler" - includes="**/*.java" - excludes="**/tests/**" - debug="true" - target="1.6" source="1.4"> - <compilerarg line="${javac.args}"/> - </javac> - <scalacfork - destdir="${build-quick.dir}/classes/compiler" - compilerpathref="locker.classpath" - params="${scalac.args.all}" - srcdir="${src.dir}/msil" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <path refid="fjbg.classpath"/> - <path refid="aux.libs"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <scalacfork - destdir="${build-quick.dir}/classes/compiler" - compilerpathref="locker.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/compiler" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <path refid="aux.libs"/> - <path refid="forkjoin.classpath"/> - <path refid="fjbg.classpath"/> - <path refid="asm.classpath"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <propertyfile file="${build-quick.dir}/classes/compiler/compiler.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-quick.dir}/classes/compiler"> - <fileset dir="${src.dir}/compiler"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.css"/> - <include name="**/*.html"/> - <include name="**/*.properties"/> - <include name="**/*.swf"/> - <include name="**/*.png"/> - <include name="**/*.gif"/> - <include name="**/*.txt"/> - </fileset> - </copy> - <touch file="${build-quick.dir}/compiler.complete" verbose="no"/> - <stopwatch name="quick.comp.timer" action="total"/> + <target name="quick.scalacheck" depends="quick.lib"> + <staged-build with="locker" stage="quick" project="scalacheck" args="-nowarn"/> </target> - <target name="quick.pre-plugins" depends="quick.comp"> - <uptodate property="quick.plugins.available" targetfile="${build-quick.dir}/plugins.complete"> - <srcfiles dir="${src.dir}/continuations"/> - </uptodate> + <target name="quick.scalap" depends="quick.comp"> + <staged-build with="locker" stage="quick" project="scalap"/> </target> - <target name="quick.plugins" depends="quick.pre-plugins" unless="quick.plugins.available"> - <stopwatch name="quick.plugins.timer"/> - <mkdir dir="${build-quick.dir}/classes/continuations-plugin"/> - <scalacfork - destdir="${build-quick.dir}/classes/continuations-plugin" - compilerpathref="quick.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/continuations/plugin" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <pathelement location="${build-quick.dir}/classes/continuations-plugin"/> - <path refid="forkjoin.classpath"/> - <path refid="fjbg.classpath"/> - <path refid="aux.libs"/> - </compilationpath> - </scalacfork> - <copy - file="${src.dir}/continuations/plugin/scalac-plugin.xml" - todir="${build-quick.dir}/classes/continuations-plugin"/> - <!-- not very nice to create jar here but needed to load plugin --> - <mkdir dir="${build-quick.dir}/misc/scala-devel/plugins"/> - <jar destfile="${build-quick.dir}/misc/scala-devel/plugins/continuations.jar"> - <fileset dir="${build-quick.dir}/classes/continuations-plugin"/> - </jar> - <!-- might split off library part into its own ant target --> - <scalacfork - destdir="${build-quick.dir}/classes/library" - compilerpathref="quick.classpath" - params="${scalac.args.quick} -Xplugin-require:continuations -P:continuations:enable" - srcdir="${src.dir}/continuations/library" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="quick.compilation.path"/> - <compilerarg value="-Xpluginsdir"/> - <compilerarg file="${build-quick.dir}/misc/scala-devel/plugins"/> - </scalacfork> - <touch file="${build-quick.dir}/plugins.complete" verbose="no"/> - <stopwatch name="quick.plugins.timer" action="total"/> + <target name="quick.partest" depends="quick.scalap, quick.comp, asm.done"> + <staged-build with="locker" stage="quick" project="partest" version="partest"> + <pre><staged-javac stage="quick" project="partest"/></pre> + </staged-build> </target> - <target name="quick.pre-scalacheck" depends="quick.plugins"> - <uptodate property="quick.scalacheck.available" targetfile="${build-quick.dir}/scalacheck.complete"> - <srcfiles dir="${src.dir}/scalacheck"/> - </uptodate> + <target name="quick.swing" depends="quick.lib" if="has.java6"> + <staged-build with="locker" stage="quick" project="swing"/> </target> - <target name="quick.scalacheck" depends="quick.pre-scalacheck" unless="quick.scalacheck.available"> - <stopwatch name="quick.scalacheck.timer"/> - <mkdir dir="${build-quick.dir}/classes/scalacheck"/> - <scalacfork - destdir="${build-quick.dir}/classes/scalacheck" - compilerpathref="quick.classpath" - params="${scalac.args.quick} -nowarn" - srcdir="${src.dir}/scalacheck" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/scalacheck"/> - </compilationpath> - </scalacfork> - <touch file="${build-quick.dir}/scalacheck.complete" verbose="no"/> - <stopwatch name="quick.scalacheck.timer" action="total"/> - </target> + <target name="quick.plugins" depends="quick.comp"> + <staged-uptodate stage="quick" project="plugins"> + <check><srcfiles dir="${src.dir}/continuations"/></check> + <do> + <stopwatch name="quick.plugins.timer"/> - <target name="quick.pre-scalap" depends="quick.scalacheck"> - <uptodate property="quick.scalap.available" targetfile="${build-quick.dir}/scalap.complete"> - <srcfiles dir="${src.dir}/scalap"/> - </uptodate> - </target> + <mkdir dir="${build-quick.dir}/classes/continuations-plugin"/> + <staged-scalac with="locker" stage="quick" project="plugins" srcdir="continuations/plugin" destproject="continuations-plugin"/> + <copy + file="${src.dir}/continuations/plugin/scalac-plugin.xml" + todir="${build-quick.dir}/classes/continuations-plugin"/> - <target name="quick.scalap" depends="quick.pre-scalap" unless="quick.scalap.available"> - <stopwatch name="quick.scalap.timer"/> - <mkdir dir="${build-quick.dir}/classes/scalap"/> - <scalacfork - destdir="${build-quick.dir}/classes/scalap" - compilerpathref="quick.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/scalap" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <pathelement location="${build-quick.dir}/classes/scalap"/> - <pathelement location="${build-quick.dir}/classes/partest"/> - <pathelement location="${ant.jar}"/> - <path refid="forkjoin.classpath"/> - </compilationpath> - </scalacfork> - <touch file="${build-quick.dir}/scalap.complete" verbose="no"/> - <stopwatch name="quick.scalap.timer" action="total"/> - </target> + <!-- not very nice to create jar here but needed to load plugin --> + <mkdir dir="${build-quick.dir}/misc/scala-devel/plugins"/> + <jar whenmanifestonly="fail" destfile="${build-quick.dir}/misc/scala-devel/plugins/continuations.jar" basedir="${build-quick.dir}/classes/continuations-plugin"/> - <target name="quick.pre-partest" depends="quick.scalap, asm.done"> - <uptodate property="quick.partest.available" targetfile="${build-quick.dir}/partest.complete"> - <srcfiles dir="${src.dir}/partest"/> - </uptodate> - </target> + <!-- might split off library part into its own ant target --> + <mkdir dir="${build-quick.dir}/classes/continuations-library"/> + <!-- have to compile with quick compiler here! --> + <staged-scalac with="quick" stage="quick" project="plugins" + srcdir="continuations/library" destproject="continuations-library" + args="-Xplugin-require:continuations -P:continuations:enable"> + <compilerarg value="-Xpluginsdir"/> + <compilerarg file="${build-quick.dir}/misc/scala-devel/plugins"/> + </staged-scalac> - <target name="quick.partest" depends="quick.pre-partest" unless="quick.partest.available"> - <stopwatch name="quick.partest.timer"/> - <mkdir dir="${build-quick.dir}/classes/partest"/> - <javac - srcdir="${src.dir}/partest" - destdir="${build-quick.dir}/classes/partest" - target="1.6" source="1.5"> - <classpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <pathelement location="${build-quick.dir}/classes/scalap"/> - <pathelement location="${build-quick.dir}/classes/partest"/> - <path refid="asm.classpath"/> - </classpath> - <include name="**/*.java"/> - <compilerarg line="${javac.args}"/> - </javac> - <scalacfork - destdir="${build-quick.dir}/classes/partest" - compilerpathref="quick.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/partest" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <pathelement location="${build-quick.dir}/classes/scalap"/> - <pathelement location="${build-quick.dir}/classes/partest"/> - <pathelement location="${ant.jar}"/> - <path refid="forkjoin.classpath"/> - <path refid="fjbg.classpath"/> - <path refid="asm.classpath"/> - <pathelement location="${scalacheck.jar}"/> - </compilationpath> - </scalacfork> - <propertyfile file="${build-quick.dir}/classes/partest/partest.properties"> - <entry key="version.number" value="${partest.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-quick.dir}/classes/partest"> - <fileset dir="${src.dir}/partest"> - <include name="**/*.xml"/> - </fileset> - </copy> - <touch file="${build-quick.dir}/partest.complete" verbose="no"/> - <stopwatch name="quick.partest.timer" action="total"/> + <stopwatch name="quick.plugins.timer" action="total"/> + </do> + </staged-uptodate> </target> - <target name="quick.pre-bin" depends="quick.partest"> - <condition property="quick.bin.available"> - <isset property="quick.comp.available"/> - </condition> + <target name="quick.bin" depends="init"> + <staged-bin stage="quick" classpathref="quick.bin.tool.path"/> </target> - <target name="quick.bin" depends="quick.pre-bin" unless="quick.bin.available"> - <path id="quick.bin.classpath"> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <pathelement location="${build-quick.dir}/classes/scalap"/> - <path refid="forkjoin.classpath"/> - <path refid="fjbg.classpath"/> - <path refid="aux.libs"/> - <path refid="asm.classpath"/> - <pathelement location="${jline.jar}"/> - </path> - <taskdef name="quick-bin" classname="scala.tools.ant.ScalaTool" classpathref="quick.bin.classpath"/> - <mkdir dir="${build-quick.dir}/bin"/> - <quick-bin - file="${build-quick.dir}/bin/scala" - class="scala.tools.nsc.MainGenericRunner" - javaFlags="${java.flags}" - classpathref="quick.bin.classpath"/> - <quick-bin - file="${build-quick.dir}/bin/scalac" - class="scala.tools.nsc.Main" - javaFlags="${java.flags}" - classpathref="quick.bin.classpath"/> - <quick-bin - file="${build-quick.dir}/bin/scaladoc" - class="scala.tools.nsc.ScalaDoc" - javaFlags="${java.flags}" - classpathref="quick.bin.classpath"/> - <quick-bin - file="${build-quick.dir}/bin/fsc" - class="scala.tools.nsc.CompileClient" - javaFlags="${java.flags}" - classpathref="quick.bin.classpath"/> - <quick-bin - file="${build-quick.dir}/bin/scalap" - class="scala.tools.scalap.Main" - javaFlags="${java.flags}" - classpathref="quick.bin.classpath"/> - <chmod perm="ugo+rx" file="${build-quick.dir}/bin/scala"/> - <chmod perm="ugo+rx" file="${build-quick.dir}/bin/scalac"/> - <chmod perm="ugo+rx" file="${build-quick.dir}/bin/scaladoc"/> - <chmod perm="ugo+rx" file="${build-quick.dir}/bin/fsc"/> - <chmod perm="ugo+rx" file="${build-quick.dir}/bin/scalap"/> - <touch file="${build-quick.dir}/bin.complete" verbose="no"/> - </target> - - <target name="quick.done" depends="quick.bin"> - <path id="quick.classpath"> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <path refid="asm.classpath"/> - <path refid="aux.libs"/> - </path> - </target> + <target name="quick.done" depends="quick.lib, quick.reflect, quick.comp, quick.scalacheck, quick.scalap, quick.swing, quick.plugins, quick.partest, quick.bin"/> + <target name="quick-opt" description="Optimized version of quick.done."> <optimized name="quick.done"/></target> - <target name="quick.clean" depends="libs.clean"> - <delete dir="${build-quick.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> <!-- =========================================================================== -PACKED QUICK BUILD (PACK) + PACKED QUICK BUILD (PACK) ============================================================================ --> - - <target name="pack.start" depends="quick.done"/> - - <target name="pack.pre-lib" depends="pack.start"> - <uptodate - property="pack.lib.available" - targetfile="${build-pack.dir}/lib/scala-library.jar" - srcfile="${build-quick.dir}/library.complete"/> + <target name="pack.lib" depends="quick.lib, quick.plugins, forkjoin.done"> + <staged-pack project="library"> + <!-- First copy maven dependencies --> + <copy todir="${build-pack.dir}/lib"> + <fileset refid="dependency.fileset" /> + <mapper type="flatten" /> + </copy> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/lib/scala-library.jar"> + <fileset dir="${build-quick.dir}/classes/library"> + <exclude name="scala/swing/**"/> + <exclude name="scala/actors/**"/> + </fileset> + <fileset dir="${build-quick.dir}/classes/continuations-library"/> + <fileset dir="${build-libs.dir}/classes/forkjoin"/> + </jar> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/lib/scala-actors.jar"> + <fileset dir="${build-quick.dir}/classes/library"> + <include name="scala/actors/**"/> + </fileset> + </jar> + </staged-pack> + </target> + + <target name="pack.swing" depends="quick.swing" if="has.java6"> + <staged-pack project="swing’"> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/lib/scala-swing.jar" basedir="${build-quick.dir}/classes/swing"/> + </staged-pack> + </target> + + <target name="pack.reflect" depends="quick.reflect"> + <staged-pack project="reflect’"> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/lib/scala-reflect.jar" basedir="${build-quick.dir}/classes/reflect"/> + </staged-pack> + </target> + + <target name="pack.comp" depends="quick.comp, asm.done"> + <staged-pack project="compiler"> + <mkdir dir="${build-pack.dir}/META-INF"/> + <copy file="META-INF/MANIFEST.MF" toDir="${build-pack.dir}/META-INF"/> + <manifest file="${build-pack.dir}/META-INF/MANIFEST.MF" mode="update"> + <attribute name="Bundle-Version" value="${version.number}"/> + <attribute name="Class-Path" value="scala-reflect.jar scala-library.jar"/> + </manifest> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/lib/scala-compiler.jar" manifest="${build-pack.dir}/META-INF/MANIFEST.MF"> + <service type="javax.script.ScriptEngineFactory" provider="scala.tools.nsc.interpreter.IMain$Factory"/> + <fileset dir="${build-quick.dir}/classes/compiler"/> + <fileset dir="${build-asm.dir}/classes"/> + <fileset dir="${build-libs.dir}/classes/fjbg"/> + </jar> + <copy file="${jline.jar}" toDir="${build-pack.dir}/lib"/> + <copy todir="${build-pack.dir}/lib"> + <fileset dir="${lib-extra.dir}"> + <include name="**/*.jar"/> + </fileset> + </copy> + </staged-pack> </target> - <target name="pack.lib" depends="pack.pre-lib" unless="pack.lib.available"> - <mkdir dir="${build-pack.dir}/lib"/> - <!-- First copy maven dependencies --> - <copy todir="${build-pack.dir}/lib"> - <fileset refid="dependency.fileset" /> - <mapper type="flatten" /> - </copy> - <jar destfile="${build-pack.dir}/lib/scala-library.jar"> - <fileset dir="${build-quick.dir}/classes/library"> - <exclude name="scala/swing/**"/> - <exclude name="scala/actors/**"/> - </fileset> - <fileset dir="${build-libs.dir}/classes/forkjoin"/> - </jar> - <jar destfile="${build-pack.dir}/lib/scala-actors.jar"> - <fileset dir="${build-quick.dir}/classes/library"> - <include name="scala/actors/**"/> - </fileset> - </jar> + <target name="pack.plugins" depends="quick.plugins"> + <staged-pack project="plugins" targetdir="misc/scala-devel/plugins" targetjar="continuations.jar"> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/misc/scala-devel/plugins/continuations.jar" basedir="${build-quick.dir}/classes/continuations-plugin"/> + </staged-pack> </target> - <target name="pack.swing" depends="pack.lib" if="has.java6"> - <jar destfile="${build-pack.dir}/lib/scala-swing.jar"> - <fileset dir="${build-quick.dir}/classes/library"> - <include name="scala/swing/**"/> - </fileset> - </jar> + <target name="pack.scalacheck" depends="quick.scalacheck"> + <uptodate property="pack.scalacheck.available" + targetfile="${build-pack.dir}/lib/scalacheck.jar"> + <srcfiles dir="${build-quick.dir}/classes/scalacheck"/></uptodate> + <if><not><isset property="pack.scalacheck.available"/></not><then> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/lib/scalacheck.jar" basedir="${build-quick.dir}/classes/scalacheck"/> + </then></if> </target> - <target name="pack.pre-reflect" depends="pack.lib, pack.swing"> - <uptodate - property="pack.reflect.available" - targetfile="${build-pack.dir}/lib/scala-reflect.jar" - srcfile="${build-quick.dir}/reflect.complete"/> + <target name="pack.partest" depends="quick.partest"> + <staged-pack project="partest"> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/lib/scala-partest.jar"> + <fileset dir="${build-quick.dir}/classes/partest"> + <exclude name="scala/tools/partest/javaagent/**"/> + </fileset> + </jar> + <jar whenmanifestonly="fail" destfile = "${build-pack.dir}/lib/scala-partest-javaagent.jar" + manifest = "${src.dir}/partest/scala/tools/partest/javaagent/MANIFEST.MF"> + <fileset dir = "${build-quick.dir}/classes/partest"> + <include name = "scala/tools/partest/javaagent/**"/> + </fileset> + </jar> + </staged-pack> </target> - <target name="pack.reflect" depends="pack.pre-reflect" unless="pack.reflect.available"> - <mkdir dir="${build-pack.dir}/lib"/> - <jar destfile="${build-pack.dir}/lib/scala-reflect.jar"> - <fileset dir="${build-quick.dir}/classes/reflect" /> - </jar> + <target name="pack.scalap" depends="quick.scalap"> + <staged-pack project="plugins" targetjar="scalap.jar"> + <jar whenmanifestonly="fail" destfile="${build-pack.dir}/lib/scalap.jar"> + <fileset dir="${build-quick.dir}/classes/scalap"/> + <fileset file="${src.dir}/scalap/decoder.properties"/> + </jar> + </staged-pack> </target> - <target name="pack.pre-comp" depends="pack.reflect"> - <uptodate - property="pack.comp.available" - targetfile="${build-pack.dir}/lib/scala-compiler.jar" - srcfile="${build-quick.dir}/compiler.complete"/> + <target name="pack.bin" depends="pack.comp, pack.lib, pack.partest, pack.plugins, pack.reflect, pack.scalacheck, pack.scalap, pack.swing"> + <staged-bin stage="pack"/> </target> - <target name="pack.comp" depends="pack.pre-comp" unless="pack.comp.available"> - <mkdir dir="${build-pack.dir}/META-INF"/> - <copy file="META-INF/MANIFEST.MF" toDir="${build-pack.dir}/META-INF"/> - <manifest file="${build-pack.dir}/META-INF/MANIFEST.MF" mode="update"> - <attribute name="Bundle-Version" value="${version.number}"/> - </manifest> - <mkdir dir="${build-pack.dir}/lib"/> - <jar destfile="${build-pack.dir}/lib/scala-compiler.jar" manifest="${build-pack.dir}/META-INF/MANIFEST.MF"> - <fileset dir="${build-quick.dir}/classes/compiler"/> - <fileset dir="${build-asm.dir}/classes"/> - <fileset dir="${build-libs.dir}/classes/fjbg"/> - </jar> - <copy file="${jline.jar}" toDir="${build-pack.dir}/lib"/> - <copy todir="${build-pack.dir}/lib"> - <fileset dir="${lib-extra.dir}"> - <include name="**/*.jar"/> - </fileset> - </copy> + <target name="pack.done" depends="pack.bin"> + <taskdef resource="scala/tools/ant/antlib.xml" classpathref="pack.compiler.path"/> + <taskdef resource="scala/tools/partest/antlib.xml" classpathref="pack.compiler.path"/> </target> - <target name="pack.pre-plugins" depends="pack.comp"> - <uptodate - property="pack.plugins.available" - targetfile="${build-pack.dir}/misc/scala-devel/plugins/continuations.jar" - srcfile="${build-quick.dir}/plugins.complete"/> - </target> - <target name="pack.plugins" depends="pack.pre-plugins" unless="pack.plugins.available"> - <mkdir dir="${build-pack.dir}/misc/scala-devel/plugins"/> - <jar destfile="${build-pack.dir}/misc/scala-devel/plugins/continuations.jar"> - <fileset dir="${build-quick.dir}/classes/continuations-plugin"/> - </jar> - </target> - - <target name="pack.scalacheck" depends="pack.plugins"> - <jar destfile="${build-pack.dir}/lib/scalacheck.jar"> - <fileset dir="${build-quick.dir}/classes/scalacheck"/> - </jar> - </target> +<!-- =========================================================================== + BOOTSTRAPPING BUILD (STRAP) +============================================================================ --> + <target name="strap.lib" depends="quick.done"> + <staged-build with="quick" stage="strap" project="library" srcpath="${src.dir}/library" includes="lib.rootdoc.includes"> + <pre> + <staged-javac stage="strap" project="library" args="-XDignore.symbol.file"/> <!-- TODO: args="-XDignore.symbol.file" necessary?? --> + <staged-javac stage="strap" project="actors" destproject="library"/> + </pre> + <post> + <staged-scalac with="quick" stage="strap" project="actors" destproject="library"/> + </post> + </staged-build> + </target> + + <target name="strap.reflect" depends="strap.lib"> <staged-build with="pack" stage="strap" project="reflect"/> </target> + <target name="strap.comp" depends="strap.reflect"> + <staged-build with="pack" stage="strap" project="compiler"> + <pre> + <staged-javac stage="strap" project="msil" destproject="compiler" excludes="**/tests/**"/> + <staged-scalac with="quick" stage="strap" project="msil" destproject="compiler"/> + </pre> + </staged-build> + </target> + <target name="strap.done" depends="strap.comp"/> + <target name="strap-opt" description="Optimized version of strap.done."> <optimized name="strap.done"/></target> - <target name="pack.pre-partest" depends="pack.scalacheck"> - <uptodate - property="pack.partest.available" - targetfile="${build-pack.dir}/lib/scala-partest.jar" - srcfile="${build-quick.dir}/partest.complete"/> - </target> - <target name="pack.partest" depends="pack.pre-partest" unless="pack.partest.available"> - <mkdir dir="${build-pack.dir}/lib"/> - <jar destfile="${build-pack.dir}/lib/scala-partest.jar"> - <fileset dir="${build-quick.dir}/classes/partest"> - <exclude name="scala/tools/partest/javaagent/**"/> - </fileset> - </jar> - <jar destfile="${build-pack.dir}/lib/scala-partest-javaagent.jar" manifest="${src.dir}/partest/scala/tools/partest/javaagent/MANIFEST.MF"> - <fileset dir="${build-quick.dir}/classes/partest"> - <include name="scala/tools/partest/javaagent/**"/> - </fileset> +<!-- =========================================================================== + PACKED LOCKER BUILD (PALO) +============================================================================ --> + <target name="palo.done" depends="locker.done"> + <mkdir dir="${build-palo.dir}/lib"/> + <jar whenmanifestonly="fail" destfile="${build-palo.dir}/lib/scala-library.jar"> + <fileset dir="${build-locker.dir}/classes/library"/> + <fileset dir="${build-libs.dir}/classes/forkjoin"/> </jar> - </target> - - <target name="pack.pre-scalap" depends="pack.partest"> - <uptodate - property="pack.scalap.available" - targetfile="${build-pack.dir}/lib/scalap.jar" - srcfile="${build-quick.dir}/scalap.complete"/> - </target> - - <target name="pack.scalap" depends="pack.pre-scalap" unless="pack.scalap.available"> - <mkdir dir="${build-pack.dir}/lib"/> - <jar destfile="${build-pack.dir}/lib/scalap.jar"> - <fileset dir="${build-quick.dir}/classes/scalap"/> - <fileset file="${src.dir}/scalap/decoder.properties"/> + <jar whenmanifestonly="fail" destfile="${build-palo.dir}/lib/scala-reflect.jar" manifest="${basedir}/META-INF/MANIFEST.MF" + basedir="${build-locker.dir}/classes/reflect"/> + <jar whenmanifestonly="fail" destfile="${build-palo.dir}/lib/scala-compiler.jar" manifest="${basedir}/META-INF/MANIFEST.MF"> + <fileset dir="${build-locker.dir}/classes/compiler"/> + <fileset dir="${build-asm.dir}/classes/"/> + <fileset dir="${build-libs.dir}/classes/fjbg"/> </jar> + <copy file="${jline.jar}" toDir="${build-palo.dir}/lib"/> </target> - <target name="pack.pre-bin" depends="pack.scalap"> - <uptodate - property="pack.bin.available" - srcfile="${build-pack.dir}/lib/scala-compiler.jar" - targetfile="${build-pack.dir}/bin.complete"/> - </target> - - <target name="pack.bin" depends="pack.pre-bin" unless="pack.bin.available"> - <taskdef name="pack-bin" classname="scala.tools.ant.ScalaTool"> - <classpath> - <pathelement location="${build-pack.dir}/lib/scala-library.jar"/> - <pathelement location="${build-pack.dir}/lib/scala-reflect.jar"/> - <pathelement location="${build-pack.dir}/lib/scala-compiler.jar"/> - <pathelement location="${build-pack.dir}/lib/jline.jar"/> - </classpath> - </taskdef> - <mkdir dir="${build-pack.dir}/bin"/> - <pack-bin - file="${build-pack.dir}/bin/scala" - class="scala.tools.nsc.MainGenericRunner" - javaFlags="${java.flags}"/> - <pack-bin - file="${build-pack.dir}/bin/scalac" - class="scala.tools.nsc.Main" - javaFlags="${java.flags}"/> - <pack-bin - file="${build-pack.dir}/bin/scaladoc" - class="scala.tools.nsc.ScalaDoc" - javaFlags="${java.flags}"/> - <pack-bin - file="${build-pack.dir}/bin/fsc" - class="scala.tools.nsc.CompileClient" - javaFlags="${java.flags}"/> - <pack-bin - file="${build-pack.dir}/bin/scalap" - class="scala.tools.scalap.Main" - javaFlags="${java.flags}"/> - <chmod perm="ugo+rx" file="${build-pack.dir}/bin/scala"/> - <chmod perm="ugo+rx" file="${build-pack.dir}/bin/scalac"/> - <chmod perm="ugo+rx" file="${build-pack.dir}/bin/scaladoc"/> - <chmod perm="ugo+rx" file="${build-pack.dir}/bin/fsc"/> - <chmod perm="ugo+rx" file="${build-pack.dir}/bin/scalap"/> - <touch file="${build-pack.dir}/bin.complete" verbose="no"/> - </target> - - <target name="pack.done" depends="pack.bin"> - <path id="pack.classpath"> - <pathelement location="${build-pack.dir}/lib/scala-library.jar"/> - <pathelement location="${build-pack.dir}/lib/scala-reflect.jar"/> - <pathelement location="${build-pack.dir}/lib/scala-compiler.jar"/> - <pathelement location="${build-pack.dir}/lib/scala-partest.jar"/> - <pathelement location="${build-pack.dir}/lib/scalap.jar"/> - <pathelement location="${build-pack.dir}/lib/scala-actors.jar"/> - <pathelement location="${ant.jar}"/> - <pathelement location="${jline.jar}"/> - <path refid="lib.extra"/> - </path> - <taskdef resource="scala/tools/ant/antlib.xml" classpathref="pack.classpath"/> - <taskdef resource="scala/tools/partest/antlib.xml" classpathref="pack.classpath"/> - </target> + <target name="palo.bin" depends="palo.done"> <staged-bin stage="palo"/></target> - <target name="pack.clean" depends="strap.clean"> - <delete dir="${build-pack.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> <!-- =========================================================================== -OSGi Artifacts + OSGi Artifacts ============================================================================ --> - - <target name="osgi.init" depends="pack.done"> + <target name="osgi.done" depends="pack.done"> <mkdir dir="${build-osgi.dir}"/> - <property name="osgi.test.src" value="${partest.dir}/osgi/src"/> - <property name="osgi.test.classes" value="${build-osgi.dir}/classes"/> - <!-- simplify fixing pom versions --> <macrodef name="make-bundle"> <attribute name="name" /> @@ -1710,888 +1271,137 @@ OSGi Artifacts output="${build-osgi.dir}"/> </sequential> </macrodef> + <uptodate property="osgi.bundles.available" targetfile="${build-osgi.dir}/bundles.complete"> <srcfiles dir="${basedir}"> <include name="build.xml"/> <include name="src/build/bnd/*.bnd"/> </srcfiles> </uptodate> - </target> - <target name="osgi.bundles" depends="osgi.init" unless="osgi.bundles.available"> - <stopwatch name="osgi.bundle.timer"/> - <make-bundle name="scala-library" version="${osgi.version.number}" /> - <make-bundle name="scala-actors" version="${osgi.version.number}" /> - <make-bundle name="scala-reflect" version="${osgi.version.number}" /> - <make-bundle name="scala-compiler" version="${osgi.version.number}" /> - <make-plugin-bundle name="continuations" version="${osgi.version.number}" /> - <touch file="${build-osgi.dir}/bundles.complete" verbose="no"/> - <stopwatch name="osgi.bundle.timer" action="total"/> + <if><not><isset property="osgi.bundles.available"/></not><then> + <stopwatch name="osgi.bundle.timer"/> + <make-bundle name="scala-library" version="${osgi.version.number}" /> + <make-bundle name="scala-actors" version="${osgi.version.number}" /> + <make-bundle name="scala-reflect" version="${osgi.version.number}" /> + <make-bundle name="scala-compiler" version="${osgi.version.number}" /> + <make-plugin-bundle name="continuations" version="${osgi.version.number}" /> + <touch file="${build-osgi.dir}/bundles.complete" verbose="no"/> + + <if><isset property="has.java6"/><then> + <make-bundle name="scala-swing" version="${osgi.version.number}"/></then> + </if> + <stopwatch name="osgi.bundle.timer" action="total"/></then> + </if> </target> - <target name="osgi.bundles.swing" depends="osgi.init" if="has.java6" unless="osgi.bundles.available"> - <!-- TODO - only if JDK6 --> - <make-bundle name="scala-swing" version="${osgi.version.number}"/> - </target> - <target name="osgi.done" depends="osgi.bundles, osgi.bundles.swing"/> +<!-- =========================================================================== + TEST SUITE +============================================================================ --> + <!-- bootstrapping stability: compare {quick,strap}/(lib|reflect|comp) --> + <target name="test.stability" depends="quick.lib, quick.reflect, quick.comp, strap.lib, strap.reflect, strap.comp"> + <exec osfamily="unix" vmlauncher="false" executable="${basedir}/tools/stability-test.sh" failonerror="true" /> + <!-- I think doing it this way means it will auto-pass on windows... that's the idea. If not, something like this. --> + <!-- <exec osfamily="windows" executable="foo" failonerror="false" failifexecutionfails="false" /> --> + </target> - <target name="osgi.test.init" depends="osgi.done"> - <path id="osgi.bundle.classpath"> - <pathelement location="${build-osgi.dir}/org.scala-lang.scala-library.jar"/> - <pathelement location="${build-osgi.dir}/org.scala-lang.scala-reflect.jar"/> - <pathelement location="${build-osgi.dir}/org.scala-lang.scala-compiler.jar"/> - <pathelement location="${build-osgi.dir}/org.scala-lang.scala-actors.jar"/> - </path> + <target name="test.stability-opt" description="Optimized version of test.stability."> <optimized name="test.stability"/></target> - <uptodate property="osgi.test.available" targetfile="${build-osgi.dir}/test-compile.complete"> - <srcfiles dir="${osgi.test.src}"> + <target name="test.osgi.init" depends="osgi.done"> + <uptodate property="test.osgi.available" targetfile="${build-osgi.dir}/test-compile.complete"> + <srcfiles dir="${test.osgi.src}"> <include name="**/*.scala"/> </srcfiles> </uptodate> </target> - <target name="osgi.test.comp" depends="osgi.test.init, quick.done" unless="osgi.test.available"> - <stopwatch name="osgi.test.comp.timer"/> - <mkdir dir="${osgi.test.classes}"/> + <target name="test.osgi.comp" depends="test.osgi.init, quick.done" unless="test.osgi.available"> + <stopwatch name="test.osgi.compiler.timer"/> + <mkdir dir="${test.osgi.classes}"/> <scalacfork - destdir="${osgi.test.classes}" - compilerpathref="quick.classpath" + destdir="${test.osgi.classes}" + compilerpathref="quick.compiler.path" params="${scalac.args.quick}" - srcdir="${osgi.test.src}" + srcdir="${test.osgi.src}" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${osgi.test.classes}"/> - <path refid="osgi.bundle.classpath"/> - <path refid="pax.exam.classpath"/> - <path refid="forkjoin.classpath"/> - </compilationpath> + <compilationpath refid="test.osgi.compiler.build.path"/> </scalacfork> <touch file="${build-osgi.dir}/test-compile.complete" verbose="no"/> - <stopwatch name="osgi.test.comp.timer" action="total"/> + <stopwatch name="test.osgi.compiler.timer" action="total"/> </target> - <target name="osgi.test" depends="osgi.test.comp"> - <stopwatch name="osgi.test.timer"/> - <mkdir dir="${osgi.test.classes}"/> + <target name="test.osgi" depends="test.osgi.comp"> + <stopwatch name="test.osgi.timer"/> + <mkdir dir="${test.osgi.classes}"/> <junit fork="yes" haltonfailure="yes"> - <classpath> - <pathelement location="${osgi.test.classes}"/> - <path refid="osgi.bundle.classpath"/> - <path refid="pax.exam.classpath"/> - <path refid="forkjoin.classpath"/> - </classpath> + <classpath refid="test.osgi.compiler.build.path"/> <batchtest fork="yes" todir="${build-osgi.dir}"> - <fileset dir="${osgi.test.classes}"> + <fileset dir="${test.osgi.classes}"> <include name="**/*Test.class"/> </fileset> </batchtest> - <formatter type="brief" usefile="false" /> + <formatter type="brief" /> <!-- silenced by having it use a file; I tried for an hour to use other formatters but classpath issues drove me to this usefile="false" --> </junit> - <stopwatch name="osgi.test.timer" action="total"/> + <stopwatch name="test.osgi.timer" action="total"/> </target> - <target name="osgi.clean"> - <delete dir="${build-osgi.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> <!-- =========================================================================== -BOOTSTRAPPING BUILD (STRAP) + SBT Compiler Interface ============================================================================ --> - - <target name="strap.start" depends="pack.done"/> - - <target name="strap.pre-lib" depends="strap.start"> - <uptodate property="strap.lib.available" targetfile="${build-strap.dir}/library.complete"> - <srcfiles dir="${src.dir}"> - <include name="library/**"/> - <include name="swing/**"/> - <include name="actors/**"/> - </srcfiles> - </uptodate> - </target> - - <target name="strap.lib" depends="strap.pre-lib" unless="strap.lib.available"> - <stopwatch name="strap.lib.timer"/> - <mkdir dir="${build-strap.dir}/classes/library"/> - <javac - srcdir="${src.dir}/library" - destdir="${build-strap.dir}/classes/library" - includes="**/*.java" - target="1.6" source="1.5"> - <compilerarg line="${javac.args} -XDignore.symbol.file"/> - <classpath> - <path refid="forkjoin.classpath"/> - <pathelement location="${build-strap.dir}/classes/library"/> - </classpath> - </javac> - <javac - srcdir="${src.dir}/actors" - destdir="${build-strap.dir}/classes/library" - includes="**/*.java" - target="1.6" source="1.5"> - <compilerarg line="${javac.args}"/> - <classpath> - <path refid="forkjoin.classpath"/> - <pathelement location="${build-strap.dir}/classes/library"/> - </classpath> - </javac> - <scalacfork - destdir="${build-strap.dir}/classes/library" - compilerpathref="pack.classpath" - srcpath="${src.dir}/library" - params="${scalac.args.quick}" - srcdir="${src.dir}/library" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="strap.compilation.path"/> - </scalacfork> - <scalacfork - destdir="${build-strap.dir}/classes/library" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/actors" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="strap.compilation.path"/> - </scalacfork> - <propertyfile file="${build-strap.dir}/classes/library/library.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-strap.dir}/classes/library"> - <fileset dir="${src.dir}/library"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.css"/> - </fileset> - </copy> - </target> - - <target name="strap.swing" if="has.java6" unless="strap.lib.available" depends="strap.lib"> - <scalacfork - destdir="${build-strap.dir}/classes/library" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/swing" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="strap.compilation.path"/> - </scalacfork> - </target> - - <target name="strap.lib.done" depends="strap.swing, strap.lib"> - <touch file="${build-strap.dir}/library.complete" verbose="no"/> - <stopwatch name="strap.lib.timer" action="total"/> - </target> - - <target name="strap.pre-reflect" depends="strap.lib.done"> - <uptodate property="strap.reflect.available" targetfile="${build-strap.dir}/reflect.complete"> - <srcfiles dir="${src.dir}/reflect"/> - </uptodate> - </target> - - <target name="strap.reflect" depends="strap.pre-reflect" unless="strap.reflect.available"> - <stopwatch name="strap.reflect.timer"/> - <mkdir dir="${build-strap.dir}/classes/reflect"/> - <scalacfork - destdir="${build-strap.dir}/classes/reflect" - compilerpathref="pack.classpath" - params="${scalac.args.all}" - srcdir="${src.dir}/reflect" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <path refid="forkjoin.classpath"/> - <path refid="aux.libs"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <propertyfile file="${build-strap.dir}/classes/reflect/reflect.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-strap.dir}/classes/reflect"> - <fileset dir="${src.dir}/reflect"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.css"/> - <include name="**/*.html"/> - <include name="**/*.properties"/> - <include name="**/*.swf"/> - <include name="**/*.png"/> - <include name="**/*.gif"/> - <include name="**/*.txt"/> - </fileset> - </copy> - <touch file="${build-strap.dir}/reflect.complete" verbose="no"/> - <stopwatch name="strap.comp.timer" action="total"/> - </target> - - <target name="strap.pre-comp" depends="strap.reflect"> - <uptodate property="strap.comp.available" targetfile="${build-strap.dir}/compiler.complete"> - <srcfiles dir="${src.dir}/compiler"/> - </uptodate> - </target> - - <target name="strap.comp" depends="strap.pre-comp" unless="strap.comp.available"> - <stopwatch name="strap.comp.timer"/> - <mkdir dir="${build-strap.dir}/classes/compiler"/> - <!-- Compile MSIL inside of strap.... --> - <javac - srcdir="${src.dir}/msil" - destdir="${build-strap.dir}/classes/compiler" - classpath="${build-strap.dir}/classes/compiler" - includes="**/*.java" - excludes="**/tests/**" - debug="true" - target="1.6" source="1.4"> - <compilerarg line="${javac.args}"/> - </javac> - <scalacfork - destdir="${build-strap.dir}/classes/compiler" - compilerpathref="pack.classpath" - params="${scalac.args.all}" - srcdir="${src.dir}/msil" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <path refid="fjbg.classpath"/> - <path refid="aux.libs"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <scalacfork - destdir="${build-strap.dir}/classes/compiler" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/compiler" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <path refid="aux.libs"/> - <path refid="forkjoin.classpath"/> - <path refid="fjbg.classpath"/> - <path refid="asm.classpath"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> - <propertyfile file="${build-strap.dir}/classes/compiler/compiler.properties"> - <entry key="version.number" value="${version.number}"/> - <entry key="maven.version.number" value="${maven.version.number}"/> - <entry key="osgi.version.number" value="${osgi.version.number}"/> - <entry key="copyright.string" value="${copyright.string}"/> - </propertyfile> - <copy todir="${build-strap.dir}/classes/compiler"> - <fileset dir="${src.dir}/compiler"> - <include name="**/*.tmpl"/> - <include name="**/*.xml"/> - <include name="**/*.js"/> - <include name="**/*.css"/> - <include name="**/*.html"/> - <include name="**/*.properties"/> - <include name="**/*.swf"/> - <include name="**/*.png"/> - <include name="**/*.gif"/> - <include name="**/*.txt"/> - </fileset> - </copy> - <touch file="${build-strap.dir}/compiler.complete" verbose="no"/> - <stopwatch name="strap.comp.timer" action="total"/> - </target> - - <target name="strap.pre-plugins" depends="strap.comp"> - <uptodate property="strap.plugins.available" targetfile="${build-strap.dir}/plugins.complete"> - <srcfiles dir="${src.dir}/continuations"/> - </uptodate> - </target> - - <target name="strap.plugins" depends="strap.pre-plugins" unless="strap.plugins.available"> - <stopwatch name="strap.plugins.timer"/> - <mkdir dir="${build-strap.dir}/classes/continuations-plugin"/> - <scalacfork - destdir="${build-strap.dir}/classes/continuations-plugin" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/continuations/plugin" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <pathelement location="${build-strap.dir}/classes/continuations-plugin"/> - <path refid="forkjoin.classpath"/> - <path refid="fjbg.classpath"/> - <path refid="aux.libs"/> - </compilationpath> - </scalacfork> - <copy - file="${src.dir}/continuations/plugin/scalac-plugin.xml" - todir="${build-strap.dir}/classes/continuations-plugin"/> - <!-- not very nice to create jar here but needed to load plugin --> - <mkdir dir="${build-strap.dir}/misc/scala-devel/plugins"/> - <jar destfile="${build-strap.dir}/misc/scala-devel/plugins/continuations.jar"> - <fileset dir="${build-strap.dir}/classes/continuations-plugin"/> - </jar> - <!-- might split off library part into its own ant target --> - <scalacfork - destdir="${build-strap.dir}/classes/library" - compilerpathref="pack.classpath" - params="${scalac.args.quick} -Xplugin-require:continuations -P:continuations:enable" - srcdir="${src.dir}/continuations/library" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="strap.compilation.path"/> - <compilerarg value="-Xpluginsdir"/> - <compilerarg file="${build-strap.dir}/misc/scala-devel/plugins"/> - </scalacfork> - <touch file="${build-strap.dir}/plugins.complete" verbose="no"/> - <stopwatch name="strap.plugins.timer" action="total"/> - </target> - - <target name="strap.scalacheck" depends="strap.plugins"> - <mkdir dir="${build-strap.dir}/classes/scalacheck"/> - <scalacfork - destdir="${build-strap.dir}/classes/scalacheck" - compilerpathref="pack.classpath" - params="${scalac.args.quick} -nowarn" - srcdir="${src.dir}/scalacheck" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - </compilationpath> - </scalacfork> - </target> - - <target name="strap.pre-scalap" depends="strap.scalacheck"> - <uptodate property="strap.scalap.available" targetfile="${build-strap.dir}/scalap.complete"> - <srcfiles dir="${src.dir}/scalap"/> - </uptodate> - </target> - - <target name="strap.scalap" depends="strap.pre-scalap" unless="strap.scalap.available"> - <stopwatch name="strap.scalap.timer"/> - <mkdir dir="${build-strap.dir}/classes/scalap"/> - <scalacfork - destdir="${build-strap.dir}/classes/scalap" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/scalap" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <pathelement location="${build-strap.dir}/classes/scalap"/> - <pathelement location="${build-strap.dir}/classes/partest"/> - <pathelement location="${ant.jar}"/> - <path refid="forkjoin.classpath"/> - </compilationpath> - </scalacfork> - <touch file="${build-strap.dir}/scalap.complete" verbose="no"/> - <stopwatch name="strap.scalap.timer" action="total"/> - </target> - - <target name="strap.pre-partest" depends="strap.scalap, asm.done"> - <uptodate property="strap.partest.available" targetfile="${build-strap.dir}/partest.complete"> - <srcfiles dir="${src.dir}/partest"/> - </uptodate> - </target> - - <target name="strap.partest" depends="strap.pre-partest" unless="strap.partest.available"> - <stopwatch name="strap.partest.timer"/> - <mkdir dir="${build-strap.dir}/classes/partest"/> - <javac - srcdir="${src.dir}/partest" - destdir="${build-strap.dir}/classes/partest" - target="1.6" source="1.5"> - <classpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <pathelement location="${build-strap.dir}/classes/scalap"/> - <pathelement location="${build-strap.dir}/classes/partest"/> - <path refid="asm.classpath"/> - </classpath> - <include name="**/*.java"/> - <compilerarg line="${javac.args}"/> - </javac> - <scalacfork - destdir="${build-strap.dir}/classes/partest" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/partest" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <pathelement location="${build-strap.dir}/classes/scalap"/> - <pathelement location="${build-strap.dir}/classes/partest"/> - <pathelement location="${ant.jar}"/> - <path refid="forkjoin.classpath"/> - <path refid="asm.classpath"/> - <pathelement location="${scalacheck.jar}"/> - </compilationpath> - </scalacfork> - <copy todir="${build-strap.dir}/classes/partest"> - <fileset dir="${src.dir}/partest"> - <include name="**/*.xml"/> - </fileset> - </copy> - <touch file="${build-strap.dir}/partest.complete" verbose="no"/> - <stopwatch name="strap.partest.timer" action="total"/> - </target> - - <target name="strap.done" depends="strap.partest"/> - - <target name="strap.clean"> - <delete dir="${build-strap.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> - -<!-- =========================================================================== -LIBRARIES (Forkjoin, FJBG, ASM) -============================================================================ --> - - - <target name="libs.clean" depends="pack.clean, asm.clean"> - <delete dir="${build-libs.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> - -<!-- =========================================================================== -SBT Compiler Interface -============================================================================ --> - - <target name="sbt.start" depends="init"> - <!-- TODO - Put this in init? Allow this to be overriden simply --> - <property name="sbt.latest.version" value="0.12.0"/> - - - <property name="sbt.src.dir" value="${build-sbt.dir}/${sbt.latest.version}/src"/> - <property name="sbt.lib.dir" value="${build-sbt.dir}/${sbt.latest.version}/lib"/> - - - - <property name="sbt.interface.jar" value="${sbt.lib.dir}/interface.jar"/> - <property name="sbt.interface.url" value="http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/interface/${sbt.latest.version}/jars/interface.jar"/> - <property name="sbt.interface.src.jar" value="${sbt.src.dir}/compiler-interface-src.jar"/> - <property name="sbt.interface.src.url" value="http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/compiler-interface/${sbt.latest.version}/jars/compiler-interface-src.jar"/> - - <!-- Ensure directories exist --> - <mkdir dir="${sbt.src.dir}"/> - <mkdir dir="${sbt.lib.dir}"/> - - <condition property="sbt.available"> - <and> + <target name="test.sbt" depends="quick.done"> + <if><not><and> <available file="${sbt.interface.jar}"/> - <available file="${sbt.interface.src.jar}"/> - </and> - </condition> + <available file="${sbt.interface.src.jar}"/></and></not> + <then> + <!-- Ensure directories exist --> + <mkdir dir="${sbt.src.dir}"/> + <mkdir dir="${sbt.lib.dir}"/> - </target> + <get src="${sbt.interface.url}" dest="${sbt.interface.jar}"/> + <get src="${sbt.interface.src.url}" dest="${sbt.interface.src.jar}"/> - <target name="sbt.libs" depends="sbt.start" unless="sbt.available"> - <get src="${sbt.interface.url}" dest="${sbt.interface.jar}"/> - <get src="${sbt.interface.src.url}" dest="${sbt.interface.src.jar}"/> - <!-- Explode sources --> - <unzip src="${sbt.interface.src.jar}" dest="${sbt.src.dir}"/> - </target> + <!-- Explode sources --> + <unzip src="${sbt.interface.src.jar}" dest="${sbt.src.dir}"/> + </then></if> - <target name="sbt.compile" depends="sbt.libs,quick.done"> <stopwatch name="quick.sbt-interface.timer"/> <mkdir dir="${build-sbt.dir}/classes"/> <scalacfork destdir="${build-sbt.dir}/classes" - compilerpathref="quick.classpath" + compilerpathref="quick.compiler.path" params="${scalac.args.quick}" srcdir="${sbt.src.dir}" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - <pathelement location="${build-quick.dir}/classes/reflect"/> - <pathelement location="${build-quick.dir}/classes/compiler"/> - <pathelement location="${sbt.interface.jar}"/> - <path refid="forkjoin.classpath"/> - </compilationpath> + <compilationpath refid="sbt.compile.build.path"/> </scalacfork> <touch file="${build-sbt.dir}/sbt-interface.complete" verbose="no"/> <stopwatch name="quick.sbt-interface.timer" action="total"/> </target> - <target name="sbt.done" depends="sbt.compile"> - </target> - - <target name="sbt.clean" depends="init"> - <delete dir="${build-sbt.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> - -<!-- =========================================================================== -DOCUMENTATION -============================================================================ --> - - <target name="docs.start" depends="pack.done"> - <macrodef name="doc-uptodate-check"> - <attribute name="name" /> - <attribute name="srcdir" /> - <element name="source-includes" optional="yes" /> - <sequential> - <uptodate property="docs.@{name}.available" targetfile="${build-docs.dir}/@{name}.complete"> - <srcfiles dir="@{srcdir}"> - <source-includes/> - </srcfiles> - </uptodate> - </sequential> - </macrodef> - - <!-- Set the github commit scaladoc sources point to --> - <!-- For releases, look for the tag with the same name as the maven version --> - <condition property="scaladoc.git.commit" value="v${maven.version.number}"> - <isset property="build.release"/> - </condition> - <!-- For snapshots, if we know the commit, point scaladoc to that particular commit instead of master --> - <condition property="scaladoc.git.commit" value="${git.commit.sha}"> - <not><equals arg1="${git.commit.sha}" arg2="unknown"/></not> - </condition> - <!-- Fallback: point scaladoc to master --> - <property name="scaladoc.git.commit" value="master"/> - <!-- Compute the URL and show it --> - <property name="scaladoc.url" value="https://github.com/scala/scala/tree/${scaladoc.git.commit}/src"/> - <echo message="Scaladoc will point to ${scaladoc.url} for source files."/> - - <!-- Unless set with -Dscaladoc.<...>, these won't be activated --> - <property name="scaladoc.raw.output" value="no"/> - <property name="scaladoc.no.prefixes" value="no"/> - </target> - - <target name="docs.pre-lib" depends="docs.start"> - <doc-uptodate-check name="library" srcdir="${src.dir}"> - <source-includes> - <include name="library/**"/> - <include name="swing/**"/> - <include name="actors/**"/> - <include name="reflect/**"/> - </source-includes> - </doc-uptodate-check> - </target> - - <target name="docs.lib" depends="docs.pre-lib" unless="docs.library.available"> - <stopwatch name="docs.lib.timer"/> - <mkdir dir="${build-docs.dir}/library"/> - <scaladoc - destdir="${build-docs.dir}/library" - doctitle="Scala Standard Library API (Scaladoc)" - docversion="${version.number}" - docfooter="epfl" - docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1" - docUncompilable="${src.dir}/library-aux" - skipPackages="scala.reflect.macros.internal:scala.reflect.internal:scala.reflect.io:scala.concurrent.impl" - sourcepath="${src.dir}" - classpathref="pack.classpath" - addparams="${scalac.args.all}" - docRootContent="${src.dir}/library/rootdoc.txt" - implicits="on" - diagrams="on" - groups="on" - rawOutput="${scaladoc.raw.output}" - noPrefixes="${scaladoc.no.prefixes}"> - <src> - <files includes="${src.dir}/actors"/> - <files includes="${src.dir}/library"/> - <files includes="${src.dir}/reflect"/> - <files includes="${src.dir}/swing"/> - <files includes="${src.dir}/continuations/library"/> - </src> - <include name="**/*.scala"/> - <exclude name="reflect/Code.scala"/> - <exclude name="reflect/Print.scala"/> - <exclude name="reflect/Symbol.scala"/> - <exclude name="reflect/Tree.scala"/> - <exclude name="reflect/Type.scala"/> - <exclude name="runtime/*$.scala"/> - <exclude name="runtime/ScalaRunTime.scala"/> - <exclude name="runtime/StringAdd.scala"/> - </scaladoc> - <touch file="${build-docs.dir}/library.complete" verbose="no"/> - <stopwatch name="docs.lib.timer" action="total"/> - </target> - - <target name="docs.pre-man" depends="docs.lib"> - <doc-uptodate-check name="manual" srcdir="${src.dir}/manual"/> - </target> - - <target name="docs.manmaker" depends="docs.pre-man" unless="docs.manual.available"> - <mkdir dir="${build.dir}/manmaker/classes"/> - <scalac - destdir="${build.dir}/manmaker/classes" - classpathref="pack.classpath" - srcdir="${src.dir}/manual" - includes="**/*.scala" - addparams="${scalac.args.all}"/> - <path id="manual.classpath"> - <pathelement location="${build-pack.dir}/lib/scala-library.jar"/> - <pathelement location="${build.dir}/manmaker/classes"/> - </path> - </target> - - <target name="docs.man" depends="docs.manmaker" unless="docs.manual.available"> - <mkdir dir="${build-docs.dir}/manual/man/man1"/> - <mkdir dir="${build-docs.dir}/manual/html"/> - <mkdir dir="${build-docs.dir}/manual/genman/man1"/> - <taskdef name="genman" - classname="scala.tools.docutil.ManMaker" - classpathref="manual.classpath"/> - <genman command="fsc, scala, scalac, scaladoc, scalap" - htmlout="${build-docs.dir}/manual/html" - manout="${build-docs.dir}/manual/genman"/> - <!-- On Windows source and target files can't be the same ! --> - <fixcrlf - srcdir="${build-docs.dir}/manual/genman" - destdir="${build-docs.dir}/manual/man" - eol="unix" includes="**/*.1"/> - <copy todir="${build-docs.dir}/manual/html"> - <fileset dir="${src.dir}/manual/scala/tools/docutil/resources"> - <include name="**/*.html"/> - <include name="**/*.css"/> - <include name="**/*.gif"/> - <include name="**/*.png"/> - </fileset> - </copy> - <touch file="${build-docs.dir}/manual.complete" verbose="no"/> - </target> - - <target name="docs.pre-comp" depends="docs.man"> - <doc-uptodate-check name="compiler" srcdir="${src.dir}/compiler"/> - </target> - - <target name="docs.comp" depends="docs.pre-comp" unless="docs.compiler.available"> - <stopwatch name="docs.comp.timer"/> - <mkdir dir="${build-docs.dir}/compiler"/> - <scaladoc - destdir="${build-docs.dir}/compiler" - doctitle="Scala Compiler" - docversion="${version.number}" - docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1" - sourcepath="${src.dir}" - classpathref="pack.classpath" - srcdir="${src.dir}/compiler" - docRootContent="${src.dir}/compiler/rootdoc.txt" - addparams="${scalac.args.all}" - implicits="on" - diagrams="on" - groups="on" - rawOutput="${scaladoc.raw.output}" - noPrefixes="${scaladoc.no.prefixes}"> - <include name="**/*.scala"/> - </scaladoc> - <touch file="${build-docs.dir}/compiler.complete" verbose="no"/> - <stopwatch name="docs.comp.timer" action="total"/> - </target> - - <target name="docs.pre-jline" depends="docs.start"> - <doc-uptodate-check name="jline" srcdir="${src.dir}/jline/src/main/java" /> - </target> - - <target name="docs.jline" depends="docs.pre-jline" unless="docs.jline.available"> - <stopwatch name="docs.jline.timer"/> - <mkdir dir="${build-docs.dir}/jline"/> - <scaladoc - destdir="${build-docs.dir}/jline" - doctitle="Scala JLine" - docversion="${version.number}" - sourcepath="${src.dir}" - classpathref="pack.classpath" - srcdir="${src.dir}/jline/src/main/java" - addparams="${scalac.args.all}" - implicits="on" - diagrams="on" - groups="on" - rawOutput="${scaladoc.raw.output}" - noPrefixes="${scaladoc.no.prefixes}"> - <include name="**/*.scala"/> - <include name="**/*.java"/> - </scaladoc> - <touch file="${build-docs.dir}/jline.complete" verbose="no"/> - <stopwatch name="docs.jline.timer" action="total"/> - </target> - - <target name="docs.pre-scalap" depends="docs.start"> - <doc-uptodate-check name="scalap" srcdir="${src.dir}/scalap" /> - </target> - - <target name="docs.scalap" depends="docs.pre-scalap" unless="docs.scalap.available"> - <stopwatch name="docs.scalap.timer"/> - <mkdir dir="${build-docs.dir}/scalap"/> - <scaladoc - destdir="${build-docs.dir}/scalap" - doctitle="Scalap" - docversion="${version.number}" - docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1" - sourcepath="${src.dir}" - classpathref="pack.classpath" - srcdir="${src.dir}/scalap" - addparams="${scalac.args.all}" - implicits="on" - diagrams="on" - groups="on" - rawOutput="${scaladoc.raw.output}" - noPrefixes="${scaladoc.no.prefixes}"> - <include name="**/*.scala"/> - </scaladoc> - <touch file="${build-docs.dir}/scalap.complete" verbose="no"/> - <stopwatch name="docs.scalap.timer" action="total"/> - </target> - - <target name="docs.pre-partest" depends="docs.start"> - <doc-uptodate-check name="partest" srcdir="${src.dir}/partest" /> - </target> - - <target name="docs.partest" depends="docs.pre-partest" unless="docs.partest.available"> - <stopwatch name="docs.partest.timer"/> - <mkdir dir="${build-docs.dir}/scala-partest"/> - <scaladoc - destdir="${build-docs.dir}/scala-partest" - doctitle="Scala Parallel Testing Framework" - docversion="${version.number}" - sourcepath="${src.dir}" - classpathref="pack.classpath" - srcdir="${src.dir}/partest" - addparams="${scalac.args.all}" - implicits="on" - diagrams="on" - groups="on" - rawOutput="${scaladoc.raw.output}" - noPrefixes="${scaladoc.no.prefixes}"> - <include name="**/*.scala"/> - </scaladoc> - <touch file="${build-docs.dir}/partest.complete" verbose="no"/> - <stopwatch name="docs.partest.timer" action="total"/> - </target> - - <target name="docs.pre-continuations-plugin" depends="docs.start"> - <doc-uptodate-check name="continuations-plugin" srcdir="${src.dir}/continuations/plugin" /> - </target> - - <target name="docs.continuations-plugin" depends="docs.pre-continuations-plugin" unless="docs.continuations-plugin.available"> - <stopwatch name="docs.continuations-plugin.timer"/> - <mkdir dir="${build-docs.dir}/continuations-plugin"/> - <scaladoc - destdir="${build-docs.dir}/continuations-plugin" - doctitle="Delimited Continuations Compiler Plugin" - docversion="${version.number}" - sourcepath="${src.dir}" - classpathref="pack.classpath" - srcdir="${src.dir}/continuations/plugin" - addparams="${scalac.args.all}" - implicits="on" - diagrams="on" - groups="on" - rawOutput="${scaladoc.raw.output}" - noPrefixes="${scaladoc.no.prefixes}"> - <include name="**/*.scala"/> - </scaladoc> - <touch file="${build-docs.dir}/continuations-plugin.complete" verbose="no"/> - <stopwatch name="docs.continuations-plugin.timer" action="total"/> - </target> - - <target name="docs.done" depends="docs.man"/> - - <target name="docs.all" depends="docs.jline, docs.comp, docs.man, docs.lib, docs.scalap, docs.partest, docs.continuations-plugin"/> - - <target name="docs.clean"> - <delete dir="${build-docs.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - <delete dir="${build.dir}/manmaker" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> - -<!-- =========================================================================== -BOOTRAPING TEST AND TEST SUITE -============================================================================ --> - - <target name="test.stability" depends="strap.done, init"> - <same dir="${build-quick.dir}" todir="${build-strap.dir}" failondifferent="yes"> - <exclude name="**/*.properties"/> - <exclude name="bin/**"/> - <exclude name="*.complete"/> - <exclude name="misc/scala-devel/plugins/*.jar"/> - </same> - </target> - - <target name="test.classload" depends="pack.done"> - <!-- TODO - Add actors + reflect to this --> - <classloadVerify classpath="${build-pack.dir}/lib/scala-library.jar" /> - </target> - - <!-- this target will run only those tests found in test/debug --> - <target name="test.sbt" depends="sbt.done"> - </target> - - <!-- this target will run only those tests found in test/debug --> - <target name="test.debug"> - <antcall target="test.suite"> - <param name="partest.srcdir" value="debug" /> - </antcall> - </target> + <property name="partest.srcdir" value="files" /> <!-- TODO: make targets for `pending` and other subdirs --> <target name="test.run" depends="pack.done"> - <property name="partest.srcdir" value="files" /> <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" timeout="1200000" srcdir="${partest.srcdir}" scalacopts="${scalac.args.optimise}"> - <compilationpath> - <path refid="pack.classpath"/> - <pathelement location="${pack.dir}/lib/scala-swing.jar"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + + <compilationpath refid="partest.classpath"/> <runtests dir="${partest.dir}/${partest.srcdir}/run" includes="*.scala"/> <jvmtests dir="${partest.dir}/${partest.srcdir}/jvm" includes="*.scala"/> </partest> </target> - <target name="test.ant" depends="pack.done"> - <property name="partest.srcdir" value="files" /> - <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" - srcdir="${partest.srcdir}" - scalacopts="${scalac.args.optimise}"> - <compilationpath> - <path refid="pack.classpath"/> - <pathelement location="${pack.dir}/lib/scala-swing.jar"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> - <anttests dir="${partest.dir}/${partest.srcdir}/ant" includes="*build.xml"/> - </partest> - </target> - <target name="test.suite" depends="pack.done"> - <property name="partest.srcdir" value="files" /> <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" timeout="2400000" srcdir="${partest.srcdir}" scalacopts="${scalac.args.optimise}"> - <compilationpath> - <path refid="pack.classpath"/> - <pathelement location="${pack.dir}/lib/scala-swing.jar"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + <compilationpath refid="partest.classpath"/> <postests dir="${partest.dir}/${partest.srcdir}/pos" includes="*.scala"/> <negtests dir="${partest.dir}/${partest.srcdir}/neg" includes="*.scala"/> <runtests dir="${partest.dir}/${partest.srcdir}/run" includes="*.scala"/> @@ -2608,25 +1418,17 @@ BOOTRAPING TEST AND TEST SUITE <instrumentedtests dir="${partest.dir}/${partest.srcdir}/instrumented"> <include name="*.scala"/> </instrumentedtests> - <presentationtests dir="${partest.dir}/${partest.srcdir}/presentation"> - <include name="*/*.scala"/> - </presentationtests> - <!-- <scripttests dir="${partest.dir}/${partest.srcdir}/script" includes="*.scala"/> --> </partest> </target> <target name="test.continuations.suite" depends="pack.done"> - <property name="partest.srcdir" value="files" /> <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" timeout="2400000" srcdir="${partest.srcdir}" scalacopts="${scalac.args.optimise} -Xplugin-require:continuations -P:continuations:enable"> <compilerarg value="-Xpluginsdir"/> <compilerarg file="${build-quick.dir}/misc/scala-devel/plugins"/> - <compilationpath> - <path refid="pack.classpath"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + <compilationpath refid="partest.classpath"/> <negtests dir="${partest.dir}/${partest.srcdir}/continuations-neg" includes="*.scala"/> <runtests dir="${partest.dir}/${partest.srcdir}/continuations-run" includes="*.scala"/> </partest> @@ -2634,23 +1436,29 @@ BOOTRAPING TEST AND TEST SUITE <target name="test.scaladoc" depends="pack.done"> <partest erroronfailed="yes" scalacopts="${scalac.args.optimise}" showlog="yes"> - <compilationpath> - <path refid="pack.classpath"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + <compilationpath refid="partest.classpath"/> <runtests dir="${partest.dir}/scaladoc/run" includes="*.scala" /> <scalachecktests dir="${partest.dir}/scaladoc/scalacheck" includes="*.scala" /> </partest> </target> - <target name="test.done" depends="test.suite, test.continuations.suite, test.scaladoc, test.stability, test.sbt, osgi.test, bc.run"/> + <target name="test.interactive" depends="pack.done"> + <partest erroronfailed="yes" scalacopts="${scalac.args.optimise}" showlog="yes"> + <compilationpath refid="partest.classpath"/> + <presentationtests dir="${partest.dir}/${partest.srcdir}/presentation"> + <include name="*/*.scala"/> + </presentationtests> + </partest> + </target> + +<!-- currently disabled: test.ant, test.bc, test.positions, test.classload --> + <target name="test.done" depends="test.osgi, test.sbt, test.interactive, test.continuations.suite, test.suite, test.scaladoc, test.stability"/> <!-- =========================================================================== -Binary compatibility testing + BINARY COMPATIBILITY TESTING ============================================================================ --> - - <target name="bc.init" depends="init"> + <target name="bc.init" depends="init" unless="maven-deps-done-mima"> <property name="bc-build.dir" value="${build.dir}/bc"/> <!-- Obtain mima --> <mkdir dir="${bc-build.dir}"/> @@ -2663,6 +1471,7 @@ Binary compatibility testing <dependency groupId="org.scala-lang" artifactId="scala-library" version="2.10.0"/> <dependency groupId="org.scala-lang" artifactId="scala-reflect" version="2.10.0"/> </artifact:dependencies> + <property name="maven-deps-done-mima" value="true"/> </target> <macrodef name="bc.run-mima"> @@ -2706,17 +1515,162 @@ Binary compatibility testing </sequential> </macrodef> - <target name="bc.run" depends="bc.init, pack.done"> + <target name="test.bc" depends="bc.init, pack.lib, pack.reflect, pack.swing"> <bc.check jar-name="scala-library"/> <bc.check jar-name="scala-reflect"/> <bc.check jar-name="scala-swing"/> </target> <!-- =========================================================================== -DISTRIBUTION + DOCUMENTATION ============================================================================ --> + <target name="docs.start" depends="pack.done"> + <!-- Set the github commit scaladoc sources point to --> + <!-- For releases, look for the tag with the same name as the maven version --> + <condition property="scaladoc.git.commit" value="v${maven.version.number}"> + <isset property="build.release"/> + </condition> + <!-- For snapshots, if we know the commit, point scaladoc to that particular commit instead of master --> + <condition property="scaladoc.git.commit" value="${git.commit.sha}"> + <not><equals arg1="${git.commit.sha}" arg2="unknown"/></not> + </condition> + <!-- Fallback: point scaladoc to master --> + <property name="scaladoc.git.commit" value="master"/> + <!-- Compute the URL and show it --> + <property name="scaladoc.url" value="https://github.com/scala/scala/tree/${scaladoc.git.commit}/src"/> + <echo message="Scaladoc will point to ${scaladoc.url} for source files."/> - <target name="dist.start" depends="pack.done, osgi.done"> + <!-- Unless set with -Dscaladoc.<...>, these won't be activated --> + <property name="scaladoc.raw.output" value="no"/> + <property name="scaladoc.no.prefixes" value="no"/> + </target> + + <target name="docs.lib" depends="docs.start"> + <staged-uptodate stage="docs" project="library"> + <check><srcfiles dir="${src.dir}"> + <include name="library/**"/> + <include name="swing/**"/> + <include name="actors/**"/> + <include name="reflect/**"/> + </srcfiles></check> + <do> + <stopwatch name="docs.lib.timer"/> + <mkdir dir="${build-docs.dir}/library"/> + <!-- last three attributes not supported by staged-docs: --> + <scaladoc + destdir="${build-docs.dir}/library" + doctitle="Scala Standard Library API (Scaladoc)" + docversion="${version.number}" + docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1" + sourcepath="${src.dir}" + classpathref="pack.compiler.path" + addparams="${scalac.args.all}" + docRootContent="${src.dir}/library/rootdoc.txt" + implicits="on" + diagrams="on" + groups="on" + rawOutput="${scaladoc.raw.output}" + noPrefixes="${scaladoc.no.prefixes}" + docfooter="epfl" + docUncompilable="${src.dir}/library-aux" + skipPackages="scala.reflect.macros.internal:scala.reflect.internal:scala.reflect.io:scala.concurrent.impl"> + <src> + <files includes="${src.dir}/actors"/> + <files includes="${src.dir}/library"/> + <files includes="${src.dir}/reflect"/> + <files includes="${src.dir}/swing"/> + <files includes="${src.dir}/continuations/library"/> + </src> + <include name="**/*.scala"/> + <exclude name="reflect/Code.scala"/> + <exclude name="reflect/Print.scala"/> + <exclude name="reflect/Symbol.scala"/> + <exclude name="reflect/Tree.scala"/> + <exclude name="reflect/Type.scala"/> + <exclude name="runtime/*$.scala"/> + <exclude name="runtime/ScalaRunTime.scala"/> + <exclude name="runtime/StringAdd.scala"/> + </scaladoc> + <stopwatch name="docs.lib.timer" action="total"/> + </do> + </staged-uptodate> + </target> + + <target name="docs.comp" depends="docs.start"> + <staged-docs project="compiler" title="Scala Compiler" docroot="rootdoc.txt"> + <include name="**/*.scala"/> + </staged-docs> + </target> + + <target name="docs.jline" depends="docs.start"> + <staged-docs project="jline" dir="jline/src/main/java" title="Scala JLine"> + <include name="**/*.scala"/> + <include name="**/*.java"/> + </staged-docs> + </target> + + <target name="docs.scalap" depends="docs.start"> + <staged-docs project="scalap" title="Scalap"> + <include name="**/*.scala"/> + </staged-docs> + </target> + + <target name="docs.partest" depends="docs.start"> + <staged-docs project="partest" title="Scala Parallel Testing Framework"> + <include name="**/*.scala"/> + </staged-docs> + </target> + + <target name="docs.continuations-plugin" depends="docs.start"> + <staged-docs project="continuations-plugin" dir="continuations/plugin" title="Delimited Continuations Compiler Plugin"> + <include name="**/*.scala"/> + </staged-docs> + </target> + + <target name="docs.man" depends="docs.start"> + <staged-uptodate stage="docs" project="manual"> + <check><srcfiles dir="${src.dir}/manual"/></check> + <do> + <mkdir dir="${build.dir}/manmaker/classes"/> + <scalac + destdir="${build.dir}/manmaker/classes" + classpathref="pack.compiler.path" + srcdir="${src.dir}/manual" + includes="**/*.scala" + addparams="${scalac.args.all}"/> + <mkdir dir="${build-docs.dir}/manual/man/man1"/> + <mkdir dir="${build-docs.dir}/manual/html"/> + <mkdir dir="${build-docs.dir}/manual/genman/man1"/> + <taskdef name="genman" + classname="scala.tools.docutil.ManMaker" + classpathref="manual.classpath"/> + <genman command="fsc, scala, scalac, scaladoc, scalap" + htmlout="${build-docs.dir}/manual/html" + manout="${build-docs.dir}/manual/genman"/> + <!-- On Windows source and target files can't be the same ! --> + <fixcrlf + srcdir="${build-docs.dir}/manual/genman" + destdir="${build-docs.dir}/manual/man" + eol="unix" includes="**/*.1"/> + <copy todir="${build-docs.dir}/manual/html"> + <fileset dir="${src.dir}/manual/scala/tools/docutil/resources"> + <include name="**/*.html"/> + <include name="**/*.css"/> + <include name="**/*.gif"/> + <include name="**/*.png"/> + </fileset> + </copy> + </do> + </staged-uptodate> + </target> + + <target name="docs.done" depends="docs.jline, docs.comp, docs.man, docs.lib, docs.scalap, docs.partest, docs.continuations-plugin"/> + + +<!-- =========================================================================== + DISTRIBUTION +============================================================================ --> + <target name="dist.base" depends="pack.done, osgi.done"> <property name="dist.name" value="scala-${version.number}"/> <property name="dist.dir" value="${dists.dir}/${dist.name}"/> @@ -2735,9 +1689,7 @@ DISTRIBUTION overwrite="yes"/> </sequential> </macrodef> - </target> - <target name="dist.base" depends="dist.start"> <mkdir dir="${dist.dir}/lib"/> <copy toDir="${dist.dir}/lib"> <fileset dir="${build-pack.dir}/lib"> @@ -2788,70 +1740,42 @@ DISTRIBUTION toFile="${dist.dir}/doc/scala-devel-docs/README.scala-swing"/> </target> - <target name="dist.man" depends="dist.doc"> + <target name="dist.man" depends="dist.base"> <mkdir dir="${dist.dir}/man"/> <copy toDir="${dist.dir}/man"> <fileset dir="${build-docs.dir}/manual/man"/> </copy> </target> - <target name="dist.src" depends="dist.man"> + <target name="dist.src" depends="dist.base"> <mkdir dir="${dist.dir}/src"/> - <jar destfile="${dist.dir}/src/scala-library-src.jar"> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/scala-library-src.jar"> <fileset dir="${src.dir}/library"/> <fileset dir="${src.dir}/continuations/library"/> </jar> - <jar destfile="${dist.dir}/src/scala-reflect-src.jar"> - <fileset dir="${src.dir}/reflect"/> - </jar> - <jar destfile="${dist.dir}/src/scala-swing-src.jar"> - <fileset dir="${src.dir}/swing"/> - </jar> - <jar destfile="${dist.dir}/src/scala-compiler-src.jar"> - <fileset dir="${src.dir}/compiler"/> - </jar> - <jar destfile="${dist.dir}/src/scala-actors-src.jar"> - <fileset dir="${src.dir}/actors"/> - </jar> - <jar destfile="${dist.dir}/src/scalap-src.jar"> - <fileset dir="${src.dir}/scalap"/> - </jar> - <!-- Needed for Maven distribution --> - <jar destfile="${dist.dir}/src/scala-partest-src.jar"> - <fileset dir="${src.dir}/partest"/> - </jar> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/scala-reflect-src.jar" basedir="${src.dir}/reflect"/> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/scala-swing-src.jar" basedir="${src.dir}/swing"/> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/scala-compiler-src.jar" basedir="${src.dir}/compiler"/> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/fjbg-src.jar" basedir="${src.dir}/fjbg"/> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/msil-src.jar" basedir="${src.dir}/msil"/> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/scala-actors-src.jar" basedir="${src.dir}/actors"/> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/scalap-src.jar" basedir="${src.dir}/scalap"/> + <jar whenmanifestonly="fail" destfile="${dist.dir}/src/scala-partest-src.jar" basedir="${src.dir}/partest"/> </target> - <target name="dist.latest.unix" depends="dist.base" unless="os.win"> - <symlink link="${dists.dir}/latest" resource="${dist.name}" overwrite="yes"/> - </target> - - <target name="dist.latest.win" depends="dist.base" if="os.win"> - <copy todir="${dists.dir}/latest"> - <fileset dir="${dist.dir}"/> - </copy> + <target name="dist.partial" depends="dist.base"> + <if><not><os family="windows"/></not><then> + <symlink link="${dists.dir}/latest" resource="${dist.name}" overwrite="yes"/> + </then><else> <!-- XXX THIS PROBABLY DOES NOT WORK: copying must happen last during dist.done! is this guaranteed? --> + <copydir dest="${dists.dir}/latest" src="${dist.dir}"/> + </else></if> </target> - <target name="dist.latest" depends="dist.latest.unix,dist.latest.win"/> + <target name="dist.done" depends="dist.doc, dist.man, dist.src, dist.partial"/> - <target name="dist.partial" depends="dist.base, dist.latest"/> - - <target name="dist.done" depends="dist.latest, dist.src"/> - - <target name="dist.clean"> - <delete dir="${dists.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> - </target> - -<!-- =========================================================================== -TEST AND DISTRIBUTION BUNDLE (ALL) -============================================================================ --> - - <target name="all.done" depends="dist.done, test.done"/> - - <target name="all.clean" depends="locker.clean, docs.clean, dist.clean, sbt.clean, osgi.clean"/> <!-- =========================================================================== -STABLE REFERENCE (STARR) + STABLE REFERENCE (STARR) ============================================================================ --> <!-- Does not use any properties other than ${basedir}, so that it can run without 'init' (when using 'replacestarrwin') --> @@ -2859,28 +1783,19 @@ STABLE REFERENCE (STARR) <target name="starr.start"> <fail message="Library in build/pack not available"> <condition><not><and> - <available file="${basedir}/build/pack/lib/scala-library.jar"/> + <available file="${build-pack.dir}/lib/scala-library.jar"/> </and></not></condition> </fail> <fail message="Compiler in build/quick not available"> <condition><not><and> - <available file="${basedir}/build/quick/classes/compiler"/> - <available file="${basedir}/build/quick/compiler.complete"/> + <available file="${build-quick.dir}/classes/compiler"/> + <available file="${build-quick.dir}/compiler.complete"/> </and></not></condition> </fail> </target> - <target name="starr.clean" depends="starr.start"> - <delete file="${basedir}/lib/scala-library.jar"/> - <delete file="${basedir}/lib/scala-reflect.jar"/> - <delete file="${basedir}/lib/scala-compiler.jar"/> - <delete file="${basedir}/lib/scala-library-src.jar"/> - <delete file="${basedir}/lib/scala-reflect-src.jar"/> - <delete file="${basedir}/lib/scala-compiler-src.jar"/> - </target> - <target name="starr.jars" depends="starr.start"> - <copy toDir="${basedir}/lib/" overwrite="yes"> + <copy toDir="${lib.dir}" overwrite="yes"> <fileset dir="${build-pack.dir}/lib"> <include name="scala-library.jar"/> <include name="scala-reflect.jar"/> @@ -2890,20 +1805,16 @@ STABLE REFERENCE (STARR) </target> <target name="starr.src" depends="starr.jars"> - <jar destfile="${basedir}/lib/scala-library-src.jar"> - <fileset dir="${basedir}/src/library"/> - <fileset dir="${basedir}/src/swing"/> - <fileset dir="${basedir}/src/actors"/> - <fileset dir="${basedir}/src/forkjoin"/> - </jar> - <jar destfile="${basedir}/lib/scala-reflect-src.jar"> - <fileset dir="${basedir}/src/reflect"/> + <jar whenmanifestonly="fail" destfile="${lib.dir}/scala-library-src.jar"> + <fileset dir="${src.dir}/library"/> + <fileset dir="${src.dir}/swing"/> + <fileset dir="${src.dir}/actors"/> + <fileset dir="${src.dir}/forkjoin"/> </jar> - <jar destfile="${basedir}/lib/scala-compiler-src.jar"> - <fileset dir="${basedir}/src/compiler"/> - <fileset dir="${basedir}/src/asm"/> - <fileset dir="${basedir}/src/fjbg"/> - <fileset dir="${basedir}/src/msil"/> + <jar whenmanifestonly="fail" destfile="${lib.dir}/scala-reflect-src.jar" basedir="${src.dir}/reflect"/> + <jar whenmanifestonly="fail" destfile="${lib.dir}/scala-compiler-src.jar"> + <fileset dir="${src.dir}/compiler"/> + <fileset dir="${src.dir}/asm"/> </jar> </target> @@ -2923,60 +1834,85 @@ STABLE REFERENCE (STARR) <target name="starr.done" depends="starr.jars, starr.removesha1"/> -<!-- =========================================================================== -FORWARDED TARGETS FOR PACKAGING -============================================================================ --> - - <target name="distpack" depends="dist.done, docs.all"> - <ant antfile="${src.dir}/build/pack.xml" target="pack-all.done" inheritall="yes" inheritrefs="yes"/> + <target name="replacestarr" description="Replaces the Starr compiler and library by fresh ones built from current sources and tests them."> + <fail message="This target is not available on Windows. Use 'ant replacestarrwin' instead."> + <condition> + <os family="windows"/> + </condition> + </fail> + <!-- needs antcall to enforce ordering --> + <antcall target="locker.clean"/> + <antcall target="pack.done"/> + <antcall target="starr.done"/> + <antcall target="locker.clean"/> + <antcall target="test.done"/> </target> - <target name="distpack-maven" depends="dist.done, docs.all"> - <ant antfile="${src.dir}/build/pack.xml" target="pack-maven.done" inheritall="yes" inheritrefs="yes"/> - </target> + <target name="replacestarr-opt" description="Replaces the Starr compiler and library by fresh, optimised ones built from current sources and tests them."> + <optimized name="replacestarr"/></target> - <target name="distpack-opt" - description="Builds an optimised distribution."> - <antcall target="distpack"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> + <!-- Ant on Windows is not able to delete jar files that are referenced in any <path>. + See ticket 1290 on trac. --> + <target name="replacestarrwin" description="Creates a new Starr on Windows. Manually execute 'ant locker.clean build' first!"> + <fail message="This target is only available on Windows. Use 'ant replacestarr' instead."> + <condition> + <not><os family="windows"/></not> + </condition> + </fail> + <echo message="CAUTION: Make sure to execute 'ant locker.clean build' prior to calling 'replacestarrwin'."/> + <antcall target="starr.done"/> + <antcall target="locker.clean"/> + <antcall target="test.done"/> </target> - <target name="distpack-maven-opt" - description="Builds an optimised maven distribution."> - <antcall target="distpack-maven"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> - </target> + <target name="replacestarrwin-opt" description="Creates a new Starr on Windows. Manually execute 'ant locker.clean build' first!"> + <optimized name="replacestarrwin"/></target> - <!-- Used by the scala-installer script --> - <target name="allallclean" depends="all.clean"/> + <target name="replacelocker" description="Replaces the Locker compiler and library by fresh ones built from current sources." + depends="palo.clean, locker.unlock, palo.done"/> -<!-- =========================================================================== -FORWARDED TARGETS FOR NIGHTLY BUILDS -============================================================================ --> + <target name="replacelocker-opt" description="Replaces the Locker compiler and library by fresh, optimised ones built from current sources."> + <optimized name="replacelocker"/></target> - <target name="nightly"> - <antcall target="nightly-nopt"> - <param name="scalac.args.optimise" value="-optimise"/> - </antcall> + <target name="buildlocker" description="Does the same for locker as build does for quick." depends="locker.unlock, palo.bin"/> + <target name="unlocklocker" description="Same as buildlocker." depends="buildlocker"/> <!-- REMOVE --> + + <target name="fastlocker.lib" description="Buildlocker without extra fuss" depends="locker.unlock, locker.lib"> + <property name="fastlocker" value="true"/> </target> - <target name="nightly-nopt" depends="all.done, docs.all"> - <!-- cannot antcall all.done, the properties defined in there (dist.dir) are not returned. need depends. --> - <ant antfile="${src.dir}/build/pack.xml" target="pack-all.done" inheritall="yes" inheritrefs="yes"/> + <target name="fastlocker.reflect" description="Buildlocker without extra fuss" depends="locker.unlock, locker.reflect"> + <property name="fastlocker" value="true"/> </target> - <target name="nightly.checkall"> - <antcall target="nightly-nopt"> - <param name="partest.scalacopts" value="-Ycheck:all"/> - </antcall> + <target name="fastlocker.comp" description="Buildlocker without extra fuss" depends="locker.unlock, locker.comp"> + <property name="fastlocker" value="true"/> </target> + <target name="fastlocker" description="Buildlocker without extra fuss" depends="fastlocker.comp"/> + + <!-- =========================================================================== -POSITIONS + TODO: FIX OR REMOVE ============================================================================ --> + <!-- not called by test target --> + <target name="test.classload" depends="pack.done"> + <!-- TODO - Add actors + reflect to this --> + <classloadVerify classpath="${build-pack.dir}/lib/scala-library.jar" /> + </target> + + <!-- not called by test target --> + <target name="test.ant" depends="pack.done"> + <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" + srcdir="${partest.srcdir}" + scalacopts="${scalac.args.optimise}"> + <compilationpath refid="partest.classpath"/> + <anttests dir="${partest.dir}/${partest.srcdir}/ant" includes="*build.xml"/> + </partest> + </target> + + <!-- not called by test target --> <target name="test.positions" depends="quick.comp"> <antcall target="test.positions.tests.sub" inheritRefs="true"> <param name="test.tests.srcs" value="${partest.dir}/files/positions"/> @@ -3030,15 +1966,13 @@ POSITIONS </if> <scalacfork destdir="" - compilerpathref="locker.classpath" + compilerpathref="locker.compiler.path" srcpath="${srcdir}" params="-Xprint-pos -Yide-debug" srcdir="${srcdir}" jvmargs="${scalacfork.jvmargs}"> <include name="${srcs}"/> - <compilationpath> - <pathelement location="${build-quick.dir}/classes/library"/> - </compilationpath> + <compilationpath refid="test.positions.sub.build.path"/> </scalacfork> </target> @@ -3057,18 +1991,13 @@ POSITIONS </target> <!-- =========================================================================== -MISCELLANEOUS + VISUALIZATION ============================================================================ --> - <target name="graph.init"> <taskdef name="vizant" classname="vizant.Vizant" classpath="${lib-ant.dir}/vizant.jar"/> </target> - <target name="graph.clean" depends="graph.init"> - <vizant antfile="${ant.file}" outfile="${ant.project.name}.dot" from="starr.clean"/> - </target> - <target name="graph.all" depends="graph.init"> <vizant antfile="${ant.file}" outfile="${ant.project.name}.dot" from="all.done"/> </target> diff --git a/src/build/pack.xml b/src/build/pack.xml index 79611b55a2..381d3f1931 100644 --- a/src/build/pack.xml +++ b/src/build/pack.xml @@ -179,41 +179,41 @@ MAIN DISTRIBUTION PACKAGING <target name="pack-maven.srcs" depends="pack-maven.libs"> <!-- Add missing src jars. --> - <jar destfile="${dists.dir}/maven/${version.number}/jline/jline-src.jar" + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/jline/jline-src.jar" basedir="${src.dir}/jline/src/main/java"> <include name="**/*"/> </jar> <!-- Continuations plugin --> - <jar destfile="${dists.dir}/maven/${version.number}/plugins/continuations/continuations-src.jar" + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/plugins/continuations/continuations-src.jar" basedir="${src.dir}/continuations/plugin"> <include name="**/*"/> </jar> </target> <target name="pack-maven.docs" depends="pack-maven.libs, pack-maven.plugins"> - <jar destfile="${dists.dir}/maven/${version.number}/jline/jline-docs.jar" + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/jline/jline-docs.jar" basedir="${build-docs.dir}/jline"> <include name="**/*"/> </jar> - <jar destfile="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar" + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar" basedir="${build-docs.dir}/library"> <include name="**/*"/> </jar> - <jar destfile="${dists.dir}/maven/${version.number}/scala-compiler/scala-compiler-docs.jar" + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/scala-compiler/scala-compiler-docs.jar" basedir="${build-docs.dir}/compiler"> <include name="**/*"/> </jar> - <jar destfile="${dists.dir}/maven/${version.number}/scalap/scalap-docs.jar" + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/scalap/scalap-docs.jar" basedir="${build-docs.dir}/scalap"> <include name="**/*"/> </jar> - <jar destfile="${dists.dir}/maven/${version.number}/scala-partest/scala-partest-docs.jar" - basedir="${build-docs.dir}/scala-partest"> + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/scala-partest/scala-partest-docs.jar" + basedir="${build-docs.dir}/partest"> <include name="**/*"/> </jar> - <jar destfile="${dists.dir}/maven/${version.number}/plugins/continuations/continuations-docs.jar" + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/plugins/continuations/continuations-docs.jar" basedir="${build-docs.dir}/continuations-plugin"> <include name="**/*"/> </jar> diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 7ba212f42e..b74770f051 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -171,6 +171,7 @@ trait Members { var returnType: TypeKind = _ var recursive: Boolean = false var bytecodeHasEHs = false // set by ICodeReader only, used by Inliner to prevent inlining (SI-6188) + var bytecodeHasInvokeDynamic = false // set by ICodeReader only, used by Inliner to prevent inlining until we have proper invoke dynamic support /** local variables and method parameters */ var locals: List[Local] = Nil diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala index 8c9a72638d..a3a0edb35d 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala @@ -409,6 +409,25 @@ trait Opcodes { self: ICodes => override def category = mthdsCat } + + /** + * A place holder entry that allows us to parse class files with invoke dynamic + * instructions. Because the compiler doesn't yet really understand the + * behavior of invokeDynamic, this op acts as a poison pill. Any attempt to analyze + * this instruction will cause a failure. The only optimization that + * should ever look at non-Scala generated icode is the inliner, and it + * has been modified to not examine any method with invokeDynamic + * instructions. So if this poison pill ever causes problems then + * there's been a serious misunderstanding + */ + // TODO do the real thing + case class INVOKE_DYNAMIC(poolEntry: Char) extends Instruction { + private def error = sys.error("INVOKE_DYNAMIC is not fully implemented and should not be analyzed") + override def consumed = error + override def produced = error + override def producedTypes = error + override def category = error + } case class BOX(boxType: TypeKind) extends Instruction { assert(boxType.isValueType && (boxType ne UNIT)) // documentation diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 9b16327ffc..7c46d648fe 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -2259,16 +2259,16 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { // info calls so that types are up to date; erasure may add lateINTERFACE to traits hostSymbol.info ; methodOwner.info - def isInterfaceCall(sym: Symbol) = ( - sym.isInterface && methodOwner != ObjectClass + def needsInterfaceCall(sym: Symbol) = ( + sym.isInterface || sym.isJavaDefined && sym.isNonBottomSubClass(ClassfileAnnotationClass) ) // whether to reference the type of the receiver or - // the type of the method owner (if not an interface!) + // the type of the method owner val useMethodOwner = ( style != Dynamic - || !isInterfaceCall(hostSymbol) && isAccessibleFrom(methodOwner, siteSymbol) || hostSymbol.isBottomClass + || methodOwner == ObjectClass ) val receiver = if (useMethodOwner) methodOwner else hostSymbol val jowner = javaName(receiver) @@ -2291,11 +2291,11 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { } style match { - case Static(true) => dbg("invokespecial"); jcode.invokespecial (jowner, jname, jtype) - case Static(false) => dbg("invokestatic"); jcode.invokestatic (jowner, jname, jtype) - case Dynamic if isInterfaceCall(receiver) => dbg("invokinterface"); jcode.invokeinterface(jowner, jname, jtype) - case Dynamic => dbg("invokevirtual"); jcode.invokevirtual (jowner, jname, jtype) - case SuperCall(_) => + case Static(true) => dbg("invokespecial"); jcode.invokespecial (jowner, jname, jtype) + case Static(false) => dbg("invokestatic"); jcode.invokestatic (jowner, jname, jtype) + case Dynamic if needsInterfaceCall(receiver) => dbg("invokinterface"); jcode.invokeinterface(jowner, jname, jtype) + case Dynamic => dbg("invokevirtual"); jcode.invokevirtual (jowner, jname, jtype) + case SuperCall(_) => dbg("invokespecial") jcode.invokespecial(jowner, jname, jtype) initModule() diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 598965b982..36b294b289 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1196,16 +1196,16 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with // info calls so that types are up to date; erasure may add lateINTERFACE to traits hostSymbol.info ; methodOwner.info - def isInterfaceCall(sym: Symbol) = ( - sym.isInterface && methodOwner != ObjectClass + def needsInterfaceCall(sym: Symbol) = ( + sym.isInterface || sym.isJavaDefined && sym.isNonBottomSubClass(ClassfileAnnotationClass) ) // whether to reference the type of the receiver or - // the type of the method owner (if not an interface!) + // the type of the method owner val useMethodOwner = ( style != Dynamic - || !isInterfaceCall(hostSymbol) && isAccessibleFrom(methodOwner, siteSymbol) || hostSymbol.isBottomClass + || methodOwner == ObjectClass ) val receiver = if (useMethodOwner) methodOwner else hostSymbol val jowner = javaName(receiver) @@ -1230,11 +1230,11 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } style match { - case Static(true) => dbg("invokespecial"); jcode.emitINVOKESPECIAL(jowner, jname, jtype) - case Static(false) => dbg("invokestatic"); jcode.emitINVOKESTATIC(jowner, jname, jtype) - case Dynamic if isInterfaceCall(receiver) => dbg("invokinterface"); jcode.emitINVOKEINTERFACE(jowner, jname, jtype) - case Dynamic => dbg("invokevirtual"); jcode.emitINVOKEVIRTUAL(jowner, jname, jtype) - case SuperCall(_) => + case Static(true) => dbg("invokespecial"); jcode.emitINVOKESPECIAL(jowner, jname, jtype) + case Static(false) => dbg("invokestatic"); jcode.emitINVOKESTATIC(jowner, jname, jtype) + case Dynamic if needsInterfaceCall(receiver) => dbg("invokinterface"); jcode.emitINVOKEINTERFACE(jowner, jname, jtype) + case Dynamic => dbg("invokevirtual"); jcode.emitINVOKEVIRTUAL(jowner, jname, jtype) + case SuperCall(_) => dbg("invokespecial") jcode.emitINVOKESPECIAL(jowner, jname, jtype) initModule() diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index 521b6cc132..498db78636 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -961,6 +961,7 @@ abstract class Inliners extends SubComponent { if(isInlineForbidden) { rs ::= "is annotated @noinline" } if(inc.isSynchronized) { rs ::= "is synchronized method" } if(inc.m.bytecodeHasEHs) { rs ::= "bytecode contains exception handlers / finally clause" } // SI-6188 + if(inc.m.bytecodeHasInvokeDynamic) { rs ::= "bytecode contains invoke dynamic" } if(rs.isEmpty) null else rs.mkString("", ", and ", "") } diff --git a/src/compiler/scala/tools/nsc/doc/base/comment/Body.scala b/src/compiler/scala/tools/nsc/doc/base/comment/Body.scala index 02e662da85..eb0d751f3e 100755 --- a/src/compiler/scala/tools/nsc/doc/base/comment/Body.scala +++ b/src/compiler/scala/tools/nsc/doc/base/comment/Body.scala @@ -75,16 +75,20 @@ object EntityLink { def unapply(el: EntityLink): Option[(Inline, LinkTo)] = Some((el.title, el.link)) } final case class HtmlTag(data: String) extends Inline { - def canClose(open: HtmlTag) = { - open.data.stripPrefix("<") == data.stripPrefix("</") + private val Pattern = """(?ms)\A<(/?)(.*?)[\s>].*\z""".r + private val (isEnd, tagName) = data match { + case Pattern(s1, s2) => + (! s1.isEmpty, Some(s2.toLowerCase)) + case _ => + (false, None) } - def close = { - if (data.indexOf("</") == -1) - Some(HtmlTag("</" + data.stripPrefix("<"))) - else - None + def canClose(open: HtmlTag) = { + isEnd && tagName == open.tagName } + + private val TagsNotToClose = Set("br", "img") + def close = tagName collect { case name if !TagsNotToClose(name) => HtmlTag(s"</$name>") } } /** The summary of a comment, usually its first sentence. There must be exactly one summary per body. */ diff --git a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala index ee78f4ea7a..6fdaaed75f 100644 --- a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala +++ b/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala @@ -6,6 +6,7 @@ package scala.tools.nsc.doc.html import scala.xml.NodeSeq +import scala.annotation.tailrec /** Highlight the syntax of Scala code appearing in a `{{{` wiki block * (see method `HtmlPage.blockToHtml`). @@ -209,9 +210,9 @@ private[html] object SyntaxHigh { out.toString } - def parse(pre: String, i: Int): Int = { + @tailrec def parse(pre: String, i: Int): Unit = { out append pre - if (i == buf.length) return i + if (i == buf.length) return buf(i) match { case '\n' => parse("\n", i+1) @@ -277,7 +278,6 @@ private[html] object SyntaxHigh { } else parse(buf(i).toChar.toString, i+1) } - i } parse("", 0) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 1f42fa8aab..fb2301de65 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -44,7 +44,7 @@ abstract class ClassfileParser { def srcfile = srcfile0 - private def currentIsTopLevel = currentClass.toString.indexOf('$') < 0 + private def currentIsTopLevel = !(currentClass.decodedName containsChar '$') private object unpickler extends scala.reflect.internal.pickling.UnPickler { val global: ClassfileParser.this.global.type = ClassfileParser.this.global @@ -137,10 +137,13 @@ abstract class ClassfileParser { (in.nextByte.toInt: @switch) match { case CONSTANT_UTF8 | CONSTANT_UNICODE => in.skip(in.nextChar) - case CONSTANT_CLASS | CONSTANT_STRING => + case CONSTANT_CLASS | CONSTANT_STRING | CONSTANT_METHODTYPE=> in.skip(2) + case CONSTANT_METHODHANDLE => + in.skip(3) case CONSTANT_FIELDREF | CONSTANT_METHODREF | CONSTANT_INTFMETHODREF - | CONSTANT_NAMEANDTYPE | CONSTANT_INTEGER | CONSTANT_FLOAT => + | CONSTANT_NAMEANDTYPE | CONSTANT_INTEGER | CONSTANT_FLOAT + | CONSTANT_INVOKEDYNAMIC => in.skip(4) case CONSTANT_LONG | CONSTANT_DOUBLE => in.skip(8) @@ -436,63 +439,58 @@ abstract class ClassfileParser { sym } - /** Return the class symbol of the given name. */ - def classNameToSymbol(name: Name): Symbol = { - def loadClassSymbol(name: Name): Symbol = { - val file = global.classPath findSourceFile ("" +name) getOrElse { - // SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented - // therefore, it will rummage through the classpath triggering errors whenever it encounters package objects - // that are not in their correct place (see bug for details) - if (!settings.isScaladoc) - warning("Class " + name + " not found - continuing with a stub.") - return NoSymbol.newClass(name.toTypeName) - } - val completer = new global.loaders.ClassfileLoader(file) - var owner: Symbol = rootMirror.RootClass - var sym: Symbol = NoSymbol - var ss: Name = null - var start = 0 - var end = name indexOf '.' - - while (end > 0) { - ss = name.subName(start, end) - sym = owner.info.decls lookup ss - if (sym == NoSymbol) { - sym = owner.newPackage(ss) setInfo completer - sym.moduleClass setInfo completer - owner.info.decls enter sym - } - owner = sym.moduleClass - start = end + 1 - end = name.indexOf('.', start) - } - ss = name.subName(0, start) - owner.info.decls lookup ss orElse { - sym = owner.newClass(ss.toTypeName) setInfoAndEnter completer - debuglog("loaded "+sym+" from file "+file) - sym + private def loadClassSymbol(name: Name): Symbol = { + val file = global.classPath findSourceFile ("" +name) getOrElse { + // SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented + // therefore, it will rummage through the classpath triggering errors whenever it encounters package objects + // that are not in their correct place (see bug for details) + if (!settings.isScaladoc) + warning(s"Class $name not found - continuing with a stub.") + return NoSymbol.newClass(name.toTypeName) + } + val completer = new global.loaders.ClassfileLoader(file) + var owner: Symbol = rootMirror.RootClass + var sym: Symbol = NoSymbol + var ss: Name = null + var start = 0 + var end = name indexOf '.' + + while (end > 0) { + ss = name.subName(start, end) + sym = owner.info.decls lookup ss + if (sym == NoSymbol) { + sym = owner.newPackage(ss) setInfo completer + sym.moduleClass setInfo completer + owner.info.decls enter sym } + owner = sym.moduleClass + start = end + 1 + end = name.indexOf('.', start) } - - def lookupClass(name: Name) = try { - if (name.pos('.') == name.length) - definitions.getMember(rootMirror.EmptyPackageClass, name.toTypeName) - else - rootMirror.getClass(name) // see tickets #2464, #3756 - } catch { - case _: FatalError => loadClassSymbol(name) + ss = name.subName(0, start) + owner.info.decls lookup ss orElse { + sym = owner.newClass(ss.toTypeName) setInfoAndEnter completer + debuglog("loaded "+sym+" from file "+file) + sym } + } + /** FIXME - we shouldn't be doing ad hoc lookups in the empty package. + * The method called "getClassByName" should either return the class or not. + */ + private def lookupClass(name: Name) = ( + if (name containsChar '.') + rootMirror getClassByName name // see tickets #2464, #3756 + else + definitions.getMember(rootMirror.EmptyPackageClass, name.toTypeName) + ) - innerClasses.get(name) match { - case Some(entry) => - //println("found inner class " + name) - val res = innerClasses.classSymbol(entry.externalName) - //println("\trouted to: " + res) - res - case None => - //if (name.toString.contains("$")) println("No inner class: " + name + innerClasses + " while parsing " + in.file.name) - lookupClass(name) - } + /** Return the class symbol of the given name. */ + def classNameToSymbol(name: Name): Symbol = { + if (innerClasses contains name) + innerClasses innerSymbol name + else + try lookupClass(name) + catch { case _: FatalError => loadClassSymbol(name) } } var sawPrivateConstructor = false @@ -646,7 +644,7 @@ abstract class ClassfileParser { info match { case MethodType(params, restpe) => // if this is a non-static inner class, remove the explicit outer parameter - val newParams = innerClasses.get(currentClass) match { + val newParams = innerClasses getEntry currentClass match { case Some(entry) if !isScalaRaw && !isStatic(entry.jflags) => /* About `clazz.owner.isPackage` below: SI-5957 * For every nested java class A$B, there are two symbols in the scala compiler. @@ -748,7 +746,7 @@ abstract class ClassfileParser { res } case tp => - assert(sig.charAt(index) != '<', tp) + assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp") tp } @@ -1107,7 +1105,7 @@ abstract class ClassfileParser { unlinkIfPresent(cName.toTypeName) } - for (entry <- innerClasses.values) { + for (entry <- innerClasses.entries) { // create a new class member for immediate inner classes if (entry.outerName == currentClass) { val file = global.classPath.findSourceFile(entry.externalName.toString) getOrElse { @@ -1145,14 +1143,9 @@ abstract class ClassfileParser { case tpnme.InnerClassesATTR if !isScala => val entries = in.nextChar.toInt for (i <- 0 until entries) { - val innerIndex = in.nextChar.toInt - val outerIndex = in.nextChar.toInt - val nameIndex = in.nextChar.toInt - val jflags = in.nextChar.toInt - if (innerIndex != 0 && outerIndex != 0 && nameIndex != 0) { - val entry = InnerClassEntry(innerIndex, outerIndex, nameIndex, jflags) - innerClasses += (pool.getClassName(innerIndex) -> entry) - } + val innerIndex, outerIndex, nameIndex, jflags = in.nextChar.toInt + if (innerIndex != 0 && outerIndex != 0 && nameIndex != 0) + innerClasses add InnerClassEntry(innerIndex, outerIndex, nameIndex, jflags) } case _ => in.skip(attrLen) @@ -1166,72 +1159,69 @@ abstract class ClassfileParser { def externalName = pool getClassName external def outerName = pool getClassName outer def originalName = pool getName name + def isStatic = ClassfileParser.this.isStatic(jflags) + def isModule = originalName.isTermName + def scope = if (isStatic) staticScope else instanceScope + def enclosing = if (isStatic) enclModule else enclClass + + // The name of the outer class, without its trailing $ if it has one. + private def strippedOuter = nme stripModuleSuffix outerName + private def isInner = innerClasses contains strippedOuter + private def enclClass = if (isInner) innerClasses innerSymbol strippedOuter else classNameToSymbol(strippedOuter) + private def enclModule = enclClass.companionModule + + private def staticWord = if (isStatic) "static " else "" + override def toString = s"$staticWord$originalName in $outerName ($externalName)" + } - override def toString = - originalName + " in " + outerName + "(" + externalName +")" + /** Return the Symbol of the top level class enclosing `name`, + * or the symbol of `name` itself if no enclosing classes are found. + */ + def topLevelClass(name: Name): Symbol = innerClasses getEntry name match { + case Some(entry) => topLevelClass(entry.outerName) + case _ => classNameToSymbol(name) } - object innerClasses extends scala.collection.mutable.HashMap[Name, InnerClassEntry] { - /** Return the Symbol of the top level class enclosing `name`, - * or 'name's symbol if no entry found for `name`. - */ - def topLevelClass(name: Name): Symbol = { - val tlName = if (isDefinedAt(name)) { - var entry = this(name) - while (isDefinedAt(entry.outerName)) - entry = this(entry.outerName) - entry.outerName - } else - name - classNameToSymbol(tlName) + /** Return the class symbol for the given name. It looks it up in its outer class. + * Forces all outer class symbols to be completed. + * + * If the given name is not an inner class, it returns the symbol found in `definitions`. + */ + object innerClasses { + private val inners = mutable.HashMap[Name, InnerClassEntry]() + + def contains(name: Name) = inners contains name + def getEntry(name: Name) = inners get name + def entries = inners.values + + def add(entry: InnerClassEntry): Unit = { + inners get entry.externalName foreach (existing => + debugwarn(s"Overwriting inner class entry! Was $existing, now $entry") + ) + inners(entry.externalName) = entry } - - /** Return the class symbol for `externalName`. It looks it up in its outer class. - * Forces all outer class symbols to be completed. - * - * If the given name is not an inner class, it returns the symbol found in `definitions`. - */ - def classSymbol(externalName: Name): Symbol = { - /** Return the symbol of `innerName`, having the given `externalName`. */ - def innerSymbol(externalName: Name, innerName: Name, static: Boolean): Symbol = { - def getMember(sym: Symbol, name: Name): Symbol = - if (static) - if (sym == clazz) staticScope.lookup(name) - else sym.companionModule.info.member(name) - else - if (sym == clazz) instanceScope.lookup(name) - else sym.info.member(name) - - innerClasses.get(externalName) match { - case Some(entry) => - val outerName = nme.stripModuleSuffix(entry.outerName) - val sym = classSymbol(outerName) - val s = - // if loading during initialization of `definitions` typerPhase is not yet set. - // in that case we simply load the member at the current phase - if (currentRun.typerPhase != null) - beforeTyper(getMember(sym, innerName.toTypeName)) - else - getMember(sym, innerName.toTypeName) - - assert(s ne NoSymbol, - "" + ((externalName, outerName, innerName, sym.fullLocationString)) + " / " + - " while parsing " + ((in.file, busy)) + - sym + "." + innerName + " linkedModule: " + sym.companionModule + sym.companionModule.info.members - ) - s - - case None => - classNameToSymbol(externalName) - } - } - - get(externalName) match { - case Some(entry) => - innerSymbol(entry.externalName, entry.originalName, isStatic(entry.jflags)) - case None => - classNameToSymbol(externalName) - } + def innerSymbol(externalName: Name): Symbol = this getEntry externalName match { + case Some(entry) => innerSymbol(entry) + case _ => NoSymbol + } + // if loading during initialization of `definitions` typerPhase is not yet set. + // in that case we simply load the member at the current phase + @inline private def enteringTyperIfPossible(body: => Symbol): Symbol = + if (currentRun.typerPhase eq null) body else beforeTyper(body) + + private def innerSymbol(entry: InnerClassEntry): Symbol = { + val name = entry.originalName.toTypeName + val enclosing = entry.enclosing + def getMember = ( + if (enclosing == clazz) entry.scope lookup name + else enclosing.info member name + ) + enteringTyperIfPossible(getMember) + /** There used to be an assertion that this result is not NoSymbol; changing it to an error + * revealed it had been going off all the time, but has been swallowed by a catch t: Throwable + * in Repository.scala. Since it has been accomplishing nothing except misleading anyone who + * thought it wasn't triggering, I removed it entirely. + */ } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 13c0d8993a..c304c18c4f 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -506,6 +506,13 @@ abstract class ICodeReader extends ClassfileParser { code.emit(UNBOX(toTypeKind(m.info.resultType))) else code.emit(CALL_METHOD(m, Static(false))) + case JVM.invokedynamic => + // TODO, this is just a place holder. A real implementation must parse the class constant entry + debuglog("Found JVM invokedynamic instructionm, inserting place holder ICode INVOKE_DYNAMIC.") + containsInvokeDynamic = true + val poolEntry = in.nextChar + in.skip(2) + code.emit(INVOKE_DYNAMIC(poolEntry)) case JVM.new_ => code.emit(NEW(REFERENCE(pool.getClassSymbol(in.nextChar)))) @@ -644,6 +651,7 @@ abstract class ICodeReader extends ClassfileParser { var containsDUPX = false var containsNEW = false var containsEHs = false + var containsInvokeDynamic = false def emit(i: Instruction) { instrs += ((pc, i)) @@ -662,6 +670,7 @@ abstract class ICodeReader extends ClassfileParser { val code = new Code(method) method.setCode(code) method.bytecodeHasEHs = containsEHs + method.bytecodeHasInvokeDynamic = containsInvokeDynamic var bb = code.startBlock def makeBasicBlocks: mutable.Map[Int, BasicBlock] = diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index f6ee7be511..970519ab7c 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -45,26 +45,24 @@ abstract class ExplicitOuter extends InfoTransform private def isInner(clazz: Symbol) = !clazz.isPackageClass && !clazz.outerClass.isStaticOwner - private def haveSameOuter(parent: Type, clazz: Symbol) = parent match { - case TypeRef(pre, sym, _) => - val owner = clazz.owner + private def haveSameOuter(parent: Type, clazz: Symbol) = { + val owner = clazz.owner + val parentSym = parent.typeSymbol - //println(s"have same outer $parent $clazz $sym ${sym.owner} $owner $pre") - - sym.isClass && owner.isClass && - (owner isSubClass sym.owner) && - owner.thisType =:= pre - - case _ => false + parentSym.isClass && owner.isClass && + (owner isSubClass parentSym.owner) && + owner.thisType =:= parent.prefix } /** Does given clazz define an outer field? */ def hasOuterField(clazz: Symbol) = { - val parents = clazz.info.parents + val parent = clazz.info.firstParent - isInner(clazz) && !clazz.isTrait && { - parents.isEmpty || !haveSameOuter(parents.head, clazz) - } + // space optimization: inherit the $outer pointer from the parent class if + // we know that it will point to the correct instance. + def canReuseParentOuterField = !parent.typeSymbol.isJavaDefined && haveSameOuter(parent, clazz) + + isInner(clazz) && !clazz.isTrait && !canReuseParentOuterField } private def outerField(clazz: Symbol): Symbol = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2458fc54e1..a98f20a971 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4461,6 +4461,12 @@ trait Typers extends Modes with Adaptations with Tags { treeCopy.New(tree, tpt1).setType(tp) } + def functionTypeWildcard(tree: Tree, arity: Int): Type = { + val tp = functionType(List.fill(arity)(WildcardType), WildcardType) + if (tp == NoType) MaxFunctionArityError(tree) + tp + } + def typedEta(expr1: Tree): Tree = expr1.tpe match { case TypeRef(_, ByNameParamClass, _) => val expr2 = Function(List(), expr1) setPos expr1.pos @@ -4472,7 +4478,7 @@ trait Typers extends Modes with Adaptations with Tags { typed1(expr2, mode, pt) case PolyType(_, MethodType(formals, _)) => if (isFunctionType(pt)) expr1 - else adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType)) + else adapt(expr1, mode, functionTypeWildcard(expr1, formals.length)) case MethodType(formals, _) => if (isFunctionType(pt)) expr1 else expr1 match { @@ -4491,7 +4497,7 @@ trait Typers extends Modes with Adaptations with Tags { val rhs = Apply(f, args) typed(rhs) case _ => - adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType)) + adapt(expr1, mode, functionTypeWildcard(expr1, formals.length)) } case ErrorType => expr1 diff --git a/src/library/scala/collection/parallel/package.scala b/src/library/scala/collection/parallel/package.scala index 83aa99ad11..988886b4ea 100644 --- a/src/library/scala/collection/parallel/package.scala +++ b/src/library/scala/collection/parallel/package.scala @@ -42,11 +42,8 @@ package object parallel { private[parallel] def outofbounds(idx: Int) = throw new IndexOutOfBoundsException(idx.toString) private[parallel] def getTaskSupport: TaskSupport = - if (scala.util.Properties.isJavaAtLeast("1.6")) { - val vendor = scala.util.Properties.javaVmVendor - if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple")) new ForkJoinTaskSupport - else new ThreadPoolTaskSupport - } else new ThreadPoolTaskSupport + if (scala.util.Properties.isJavaAtLeast("1.6")) new ForkJoinTaskSupport + else new ThreadPoolTaskSupport val defaultTaskSupport: TaskSupport = getTaskSupport diff --git a/src/reflect/scala/reflect/internal/ClassfileConstants.scala b/src/reflect/scala/reflect/internal/ClassfileConstants.scala index 7ccb661426..c198271fb1 100644 --- a/src/reflect/scala/reflect/internal/ClassfileConstants.scala +++ b/src/reflect/scala/reflect/internal/ClassfileConstants.scala @@ -72,6 +72,9 @@ object ClassfileConstants { final val CONSTANT_METHODREF = 10 final val CONSTANT_INTFMETHODREF = 11 final val CONSTANT_NAMEANDTYPE = 12 + final val CONSTANT_METHODHANDLE = 15 + final val CONSTANT_METHODTYPE = 16 + final val CONSTANT_INVOKEDYNAMIC = 18 // tags describing the type of a literal in attribute values final val BYTE_TAG = 'B' @@ -306,7 +309,7 @@ object ClassfileConstants { final val invokespecial = 0xb7 final val invokestatic = 0xb8 final val invokeinterface = 0xb9 - final val xxxunusedxxxx = 0xba + final val invokedynamic = 0xba final val new_ = 0xbb final val newarray = 0xbc diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 45c16b7302..7274eeafe0 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -2538,20 +2538,32 @@ trait Symbols extends api.Symbols { self: SymbolTable => } /** change name by appending $$<fully-qualified-name-of-class `base`> - * Do the same for any accessed symbols or setters/getters + * Do the same for any accessed symbols or setters/getters. + * If the accessor to be renamed is overriding a base symbol, enter + * a cloned symbol with the original name but without ACCESSOR flag. */ override def expandName(base: Symbol) { - if (!hasFlag(EXPANDEDNAME)) { - setFlag(EXPANDEDNAME) - if (hasAccessorFlag && !isDeferred) { - accessed.expandName(base) - } - else if (hasGetter) { - getter(owner).expandName(base) - setter(owner).expandName(base) - } - name = nme.expandedName(name.toTermName, base) + def expand(sym: Symbol) { + if ((sym eq NoSymbol) || (sym hasFlag EXPANDEDNAME)) () // skip + else sym setFlag EXPANDEDNAME setName nme.expandedName(sym.name.toTermName, base) + } + def cloneAndExpand(accessor: Symbol) { + val clone = accessor.cloneSymbol(accessor.owner, (accessor.flags | ARTIFACT) & ~ACCESSOR) + expand(accessor) + log(s"Expanded overriding accessor to $accessor, but cloned $clone to preserve override") + accessor.owner.info.decls enter clone + } + def expandAccessor(accessor: Symbol) { + if (accessor.isOverridingSymbol) cloneAndExpand(accessor) else expand(accessor) + } + if (hasAccessorFlag && !isDeferred) { + expand(accessed) + } + else if (hasGetter) { + expandAccessor(getter(owner)) + expandAccessor(setter(owner)) } + expand(this) } protected def doCookJavaRawInfo() { @@ -3223,6 +3235,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def companionModule = NoSymbol override def companionSymbol = NoSymbol override def isSubClass(that: Symbol) = false + override def isOverridingSymbol = false override def filter(cond: Symbol => Boolean) = this override def defString: String = toString override def locationString: String = "" diff --git a/test/debug/OBSOLETE b/test/debug/OBSOLETE new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/debug/OBSOLETE diff --git a/test/files/jvm/t7253.check b/test/files/jvm/t7253.check new file mode 100644 index 0000000000..43f53aba12 --- /dev/null +++ b/test/files/jvm/t7253.check @@ -0,0 +1 @@ +bytecode identical diff --git a/test/files/jvm/t7253/Base_1.scala b/test/files/jvm/t7253/Base_1.scala new file mode 100644 index 0000000000..a531ebb69d --- /dev/null +++ b/test/files/jvm/t7253/Base_1.scala @@ -0,0 +1,5 @@ +trait A { def f(): Int } +trait B1 extends A +abstract class B2 extends A +class B3 extends A { def f(): Int = 1 } +class B4 extends B3 diff --git a/test/files/jvm/t7253/JavaClient_1.java b/test/files/jvm/t7253/JavaClient_1.java new file mode 100644 index 0000000000..43475de2f5 --- /dev/null +++ b/test/files/jvm/t7253/JavaClient_1.java @@ -0,0 +1,9 @@ +public class JavaClient_1 { + int foo() { + ((A) null).f(); + ((B1) null).f(); + ((B2) null).f(); + ((B3) null).f(); + return ((B4) null).f(); + } +} diff --git a/test/files/jvm/t7253/ScalaClient_1.scala b/test/files/jvm/t7253/ScalaClient_1.scala new file mode 100644 index 0000000000..d244b326a8 --- /dev/null +++ b/test/files/jvm/t7253/ScalaClient_1.scala @@ -0,0 +1,9 @@ +class ScalaClient_1 { + def foo() = { + (null: A).f() + (null: B1).f() + (null: B2).f() + (null: B3).f() + (null: B4).f() + } +} diff --git a/test/files/jvm/t7253/test.scala b/test/files/jvm/t7253/test.scala new file mode 100644 index 0000000000..7fe08e8813 --- /dev/null +++ b/test/files/jvm/t7253/test.scala @@ -0,0 +1,28 @@ +import scala.tools.partest.BytecodeTest + +import scala.tools.nsc.util.JavaClassPath +import java.io.InputStream +import scala.tools.asm +import asm.ClassReader +import asm.tree.{ClassNode, InsnList} +import scala.collection.JavaConverters._ + +object Test extends BytecodeTest { + import instructions._ + + def show: Unit = { + val instrBaseSeqs = Seq("ScalaClient_1", "JavaClient_1") map (name => instructions.fromMethod(getMethod(loadClassNode(name), "foo"))) + val instrSeqs = instrBaseSeqs map (_ filter isInvoke) + cmpInstructions(instrSeqs(0), instrSeqs(1)) + } + + def cmpInstructions(isa: List[Instruction], isb: List[Instruction]) = { + if (isa == isb) println("bytecode identical") + else diffInstructions(isa, isb) + } + + def isInvoke(node: Instruction): Boolean = { + val opcode = node.opcode + (opcode == "INVOKEVIRTUAL") || (opcode == "INVOKEINTERFACE") + } +} diff --git a/test/files/neg/t7251.check b/test/files/neg/t7251.check new file mode 100644 index 0000000000..8df8984d63 --- /dev/null +++ b/test/files/neg/t7251.check @@ -0,0 +1,4 @@ +B_2.scala:5: error: object s.Outer$Triple$ is not a value + println( s.Outer$Triple$ ) + ^ +one error found diff --git a/test/files/neg/t7251/A_1.scala b/test/files/neg/t7251/A_1.scala new file mode 100644 index 0000000000..d05373ed28 --- /dev/null +++ b/test/files/neg/t7251/A_1.scala @@ -0,0 +1,10 @@ +package s + +object Outer { + type Triple[+A, +B, +C] = Tuple3[A, B, C] + object Triple { + def apply[A, B, C](x: A, y: B, z: C) = Tuple3(x, y, z) + def unapply[A, B, C](x: Tuple3[A, B, C]): Option[Tuple3[A, B, C]] = Some(x) + } +} + diff --git a/test/files/neg/t7251/B_2.scala b/test/files/neg/t7251/B_2.scala new file mode 100644 index 0000000000..eb59b30902 --- /dev/null +++ b/test/files/neg/t7251/B_2.scala @@ -0,0 +1,7 @@ +package s + +object Test { + def main(args: Array[String]): Unit = { + println( s.Outer$Triple$ ) + } +} diff --git a/test/files/neg/t7299.check b/test/files/neg/t7299.check new file mode 100644 index 0000000000..74340c4841 --- /dev/null +++ b/test/files/neg/t7299.check @@ -0,0 +1,7 @@ +t7299.scala:4: error: implementation restricts functions to 22 parameters + val eta1 = f _ + ^ +t7299.scala:5: error: implementation restricts functions to 22 parameters + val eta2 = g[Any] _ + ^ +two errors found diff --git a/test/files/neg/t7299.scala b/test/files/neg/t7299.scala new file mode 100644 index 0000000000..f3aae5ce5d --- /dev/null +++ b/test/files/neg/t7299.scala @@ -0,0 +1,6 @@ +object Test { + def f(a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, a8: Int, a9: Int, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, a15: Int, a16: Int, a17: Int, a18: Int, a19: Int, a20: Int, a21: Int, a22: Int, a23: Int) = 0 + def g[A](a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, a8: Int, a9: Int, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, a15: Int, a16: Int, a17: Int, a18: Int, a19: Int, a20: Int, a21: Int, a22: Int, a23: Int) = 0 + val eta1 = f _ + val eta2 = g[Any] _ +} diff --git a/test/files/pos/t6210.flags b/test/files/pos/t6210.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t6210.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t6210.scala b/test/files/pos/t6210.scala new file mode 100644 index 0000000000..1ce8493872 --- /dev/null +++ b/test/files/pos/t6210.scala @@ -0,0 +1,21 @@ +abstract sealed trait AST +abstract sealed trait AExpr extends AST +case class AAssign(name: String, v: AExpr) extends AExpr +case class AConstBool(v: Boolean) extends AExpr + +trait Ty {} +case class TInt() extends Ty +case class TBool() extends Ty + +object Foo { + def checkExpr(ast: AExpr): Ty = { + var astTy:Ty = ast match { + case AAssign(nm: String, v:AExpr) => TBool() + + case AConstBool(v: Boolean) => TBool() + + case _ => throw new Exception(s"Unhandled case check(ast: ${ast.getClass})") + } + astTy + } +} diff --git a/test/files/run/classfile-format-51.scala b/test/files/run/classfile-format-51.scala new file mode 100644 index 0000000000..9b1e612f4f --- /dev/null +++ b/test/files/run/classfile-format-51.scala @@ -0,0 +1,126 @@ +import java.io.{File, FileOutputStream} + +import scala.tools.nsc.settings.ScalaVersion +import scala.tools.partest._ +import scala.tools.asm +import asm.{AnnotationVisitor, ClassWriter, FieldVisitor, Handle, MethodVisitor, Opcodes} +import Opcodes._ + +// This test ensures that we can read JDK 7 (classfile format 51) files, including those +// with invokeDynamic instructions and associated constant pool entries +// to do that it first uses ASM to generate a class called DynamicInvoker. Then +// it runs a normal compile on the source in the 'code' field that refers to +// DynamicInvoker. Any failure will be dumped to std out. +// +// By it's nature the test can only work on JDK 7+ because under JDK 6 some of the +// classes referred to by DynamicInvoker won't be available and DynamicInvoker won't +// verify. So the test includes a version check that short-circuites the whole test +// on JDK 6 +object Test extends DirectTest { + override def extraSettings: String = "-optimise -usejavacp -d " + testOutput.path + " -cp " + testOutput.path + + def generateClass() { + val invokerClassName = "DynamicInvoker" + val bootstrapMethodName = "bootstrap" + val bootStrapMethodType = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;" + val targetMethodName = "target" + val targetMethodType = "()Ljava/lang/String;" + + val cw = new ClassWriter(0) + cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, invokerClassName, null, "java/lang/Object", null) + + val constructor = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null) + constructor.visitCode() + constructor.visitVarInsn(ALOAD, 0) + constructor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V") + constructor.visitInsn(RETURN) + constructor.visitMaxs(1, 1) + constructor.visitEnd() + + val target = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, targetMethodName, targetMethodType, null, null) + target.visitCode() + target.visitLdcInsn("hello") + target.visitInsn(ARETURN) + target.visitMaxs(1, 1) + target.visitEnd() + + val bootstrap = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, bootstrapMethodName, bootStrapMethodType, null, null) + bootstrap.visitCode() +// val lookup = MethodHandles.lookup(); + bootstrap.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;") + bootstrap.visitVarInsn(ASTORE, 3) // lookup + +// val clazz = lookup.lookupClass(); + bootstrap.visitVarInsn(ALOAD, 3) // lookup + bootstrap.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "lookupClass", "()Ljava/lang/Class;") + bootstrap.visitVarInsn(ASTORE, 4) // clazz + +// val methodType = MethodType.fromMethodDescriptorString("()Ljava/lang/String, clazz.getClassLoader()") + bootstrap.visitLdcInsn("()Ljava/lang/String;") + bootstrap.visitVarInsn(ALOAD, 4) // CLAZZ + bootstrap.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;") + bootstrap.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodType", "fromMethodDescriptorString", "(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/invoke/MethodType;") + bootstrap.visitVarInsn(ASTORE, 5) // methodType + +// val methodHandle = lookup.findStatic(thisClass, "target", methodType) + bootstrap.visitVarInsn(ALOAD, 3) // lookup + bootstrap.visitVarInsn(ALOAD, 4) // clazz + bootstrap.visitLdcInsn("target") + bootstrap.visitVarInsn(ALOAD, 5) // methodType + bootstrap.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findStatic", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;") + bootstrap.visitVarInsn(ASTORE, 6) // methodHandle + +// new ConstantCallSite(methodHandle) + bootstrap.visitTypeInsn(NEW, "java/lang/invoke/ConstantCallSite") + bootstrap.visitInsn(DUP) + bootstrap.visitVarInsn(ALOAD, 6) // methodHandle + bootstrap.visitMethodInsn(INVOKESPECIAL, "java/lang/invoke/ConstantCallSite", "<init>", "(Ljava/lang/invoke/MethodHandle;)V") + bootstrap.visitInsn(ARETURN) + bootstrap.visitMaxs(4,7) + bootstrap.visitEnd() + + val test = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "test", s"()Ljava/lang/String;", null, null) + test.visitCode() + val bootstrapHandle = new Handle(H_INVOKESTATIC, invokerClassName, bootstrapMethodName, bootStrapMethodType) + test.visitInvokeDynamicInsn("invoke", targetMethodType, bootstrapHandle) + test.visitInsn(ARETURN) + test.visitMaxs(1, 1) + test.visitEnd() + + cw.visitEnd() + val bytes = cw.toByteArray() + + val fos = new FileOutputStream(new File(s"${testOutput.path}/$invokerClassName.class")) + try + fos write bytes + finally + fos.close() + + } + + def code = +""" +object Driver { + val invoker = new DynamicInvoker() + println(invoker.test()) +} +""" + + override def show(): Unit = { + // redirect err to out, for logging + val prevErr = System.err + System.setErr(System.out) + try { + // this test is only valid under JDK 1.7+ + // cheat a little by using 'ScalaVersion' because it can parse java versions just as well + val requiredJavaVersion = ScalaVersion("1.7") + val executingJavaVersion = ScalaVersion(System.getProperty("java.specification.version")) + if (executingJavaVersion >= requiredJavaVersion) { + generateClass() + compile() + } + } + finally + System.setErr(prevErr) + } +} diff --git a/test/files/run/outertest.scala b/test/files/run/outertest.scala index 3cc96afa5b..fa0443f669 100644 --- a/test/files/run/outertest.scala +++ b/test/files/run/outertest.scala @@ -1,26 +1,57 @@ // A test for the case where the outer field of class B#J should be eliminated. -// You can verify this by running a javap on B.J + +import reflect.ClassTag + abstract class A { + abstract class I - abstract class I { + val foo = this +} +class B extends A { + class J extends I { + val bar = foo } - val foo = "foo" + type II = I + class K extends II { + val bar = foo + } + class L extends (I @annotation.tailrec) { + val bar = foo + } } -class B extends A { - class J extends I { +class C extends A { + val c: C = this + + class M extends c.I { val bar = foo } - } -object Test extends App { +object Test extends App { val b = new B - assert((new b.J).bar == b.foo) + val c0 = new C + val c = new { override val c = c0 } with C + + assert((new b.J).bar eq b) + assert((new b.K).bar eq b) + assert((new b.L).bar eq b) + assert((new c.M).bar eq c) + + def checkOuterFields[C: ClassTag](expected: Int) { + val cls = implicitly[ClassTag[C]].runtimeClass + val outerFields = cls.getDeclaredFields().filter(_.getName.contains("$outer")) + assert(outerFields.size == expected, outerFields.map(_.getName)) + } + checkOuterFields[A#I](1) // the base class must have the $outer pointer + checkOuterFields[B#J](0) // reuse parent class' $outer pointer + checkOuterFields[B#K](0) // ... through an alias + checkOuterFields[B#L](0) // ... through the annotated type + checkOuterFields[C#M](1) // different prefix, can't share. } diff --git a/test/files/run/t6387.check b/test/files/run/t6387.check new file mode 100644 index 0000000000..83b33d238d --- /dev/null +++ b/test/files/run/t6387.check @@ -0,0 +1 @@ +1000 diff --git a/test/files/run/t6387.scala b/test/files/run/t6387.scala new file mode 100644 index 0000000000..bbebb5f511 --- /dev/null +++ b/test/files/run/t6387.scala @@ -0,0 +1,16 @@ +trait A { + def foo: Long +} + +object Test { + def a(): A = new A { + var foo: Long = 1000L + + val test = () => { + foo = 28 + } + } + def main(args: Array[String]) { + println(a().foo) + } +} diff --git a/test/files/run/t7246.check b/test/files/run/t7246.check new file mode 100755 index 0000000000..ce01362503 --- /dev/null +++ b/test/files/run/t7246.check @@ -0,0 +1 @@ +hello diff --git a/test/files/run/t7246/Outer.java b/test/files/run/t7246/Outer.java new file mode 100755 index 0000000000..163276fb3b --- /dev/null +++ b/test/files/run/t7246/Outer.java @@ -0,0 +1,4 @@ +public class Outer { + public class Inner { + } +}
\ No newline at end of file diff --git a/test/files/run/t7246/Test.scala b/test/files/run/t7246/Test.scala new file mode 100755 index 0000000000..9f23ca8f3a --- /dev/null +++ b/test/files/run/t7246/Test.scala @@ -0,0 +1,16 @@ +object Test extends App { + + val so = new SubOuter + val si = new so.SubInner + println(si.bar) +} + +class SubOuter extends Outer { + + val foo = "hello" + + class SubInner extends Inner { + def bar = foo + } + +}
\ No newline at end of file diff --git a/test/files/run/t7246b.check b/test/files/run/t7246b.check new file mode 100755 index 0000000000..5073bd8617 --- /dev/null +++ b/test/files/run/t7246b.check @@ -0,0 +1,2 @@ +base +sub diff --git a/test/files/run/t7246b/Base.scala b/test/files/run/t7246b/Base.scala new file mode 100755 index 0000000000..4e71d3313d --- /dev/null +++ b/test/files/run/t7246b/Base.scala @@ -0,0 +1,7 @@ +class Base { + val baseOuter = "base" + + class BaseInner { + val baseInner = baseOuter + } +} diff --git a/test/files/run/t7246b/Outer.java b/test/files/run/t7246b/Outer.java new file mode 100755 index 0000000000..53a79316ef --- /dev/null +++ b/test/files/run/t7246b/Outer.java @@ -0,0 +1,4 @@ +public class Outer extends Base { + public class Inner extends BaseInner { + } +}
\ No newline at end of file diff --git a/test/files/run/t7246b/Test.scala b/test/files/run/t7246b/Test.scala new file mode 100755 index 0000000000..f0982ea8d0 --- /dev/null +++ b/test/files/run/t7246b/Test.scala @@ -0,0 +1,14 @@ +object Test extends App { + + val so = new SubOuter + val si = new so.SubInner + println(si.baseInner) + println(si.subInner) +} + +class SubOuter extends Outer { + val subOuter = "sub" + class SubInner extends Inner { + def subInner = subOuter + } +} diff --git a/test/scaladoc/run/SI-6580.check b/test/scaladoc/run/SI-6580.check new file mode 100644 index 0000000000..2fb6ec3258 --- /dev/null +++ b/test/scaladoc/run/SI-6580.check @@ -0,0 +1,11 @@ +Chain(List(Chain(List(Text(Here z(1) is defined as follows:), Text( +), HtmlTag(<br>), Text( +), Text( ), HtmlTag(<img src='http://example.com/fig1.png'>), Text( +), HtmlTag(<br>), Text( +), Text(plus z(1) times), Text( +), HtmlTag(<br>), Text( +), Text( ), HtmlTag(<img src='http://example.com/fig2.png'>), Text( +), HtmlTag(<br>), Text( +), Text(equals QL of something +))))) +Done. diff --git a/test/scaladoc/run/SI-6580.scala b/test/scaladoc/run/SI-6580.scala new file mode 100644 index 0000000000..c544138f44 --- /dev/null +++ b/test/scaladoc/run/SI-6580.scala @@ -0,0 +1,32 @@ +import scala.tools.nsc.doc +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.html.page.{Index, ReferenceIndex} +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + override def scaladocSettings = "" + override def code = """ + + object Test { + /** Here z(1) is defined as follows: + * <br> + * <img src='http://example.com/fig1.png'> + * <br> + * plus z(1) times + * <br> + * <img src='http://example.com/fig2.png'> + * <br> + * equals QL of something + */ + def f = 1 + } + + """ + + def testModel(rootPackage: Package) { + import access._ + + val f = rootPackage._object("Test")._method("f") + println(f.comment.get.short) + } +} diff --git a/tools/stability-test.sh b/tools/stability-test.sh new file mode 100755 index 0000000000..f017ac0842 --- /dev/null +++ b/tools/stability-test.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# + +declare failed + +echo "Comparing build/quick/classes and build/strap/classes" +for dir in library reflect compiler; do + # feel free to replace by a more elegant approach -- don't know how + if diff -rw -x '*.css' \ + -x '*.custom' \ + -x '*.gif' \ + -x '*.js' \ + -x '*.layout' \ + -x '*.png' \ + -x '*.properties' \ + -x '*.tmpl' \ + -x '*.tooltip' \ + -x '*.txt' \ + -x '*.xml' \ + build/{quick,strap}/classes/$dir + then + classes=$(find build/quick/classes/$dir -name '*.class' | wc -l) + printf "%8s: %5d classfiles verified identical\n" $dir $classes + else + failed=true + fi +done + +[[ -z $failed ]] || exit 127 |