diff options
126 files changed, 3693 insertions, 1052 deletions
diff --git a/build.number b/build.number new file mode 100644 index 0000000000..b5c4e61d13 --- /dev/null +++ b/build.number @@ -0,0 +1,9 @@ +#Tue Sep 11 19:21:09 CEST 2007 +version.major=2 +version.minor=10 +version.patch=0 +# This is the -N part of a version. if it's 0, it's dropped from maven versions. +version.bnum=0 + +# Note: To build a release run ant with -Dbuild.release=true +# To build an RC, run ant with -Dmaven.version.suffix=-RCN @@ -166,6 +166,8 @@ PROPERTIES <!-- Loads custom properties definitions --> <property file="${basedir}/build.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=""/> @@ -236,7 +238,30 @@ INITIALISATION </touch> </target> - <target name="init" depends="init.jars"> + <!-- 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"> + <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.build.suffix.done" depends="init.build.release, init.build.patch.release"/> + + <target name="init" depends="init.jars, init.build.suffix.done"> <!-- 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.) @@ -255,22 +280,29 @@ INITIALISATION <condition property="os.win"> <os family="windows"/> </condition> - - <!-- Generating version string --> - <exec osfamily="unix" executable="tools/get-scala-revision" outputproperty="version.number" failifexecutionfails="false" /> - <exec osfamily="windows" executable="tools/get-scala-revision.bat" outputproperty="version.number" failifexecutionfails="false" /> + + <exec osfamily="unix" executable="tools/get-scala-commit-sha" outputproperty="git.commit.sha" failifexecutionfails="false" /> + <exec osfamily="windows" executable="tools/get-scala-commit-sha.bat" outputproperty="git.commit.sha" failifexecutionfails="false" /> + <exec osfamily="unix" executable="tools/get-scala-commit-date" outputproperty="git.commit.date" failifexecutionfails="false" /> + <exec osfamily="windows" executable="tools/get-scala-commit-date.bat" outputproperty="git.commit.date" failifexecutionfails="false" /> + <!-- 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="version.number" + value="${version.major}.${version.minor}.${version.patch}${version.suffix}-${git.commit.date}-${git.commit.sha}"/> + <property + name="osgi.version.number" + value="${version.major}.${version.minor}.${version.patch}.v${git.commit.date}${version.suffix}-${git.commit.sha}"/> <!-- some default in case something went wrong getting the revision --> <property name="version.number" value="-unknown-"/> <property name="init.avail" value="yes"/> - <!-- And print-out what we are building --> - <echo message=" build time: ${time.human}" /> - <echo message=" java version: ${java.vm.name} ${java.version}" /> - <echo message=" java args: ${env.ANT_OPTS} ${jvm.opts}" /> - <echo message=" javac args: ${javac.args}" /> - <echo message=" scalac args: ${scalac.args}" /> - <echo message=" build number: ${version.number}" /> - <!-- Local libs (developer use.) --> <mkdir dir="${lib-extra.dir}"/> @@ -293,7 +325,19 @@ INITIALISATION <path refid="lib.extra"/> </path> - <!-- Define tasks that can be run with Starr --> + <!-- And print-out what we are building --> + <echo message=" build time: ${time.human}" /> + <echo message=" java version: ${java.vm.name} ${java.version}" /> + <echo message=" java args: ${env.ANT_OPTS} ${jvm.opts}" /> + <echo message=" javac args: ${javac.args}" /> + <echo message=" scalac args: ${scalac.args}" /> + <echo message=" git date: ${git.commit.date}" /> + <echo message=" git hash: ${git.commit.sha}" /> + <echo message=" maven version: ${maven.version.number}"/> + <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="${comp.starr.jar}"/> @@ -358,6 +402,8 @@ LOCAL REFERENCE BUILD (LOCKER) </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"> @@ -397,6 +443,8 @@ LOCAL REFERENCE BUILD (LOCKER) </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"> @@ -563,9 +611,9 @@ QUICK BUILD (QUICK) <srcfiles dir="${src.dir}"> <include name="library/**"/> <include name="dbc/**"/> - <include name="actors/**"/> <include name="continuations/**"/> <include name="swing/**"/> + <include name="actors/**"/> </srcfiles> </uptodate> </target> @@ -628,6 +676,8 @@ QUICK BUILD (QUICK) </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"> @@ -687,6 +737,8 @@ QUICK BUILD (QUICK) </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"> @@ -940,6 +992,7 @@ PACKED QUICK BUILD (PACK) <fileset dir="${build-quick.dir}/classes/library"> <exclude name="scala/dbc/**"/> <exclude name="scala/swing/**"/> + <exclude name="scala/actors/**"/> </fileset> <zipfileset dirmode="755" filemode="644" src="${forkjoin.jar}"/> </jar> @@ -953,6 +1006,11 @@ PACKED QUICK BUILD (PACK) <include name="scala/swing/**"/> </fileset> </jar> + <jar destfile="${build-pack.dir}/lib/scala-actors.jar"> + <fileset dir="${build-quick.dir}/classes/library"> + <include name="scala/actors/**"/> + </fileset> + </jar> </target> <target name="pack.pre-comp" depends="pack.lib"> @@ -1082,6 +1140,7 @@ PACKED QUICK BUILD (PACK) <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"/> @@ -1105,8 +1164,8 @@ BOOTSTRAPPING BUILD (STRAP) <srcfiles dir="${src.dir}"> <include name="library/**"/> <include name="dbc/**"/> - <include name="actors/**"/> <include name="swing/**"/> + <include name="actors/**"/> </srcfiles> </uptodate> </target> @@ -1169,6 +1228,8 @@ BOOTSTRAPPING BUILD (STRAP) </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"> @@ -1208,6 +1269,8 @@ BOOTSTRAPPING BUILD (STRAP) </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"> @@ -1530,8 +1593,8 @@ DOCUMENTATION <source-includes> <include name="library/**"/> <include name="dbc/**"/> - <include name="actors/**"/> <include name="swing/**"/> + <include name="actors/**"/> </source-includes> </doc-uptodate-check> </target> @@ -1549,7 +1612,7 @@ DOCUMENTATION sourcepath="${src.dir}" classpathref="pack.classpath" addparams="${scalac.args.all}" - docRootContent="${src.dir}/library/rootdoc.txt"> + docRootContent="${src.dir}/library/rootdoc.txt"> <src> <files includes="${src.dir}/actors"/> <files includes="${src.dir}/library/scala"/> @@ -1908,7 +1971,6 @@ DISTRIBUTION <mkdir dir="${dist.dir}/src"/> <jar destfile="${dist.dir}/src/scala-library-src.jar"> <fileset dir="${src.dir}/library"/> - <fileset dir="${src.dir}/actors"/> <fileset dir="${src.dir}/continuations/library"/> </jar> <jar destfile="${dist.dir}/src/scala-dbc-src.jar"> @@ -1920,6 +1982,9 @@ DISTRIBUTION <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> @@ -1996,8 +2061,8 @@ STABLE REFERENCE (STARR) <target name="starr.src" depends="starr.comp"> <jar destfile="${basedir}/lib/scala-library-src.jar"> <fileset dir="${basedir}/src/library"/> - <fileset dir="${basedir}/src/actors"/> <fileset dir="${basedir}/src/swing"/> + <fileset dir="${basedir}/src/actors"/> <fileset dir="${basedir}/src/dbc"/> </jar> </target> @@ -2077,12 +2142,6 @@ FORWARDED TARGETS FOR NIGHTLY BUILDS <ant antfile="${src.dir}/build/pack.xml" target="pack-all.done" inheritall="yes" inheritrefs="yes"/> </target> - <target name="nightly.checkinit"> - <antcall target="nightly-nopt"> - <param name="scalac.args.optimise" value="-Xcheckinit"/> - </antcall> - </target> - <target name="nightly.checkall"> <antcall target="nightly-nopt"> <param name="partest.scalacopts" value="-Ycheck:all"/> diff --git a/src/build/maven/maven-deploy.xml b/src/build/maven/maven-deploy.xml index 2e490163e0..7f8343a84e 100644 --- a/src/build/maven/maven-deploy.xml +++ b/src/build/maven/maven-deploy.xml @@ -16,10 +16,15 @@ <property name="local.release.repository" value="${user.home}/.m2/repository" /> <property name="repository.credentials.id" value="sonatype-nexus" /> <property name="settings.file" value="${user.home}/.m2/settings.xml" /> - + <condition property="version.is.snapshot"> + <contains string="${maven.version.number}" substring="-SNAPSHOT"/> + </condition> + <echo>Using server[${repository.credentials.id}] for maven repository credentials. Please make sure that your ~/.m2/settings.xml has the needed username/password for this server id </echo> + + </target> <target name="init.maven" depends="init.properties"> @@ -106,11 +111,12 @@ <deploy-local name="scala-library" version="@{version}" repository="@{repository}" /> <deploy-local name="scala-compiler" version="@{version}" repository="@{repository}" /> <deploy-local-plugin name="continuations" version="@{version}" repository="@{repository}"/> + <deploy-local name="scala-actors" version="@{version}" repository="@{repository}" /> <deploy-local name="scala-dbc" version="@{version}" repository="@{repository}" /> <deploy-local name="scala-swing" version="@{version}" repository="@{repository}"/> - <deploy-local name="scalap" version="@{version}" repository="@{repository}"/> - <deploy-local name="scala-partest" version="@{version}" repository="@{repository}"/> - <deploy-local name="jline" version="@{version}" repository="@{repository}"/> + <deploy-local name="scalap" version="@{version}" repository="@{repository}"/> + <deploy-local name="scala-partest" version="@{version}" repository="@{repository}"/> + <deploy-local name="jline" version="@{version}" repository="@{repository}"/> </sequential> </macrodef> </target> @@ -163,12 +169,13 @@ <artifact:attach type="jar" file="scala-library/scala-library-docs.jar" classifier="javadoc" /> </extra-attachments> </deploy-remote> - <deploy-remote name="jline" version="@{version}" repository="@{repository}"/> + <deploy-remote name="jline" version="@{version}" repository="@{repository}"/> <deploy-remote name="scala-compiler" version="@{version}" repository="@{repository}" /> <deploy-remote name="scala-dbc" version="@{version}" repository="@{repository}" /> <deploy-remote name="scala-swing" version="@{version}" repository="@{repository}"/> - <deploy-remote name="scalap" version="@{version}" repository="@{repository}"/> - <deploy-remote name="scala-partest" version="@{version}" repository="@{repository}"/> + <deploy-remote name="scala-actors" version="@{version}" repository="@{repository}"/> + <deploy-remote name="scalap" version="@{version}" repository="@{repository}"/> + <deploy-remote name="scala-partest" version="@{version}" repository="@{repository}"/> <deploy-remote-plugin name="continuations" version="@{version}" repository="@{repository}"/> </sequential> </macrodef> @@ -229,40 +236,44 @@ <attribute name="version" /> <sequential> <deploy-remote-plugin-signed name="continuations" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scala-library" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="jline" version="@{version}" repository="@{repository}"/> + <deploy-remote-signed name="scala-library" version="@{version}" repository="@{repository}"/> + <deploy-remote-signed name="jline" version="@{version}" repository="@{repository}"/> <deploy-remote-signed name="scala-compiler" version="@{version}" repository="@{repository}" /> <deploy-remote-signed name="scala-dbc" version="@{version}" repository="@{repository}" /> <deploy-remote-signed name="scala-swing" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scalap" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scala-partest" version="@{version}" repository="@{repository}"/> + <deploy-remote-signed name="scala-actors" version="@{version}" repository="@{repository}"/> + <deploy-remote-signed name="scalap" version="@{version}" repository="@{repository}"/> + <deploy-remote-signed name="scala-partest" version="@{version}" repository="@{repository}"/> </sequential> </macrodef> </target> <!-- Local Targets --> - <target name="deploy.snapshot.local" depends="deploy.local.init" description="Deploys the bundled snapshot of the Scala Lanaguage to a local maven repository"> - <deploy-local-all version="${maven.snapshot.version.number}" repository="${local.snapshot.repository}" /> + <target name="deploy.snapshot.local" depends="deploy.local.init" if="version.is.snapshot" description="Deploys the bundled snapshot of the Scala Lanaguage to a local maven repository"> + <deploy-local-all version="${maven.version.number}" repository="${local.snapshot.repository}" /> </target> - <target name="deploy.release.local" depends="deploy.local.init" description="Deploys the bundled files as a release into the local Maven repository"> - <deploy-local-all version="${version.number}" repository="${local.release.repository}" /> + <target name="deploy.release.local" depends="deploy.local.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the local Maven repository"> + <deploy-local-all version="${maven.version.number}" repository="${local.release.repository}" /> </target> + <target name="deploy.local" depends="deploy.snapshot.local, deploy.release.local" description="Deploys the bundle files to the local maven repo."/> - <!-- Remote Targets --> - <target name="deploy.signed.snapshot" depends="deploy.remote.init" description="Deploys the bundled files as a snapshot into the desired remote Maven repository"> - <deploy-remote-signed-all version="${maven.snapshot.version.number}" repository="${remote.snapshot.repository}" /> + <!-- Remote Signed Targets --> + <target name="deploy.signed.snapshot" depends="deploy.remote.init" if="version.is.snapshot" description="Deploys the bundled files as a snapshot into the desired remote Maven repository"> + <deploy-remote-signed-all version="${maven.version.number}" repository="${remote.snapshot.repository}" /> </target> - <target name="deploy.signed.release" depends="deploy.remote.init" description="Deploys the bundled files as a release into the desired remote Maven repository"> - <deploy-remote-signed-all version="${version.number}" repository="${remote.release.repository}" /> + <target name="deploy.signed.release" depends="deploy.remote.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the desired remote Maven repository"> + <deploy-remote-signed-all version="${maven.version.number}" repository="${remote.release.repository}" /> </target> - - <target name="deploy.snapshot" depends="deploy.remote.init" description="Deploys the bundled files as a snapshot into the desired remote Maven repository"> - <deploy-remote-all version="${maven.snapshot.version.number}" repository="${remote.snapshot.repository}" /> + <target name="deploy.signed" depends="deploy.signed.release, deploy.signed.snapshot" description="Deploys signed bundles to remote repo"/> + <!-- Remote unsigned targets --> + <target name="deploy.snapshot" depends="deploy.remote.init" if="version.is.snapshot" description="Deploys the bundled files as a snapshot into the desired remote Maven repository"> + <deploy-remote-all version="${maven.version.number}" repository="${remote.snapshot.repository}" /> </target> - <target name="deploy.release" depends="deploy.remote.init" description="Deploys the bundled files as a release into the desired remote Maven repository"> - <deploy-remote-all version="${version.number}" repository="${remote.release.repository}" /> + <target name="deploy.release" depends="deploy.remote.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the desired remote Maven repository"> + <deploy-remote-all version="${maven.version.number}" repository="${remote.release.repository}" /> </target> + <target name="deploy" depends="deploy.snapshot, deploy.release" description="Deploys unsigned artifacts to the maven repo."/> </project> diff --git a/src/build/maven/scala-actors-pom.xml b/src/build/maven/scala-actors-pom.xml new file mode 100644 index 0000000000..12bae2a23d --- /dev/null +++ b/src/build/maven/scala-actors-pom.xml @@ -0,0 +1,62 @@ +<project + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.scala-lang</groupId> + <artifactId>scala-actors</artifactId> + <packaging>jar</packaging> + <version>@VERSION@</version> + <name>Scala Actors library</name> + <description>Deprecated Actors Library for Scala</description> + <url>http://www.scala-lang.org/</url> + <inceptionYear>2006</inceptionYear> + <organization> + <name>LAMP/EPFL</name> + <url>http://lamp.epfl.ch/</url> + </organization> + <licenses> + <license> + <name>BSD-like</name> + <url>http://www.scala-lang.org/downloads/license.html + </url> + <distribution>repo</distribution> + </license> + </licenses> + <scm> + <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection> + <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url> + </scm> + <issueManagement> + <system>trac</system> + <url>http://lampsvn.epfl.ch/trac/scala + </url> + </issueManagement> + <dependencies> + <dependency> + <groupId>org.scala-lang</groupId> + <artifactId>scala-library</artifactId> + <version>@VERSION@</version> + </dependency> + </dependencies> + <distributionManagement> + <repository> + <id>scala-tools.org</id> + <url>@RELEASE_REPOSITORY@</url> + </repository> + <snapshotRepository> + <id>scala-tools.org</id> + <url>@SNAPSHOT_REPOSITORY@</url> + <uniqueVersion>false</uniqueVersion> + </snapshotRepository> + </distributionManagement> + <developers> + <developer> + <id>lamp</id> + <name>EPFL LAMP</name> + </developer> + <developer> + <id>Typesafe</id> + <name>Typesafe, Inc.</name> + </developer> + </developers> +</project> diff --git a/src/build/pack.xml b/src/build/pack.xml index 1b0cf19151..c12cfa44bf 100644 --- a/src/build/pack.xml +++ b/src/build/pack.xml @@ -114,8 +114,8 @@ MAIN DISTRIBUTION SBAZ version="${version.number}" desc="The Scala library. This is the minimal requirement to run any Scala program." link="${sbaz.universe}/scala-library-${version.number}.sbp"> - <libset dir="${dist.dir}/lib" includes="scala-library.jar,scala-dbc.jar,scala-swing.jar"/> - <srcset dir="${dist.dir}/src" includes="scala-library-src.jar,scala-dbc-src.jar,scala-swing-src.jar"/> + <libset dir="${dist.dir}/lib" includes="scala-library.jar,scala-dbc.jar,scala-swing.jar,scala-actors.jar"/> + <srcset dir="${dist.dir}/src" includes="scala-library-src.jar,scala-dbc-src.jar,scala-swing-src.jar,scala-actors-src.jar"/> <looseset destination="doc"> <fileset dir="${dist.dir}/doc" includes="LICENSE,README"/> </looseset> @@ -228,6 +228,7 @@ MAIN DISTRIBUTION SBAZ <mvn-copy-lib mvn.artifact.name="scala-compiler"/> <mvn-copy-lib mvn.artifact.name="scala-dbc"/> <mvn-copy-lib mvn.artifact.name="scala-swing"/> + <mvn-copy-lib mvn.artifact.name="scala-actors"/> <mvn-copy-lib mvn.artifact.name="scala-partest"/> <mvn-copy-lib mvn.artifact.name="scalap"/> </target> @@ -290,11 +291,13 @@ MAIN DISTRIBUTION SBAZ basedir="${build-docs.dir}/continuations-plugin"> <include name="**/*"/> </jar> - <!-- TODO - Scala swing, dbc should maybe have thier own jar, but creating it is SLOW. --> + <!-- TODO - Scala swing, dbc and actors should maybe have thier own jar, but creating it is SLOW. --> <copy tofile="${dists.dir}/maven/${version.number}/scala-swing/scala-swing-docs.jar" file="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar"/> <copy tofile="${dists.dir}/maven/${version.number}/scala-dbc/scala-dbc-docs.jar" file="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar"/> + <copy tofile="${dists.dir}/maven/${version.number}/scala-actors/scala-actors-docs.jar" + file="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar"/> </target> <target name="pack-maven.latest.unix" depends="pack-maven.docs" unless="os.win"> @@ -315,8 +318,6 @@ MAIN DISTRIBUTION SBAZ <copy tofile="${dists.dir}/maven/${version.number}/build.xml" file="${src.dir}/build/maven/maven-deploy.xml"/> <!-- export properties for use when deploying --> - <property name="maven.snapshot.version.number" - value="${version.major}.${version.minor}.${version.patch}-SNAPSHOT"/> <echoproperties destfile="${dists.dir}/maven/${version.number}/build.properties"/> </target> diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 1d53b83b75..bd823c3128 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -904,6 +904,20 @@ trait Definitions extends reflect.api.StandardDefinitions { def termMember(owner: Symbol, name: String): Symbol = owner.info.member(newTermName(name)) def typeMember(owner: Symbol, name: String): Symbol = owner.info.member(newTypeName(name)) + def findMemberFromRoot(fullName: Name): Symbol = { + val segs = nme.segments(fullName.toString, fullName.isTermName) + if (segs.isEmpty) NoSymbol + else findNamedMember(segs.tail, definitions.RootClass.info member segs.head) + } + def findNamedMember(fullName: Name, root: Symbol): Symbol = { + val segs = nme.segments(fullName.toString, fullName.isTermName) + if (segs.isEmpty || segs.head != root.simpleName) NoSymbol + else findNamedMember(segs.tail, root) + } + def findNamedMember(segs: List[Name], root: Symbol): Symbol = + if (segs.isEmpty) root + else findNamedMember(segs.tail, root.info member segs.head) + def getMember(owner: Symbol, name: Name): Symbol = { if (owner == NoSymbol) NoSymbol else owner.info.nonPrivateMember(name) match { @@ -911,6 +925,7 @@ trait Definitions extends reflect.api.StandardDefinitions { case result => result } } + def packageExists(packageName: String): Boolean = getModuleIfDefined(packageName).isPackage diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala index 270491d078..3110d73461 100644 --- a/src/compiler/scala/reflect/internal/Flags.scala +++ b/src/compiler/scala/reflect/internal/Flags.scala @@ -107,7 +107,7 @@ class ModifierFlags { // pre: PRIVATE or PROTECTED are also set final val JAVA = 0x00100000 // symbol was defined by a Java class final val STATIC = 0x00800000 // static field, method or class - final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor) + final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor, or a GADT skolem) final val TRAIT = 0x02000000 // symbol is a trait final val DEFAULTPARAM = 0x02000000 // the parameter has a default value final val PARAMACCESSOR = 0x20000000 // for field definitions generated for primary constructor @@ -468,33 +468,34 @@ class Flags extends ModifierFlags { protected final val rawFlagPickledOrder: Array[Long] = pickledListOrder.toArray def flagOfModifier(mod: Modifier): Long = mod match { - case Modifier.`protected` => PROTECTED - case Modifier.`private` => PRIVATE - case Modifier.`override` => OVERRIDE - case Modifier.`abstract` => ABSTRACT - case Modifier.`final`=> FINAL - case Modifier.`sealed`=> SEALED - case Modifier.`implicit`=> IMPLICIT - case Modifier.`lazy`=> LAZY - case Modifier.`case`=> CASE - case Modifier.`trait`=> TRAIT - case Modifier.deferred => DEFERRED - case Modifier.interface => INTERFACE - case Modifier.mutable => MUTABLE - case Modifier.parameter => PARAM - case Modifier.`macro` => MACRO - case Modifier.covariant => COVARIANT - case Modifier.contravariant => CONTRAVARIANT - case Modifier.preSuper => PRESUPER + case Modifier.`protected` => PROTECTED + case Modifier.`private` => PRIVATE + case Modifier.`override` => OVERRIDE + case Modifier.`abstract` => ABSTRACT + case Modifier.`final` => FINAL + case Modifier.`sealed` => SEALED + case Modifier.`implicit` => IMPLICIT + case Modifier.`lazy` => LAZY + case Modifier.`case` => CASE + case Modifier.`trait` => TRAIT + case Modifier.deferred => DEFERRED + case Modifier.interface => INTERFACE + case Modifier.mutable => MUTABLE + case Modifier.parameter => PARAM + case Modifier.`macro` => MACRO + case Modifier.covariant => COVARIANT + case Modifier.contravariant => CONTRAVARIANT + case Modifier.preSuper => PRESUPER case Modifier.abstractOverride => ABSOVERRIDE - case Modifier.local => LOCAL - case Modifier.java => JAVA - case Modifier.static => STATIC - case Modifier.caseAccessor => CASEACCESSOR + case Modifier.local => LOCAL + case Modifier.java => JAVA + case Modifier.static => STATIC + case Modifier.caseAccessor => CASEACCESSOR case Modifier.defaultParameter => DEFAULTPARAM - case Modifier.defaultInit => DEFAULTINIT - case Modifier.paramAccessor => PARAMACCESSOR - case Modifier.bynameParameter => BYNAMEPARAM + case Modifier.defaultInit => DEFAULTINIT + case Modifier.paramAccessor => PARAMACCESSOR + case Modifier.bynameParameter => BYNAMEPARAM + case _ => 0 } def flagsOfModifiers(mods: List[Modifier]): Long = diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 1003fa804f..04381937d1 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -351,6 +351,8 @@ trait Importers { self: SymbolTable => new ApplyToImplicitArgs(importTree(fun), args map importTree) case _: from.ApplyImplicitView => new ApplyImplicitView(importTree(fun), args map importTree) + case _: from.ApplyConstructor => + new ApplyConstructor(importTree(fun), args map importTree) case _ => new Apply(importTree(fun), args map importTree) } diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 9678d2b8cd..907f7d1237 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -269,11 +269,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Create a new existential type skolem with this symbol its owner, * based on the given symbol and origin. */ - def newExistentialSkolem(basis: Symbol, origin: AnyRef, name: TypeName = null, info: Type = null): TypeSkolem = { - val skolem = newTypeSkolemSymbol(if (name eq null) basis.name.toTypeName else name, origin, basis.pos, (basis.flags | EXISTENTIAL) & ~PARAM) - skolem setInfo (if (info eq null) basis.info cloneInfo skolem else info) + def newExistentialSkolem(basis: Symbol, origin: AnyRef): TypeSkolem = { + val skolem = newTypeSkolemSymbol(basis.name.toTypeName, origin, basis.pos, (basis.flags | EXISTENTIAL) & ~PARAM) + skolem setInfo (basis.info cloneInfo skolem) } + // flags set up to maintain TypeSkolem's invariant: origin.isInstanceOf[Symbol] == !hasFlag(EXISTENTIAL) + // CASEACCESSOR | SYNTHETIC used to single this symbol out in deskolemizeGADT + def newGADTSkolem(name: TypeName, origin: Symbol, info: Type): TypeSkolem = + newTypeSkolemSymbol(name, origin, origin.pos, origin.flags & ~(EXISTENTIAL | PARAM) | CASEACCESSOR | SYNTHETIC) setInfo info + + final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = newAbstractType(name, pos, EXISTENTIAL | newFlags) @@ -495,6 +501,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => // List[T] forSome { type T } final def isExistentialSkolem = isExistentiallyBound && isSkolem final def isExistentialQuantified = isExistentiallyBound && !isSkolem + final def isGADTSkolem = isSkolem && hasFlag(CASEACCESSOR | SYNTHETIC) // class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR) @@ -1985,6 +1992,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (isTrait) ("trait", "trait", "TRT") else if (isClass) ("class", "class", "CLS") else if (isType) ("type", "type", "TPE") + else if (isClassConstructor && isPrimaryConstructor) ("primary constructor", "constructor", "PCTOR") else if (isClassConstructor) ("constructor", "constructor", "CTOR") else if (isSourceMethod) ("method", "method", "METH") else if (isTerm) ("value", "value", "VAL") @@ -2129,12 +2137,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE else ExplicitFlags + // make the error message more googlable + def flagsExplanationString = + if (isGADTSkolem) " (this is a GADT skolem)" + else "" + def accessString = hasFlagsToString(PRIVATE | PROTECTED | LOCAL) def defaultFlagString = hasFlagsToString(defaultFlagMask) private def defStringCompose(infoString: String) = compose( defaultFlagString, keyString, - varianceString + nameString + infoString + varianceString + nameString + infoString + flagsExplanationString ) /** String representation of symbol's definition. It uses the * symbol's raw info to avoid forcing types. @@ -2477,7 +2490,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * where the skolem was introduced (this is important for knowing when to pack it * again into ab Existential). origin is `null` only in skolemizeExistentials called * from <:< or isAsSpecific, because here its value does not matter. - * I elieve the following invariant holds: + * I believe the following invariant holds: * * origin.isInstanceOf[Symbol] == !hasFlag(EXISTENTIAL) */ diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index 769d7a9ed1..ce3de94335 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -17,7 +17,7 @@ abstract class TreeInfo { val global: SymbolTable import global._ - import definitions.{ isVarArgsList, isCastSymbol, ThrowableClass } + import definitions.{ isVarArgsList, isCastSymbol, ThrowableClass, TupleClass } /* Does not seem to be used. Not sure what it does anyway. def isOwnerDefinition(tree: Tree): Boolean = tree match { @@ -312,6 +312,24 @@ abstract class TreeInfo { case _ => false } + /** Is this tree comprised of nothing but identifiers, + * but possibly in bindings or tuples? For instance + * + * foo @ (bar, (baz, quux)) + * + * is a variable pattern; if the structure matches, + * then the remainder is inevitable. + */ + def isVariablePattern(tree: Tree): Boolean = tree match { + case Bind(name, pat) => isVariablePattern(pat) + case Ident(name) => true + case Apply(sel, args) => + ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName) + && (args forall isVariablePattern) + ) + case _ => false + } + /** Is this argument node of the form <expr> : _* ? */ def isWildcardStarArg(tree: Tree): Boolean = tree match { diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index f823110440..8ed0ee6357 100644 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ b/src/compiler/scala/reflect/internal/TreePrinters.scala @@ -433,7 +433,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => /** Hook for extensions */ def xprintTree(treePrinter: TreePrinter, tree: Tree) = - treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")")) + treePrinter.print(tree.printingPrefix+tree.productIterator.mkString("(", ", ", ")")) def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer) def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream)) diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 2382413a9a..549c9e4607 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -1041,8 +1041,8 @@ trait Types extends api.Types { self: SymbolTable => baseClasses.head.newOverloaded(this, members.toList) } } - /** The existential skolems and existentially quantified variables which are free in this type */ - def existentialSkolems: List[Symbol] = { + /** The (existential or otherwise) skolems and existentially quantified variables which are free in this type */ + def skolemsExceptMethodTypeParams: List[Symbol] = { var boundSyms: List[Symbol] = List() var skolems: List[Symbol] = List() for (t <- this) { @@ -1050,7 +1050,8 @@ trait Types extends api.Types { self: SymbolTable => case ExistentialType(quantified, qtpe) => boundSyms = boundSyms ::: quantified case TypeRef(_, sym, _) => - if ((sym hasFlag EXISTENTIAL) && !(boundSyms contains sym) && !(skolems contains sym)) + if ((sym.isExistentialSkolem || sym.isGADTSkolem) && // treat GADT skolems like existential skolems + !((boundSyms contains sym) || (skolems contains sym))) skolems = sym :: skolems case _ => } diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index bc2cc8191c..9ccd0c28db 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -44,6 +44,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb with symtab.Positions { override def settings = currentSettings + + import definitions.{ findNamedMember, findMemberFromRoot } // alternate constructors ------------------------------------------ @@ -1494,21 +1496,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb afterPhase(phase) { currentRun.units foreach (treePrinter.print(_)) } } - private def findMemberFromRoot(fullName: Name): Symbol = { - val segs = nme.segments(fullName.toString, fullName.isTermName) - if (segs.isEmpty) NoSymbol - else findNamedMember(segs.tail, definitions.RootClass.info member segs.head) - } - - private def findNamedMember(fullName: Name, root: Symbol): Symbol = { - val segs = nme.segments(fullName.toString, fullName.isTermName) - if (segs.isEmpty || segs.head != root.simpleName) NoSymbol - else findNamedMember(segs.tail, root) - } - private def findNamedMember(segs: List[Name], root: Symbol): Symbol = - if (segs.isEmpty) root - else findNamedMember(segs.tail, root.info member segs.head) - /** We resolve the class/object ambiguity by passing a type/term name. */ def showDef(fullName: Name, declsOnly: Boolean, ph: Phase) = { diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 6a6379cca2..678f7b3028 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -19,6 +19,8 @@ import scala.collection.mutable */ trait DocComments { self: Global => + var cookedDocComments = Map[Symbol, String]() + def reporter: Reporter /** The raw doc comment map */ @@ -50,21 +52,29 @@ trait DocComments { self: Global => else sym.owner.ancestors map (sym overriddenSymbol _) filter (_ != NoSymbol) } - /** The raw doc comment of symbol `sym`, minus @usecase and @define sections, augmented by + /** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by * missing sections of an inherited doc comment. * If a symbol does not have a doc comment but some overridden version of it does, * the doc comment of the overridden version is copied instead. */ - def cookedDocComment(sym: Symbol, docStr: String = ""): String = { - val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse "" - else DocComment(docStr).template - superComment(sym) match { - case None => - ownComment - case Some(sc) => - if (ownComment == "") sc - else merge(sc, ownComment, sym) - } + def cookedDocComment(sym: Symbol, docStr: String = ""): String = cookedDocComments.get(sym) match { + case Some(comment) => + comment + case None => + val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse "" + else DocComment(docStr).template + val comment = superComment(sym) match { + case None => + if (ownComment.indexOf("@inheritdoc") != -1) + reporter.warning(sym.pos, "The comment for " + sym + + " contains @inheritdoc, but no parent comment is available to inherit from.") + ownComment.replaceAllLiterally("@inheritdoc", "<invalid inheritdoc annotation>") + case Some(sc) => + if (ownComment == "") sc + else expandInheritdoc(sc, merge(sc, ownComment, sym), sym) + } + cookedDocComments += (sym -> comment) + comment } /** The cooked doc comment of symbol `sym` after variable expansion, or "" if missing. @@ -99,10 +109,18 @@ trait DocComments { self: Global => */ def useCases(sym: Symbol, site: Symbol): List[(Symbol, String, Position)] = { def getUseCases(dc: DocComment) = { - for (uc <- dc.useCases; defn <- uc.expandedDefs(sym, site)) yield - (defn, - expandVariables(merge(cookedDocComment(sym), uc.comment.raw, defn), sym, site), - uc.pos) + val fullSigComment = cookedDocComment(sym) + for (uc <- dc.useCases; defn <- uc.expandedDefs(sym, site)) yield { + // use cases comments go through a series of transformations: + // 1 - filling in missing sections from the full signature + // 2 - expanding explicit inheritance @inheritdoc tags + // 3 - expanding variables like $COLL + val useCaseCommentRaw = uc.comment.raw + val useCaseCommentMerged = merge(fullSigComment, useCaseCommentRaw, defn) + val useCaseCommentInheritdoc = expandInheritdoc(fullSigComment, useCaseCommentMerged, sym) + val useCaseCommentVariables = expandVariables(useCaseCommentInheritdoc, sym, site) + (defn, useCaseCommentVariables, uc.pos) + } } getDocComment(sym) map getUseCases getOrElse List() } @@ -201,6 +219,80 @@ trait DocComments { self: Global => } } + /** + * Expand inheritdoc tags + * - for the main comment we transform the inheritdoc into the super variable, + * and the variable expansion can expand it further + * - for the param, tparam and throws sections we must replace comments on the spot + * + * This is done separately, for two reasons: + * 1. It takes longer to run compared to merge + * 2. The inheritdoc annotation should not be used very often, as building the comment from pieces severely + * impacts performance + */ + def expandInheritdoc(src: String, dst: String, sym: Symbol): String = + if (dst.indexOf("@inheritdoc") == -1) + dst + else { + val srcSections = tagIndex(src) + val dstSections = tagIndex(dst) + val srcTagMap = sectionTagMap(src, srcSections) + val srcNamedParams = Map() + + ("@param" -> paramDocs(src, "@param", srcSections)) + + ("@tparam" -> paramDocs(src, "@tparam", srcSections)) + + ("@throws" -> paramDocs(src, "@throws", srcSections)) + + val out = new StringBuilder + + def replaceInheritdoc(src: String, dst: String) = + if (dst.indexOf("@inheritdoc") == -1) + dst + else + dst.replaceAllLiterally("@inheritdoc", src) + + def getSourceSection(section: (Int, Int)): String = { + + def getSectionHeader = extractSectionTag(dst, section) match { + case param@("@param"|"@tparam"|"@throws") => param + " " + extractSectionParam(dst, section) + case other => other + } + + def sectionString(param: String, paramMap: Map[String, (Int, Int)]): String = + paramMap.get(param) match { + case Some(section) => + // Cleanup the section tag and parameter + val sectionTextBounds = extractSectionText(src, section) + cleanupSectionText(src.substring(sectionTextBounds._1, sectionTextBounds._2)) + case None => + reporter.info(sym.pos, "The \"" + getSectionHeader + "\" annotation of the " + sym + + " comment contains @inheritdoc, but the corresponding section in the parent is not defined.", true) + "<invalid inheritdoc annotation>" + } + + dst.substring(section._1, section._1 + 7) match { + case param@("@param "|"@tparam"|"@throws") => sectionString(extractSectionParam(dst, section), srcNamedParams(param.trim)) + case _ => sectionString(extractSectionTag(dst, section), srcTagMap) + } + } + + def mainComment(str: String, sections: List[(Int, Int)]): String = + if (str.trim.length > 3) + str.trim.substring(3, startTag(str, sections)) + else + "" + + // Append main comment + out.append("/**") + out.append(replaceInheritdoc(mainComment(src, srcSections), mainComment(dst, dstSections))) + + // Append sections + for (section <- dstSections) + out.append(replaceInheritdoc(getSourceSection(section), dst.substring(section._1, section._2))) + + out.append("*/") + out.toString + } + /** Maps symbols to the variable -> replacement maps that are defined * in their doc comments */ diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index 9466d1c1f2..3d4253f941 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -9,14 +9,13 @@ package ast import compat.Platform.EOL import symtab.Flags._ -/** The object <code>nodePrinter</code> converts the internal tree - * representation to a string formatted as a Scala expression. +/** The object `nodePrinter` converts the internal tree + * representation to a string. * * @author Stephane Micheloud - * @version 1.0 + * @author Paul Phillips */ abstract class NodePrinters { - val global: Global import global._ @@ -25,262 +24,293 @@ abstract class NodePrinters { } var infolevel = InfoLevel.Quiet - object nodeToString extends Function1[Tree, String] { + def nodeToString: Tree => String = + if (sys.props contains "scala.colors") nodeToColorizedString + else nodeToRegularString + + object nodeToRegularString extends DefaultPrintAST with (Tree => String) { + def apply(tree: Tree) = stringify(tree) + } + + object nodeToColorizedString extends ColorPrintAST with (Tree => String) { + def apply(tree: Tree) = stringify(tree) + } + + trait ColorPrintAST extends DefaultPrintAST { + import scala.tools.util.color._ + + def keywordColor = Cyan + def typeColor = Yellow + def termColor = Blue + def flagColor = Red + def literalColor = Green + + override def showFlags(tree: MemberDef) = "" + ( + super.showFlags(tree) in flagColor.bright + ) + override def showDefTreeName(tree: DefTree) = "" + ( + if (tree.name.isTermName) tree.name.decode in termColor.bright + else tree.name.decode in typeColor.bright + ) + override def showName(name: Name): String = "" + ( + if (name == nme.EMPTY || name == tpnme.EMPTY) "<empty>" in keywordColor + else if (name.isTermName) name.decode in termColor + else name.decode in typeColor + ) + override def showLiteral(lit: Literal) = "" + ( + super.showLiteral(lit) in literalColor.bright + ) + } + + trait DefaultPrintAST extends PrintAST { + def showDefTreeName(tree: DefTree) = showName(tree.name) + def showFlags(tree: MemberDef) = flagsToString(tree.symbol.flags | tree.mods.flags) + def showLiteral(lit: Literal) = lit.value.escapedStringValue + def showTypeTree(tt: TypeTree) = "<tpt>" + showAttributes(tt) + def showName(name: Name) = name match { + case nme.EMPTY | tpnme.EMPTY => "<empty>" + case name => "\"" + name + "\"" + } + + def showSymbol(tree: Tree): String = { + val sym = tree.symbol + if (sym == null || sym == NoSymbol) "" + else " sym/owner/tpe=%s %s/%s/%s".format(sym.accurateKindString, sym.name, sym.owner, sym.tpe) + } + def showType(tree: Tree): String = { + val tpe = tree.tpe + if (tpe == null || tpe == NoType) "" + else " tree.tpe=" + tpe + } + + def showAttributes(tree: Tree): String = { + if (infolevel == InfoLevel.Quiet) "" + else { + try { showSymbol(tree) + showType(tree) trim } + catch { case ex: Throwable => "sym= <error> " + ex.getMessage } + } + } + } + + trait PrintAST { private val buf = new StringBuilder + private var level = 0 - def apply(tree: Tree): String = { - def traverse(tree: Tree, level: Int, comma: Boolean) { - def println(s: String) { - for (i <- 0 until level) buf.append(" ") - buf.append(s) - buf.append(EOL) - } - def printcln(s: String) { - for (i <- 0 until level) buf.append(" ") - buf.append(s) - if (comma) buf.append(",") - buf.append(EOL) - } - def annotationInfoToString(annot: AnnotationInfo): String = { - val str = new StringBuilder - str.append(annot.atp.toString()) - if (!annot.args.isEmpty) - str.append(annot.args.mkString("(", ",", ")")) - if (!annot.assocs.isEmpty) - for (((name, value), index) <- annot.assocs.zipWithIndex) { - if (index > 0) - str.append(", ") - str.append(name).append(" = ").append(value) - } - str.toString - } - def symflags(tree: Tree): String = { - val buf = new StringBuffer - val sym = tree.symbol - buf append flagsToString(sym.flags) + def showName(name: Name): String + def showDefTreeName(defTree: DefTree): String + def showFlags(tree: MemberDef): String + def showLiteral(lit: Literal): String + def showTypeTree(tt: TypeTree): String + def showAttributes(tree: Tree): String // symbol and type + + def showRefTreeName(tree: Tree): String = tree match { + case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name) + case Select(qual, name) => showRefTreeName(qual) + "." + showName(name) + case Ident(name) => showName(name) + case _ => "" + tree + } + def showRefTree(tree: RefTree): String = { + def prefix0 = showRefTreeName(tree.qualifier) + def prefix = if (prefix0 == "") "" else (tree match { + case SelectFromTypeTree(_, _) => prefix0 + "#" + case Select(_, _) => prefix0 + "." + case _ => "" + }) + def attrs = showAttributes(tree) match { + case "" => "" + case s => " // " + s + } + prefix + showName(tree.name) + attrs + } + + def stringify(tree: Tree): String = { + buf.clear() + level = 0 + traverse(tree) + buf.toString + } + def traverseAny(x: Any) { + x match { + case t: Tree => traverse(t) + case xs: List[_] => printMultiline("List", "")(xs foreach traverseAny) + case _ => println("" + x) + } + } + def println(s: String) = printLine(s, "") + + def printLine(value: String, comment: String) { + buf append " " * level + buf append value + if (comment != "") { + buf append " // " + buf append comment + } + buf append EOL + } - val annots = ", annots=" + ( - if (!sym.annotations.isEmpty) - sym.annotations.map(annotationInfoToString).mkString("[", ",", "]") - else - tree.asInstanceOf[MemberDef].mods.annotations) - (if (buf.length() > 2) buf.substring(3) - else "0") + ", // flags=" + flagsToString(sym.flags) + annots + def annotationInfoToString(annot: AnnotationInfo): String = { + val str = new StringBuilder + str.append(annot.atp.toString()) + if (!annot.args.isEmpty) + str.append(annot.args.mkString("(", ",", ")")) + if (!annot.assocs.isEmpty) + for (((name, value), index) <- annot.assocs.zipWithIndex) { + if (index > 0) + str.append(", ") + str.append(name).append(" = ").append(value) } + str.toString + } + def printModifiers(tree: MemberDef) { + val annots0 = tree.symbol.annotations match { + case Nil => tree.mods.annotations + case xs => xs map annotationInfoToString + } + val annots = annots0 match { + case Nil => "" + case xs => " " + xs.mkString("@{ ", ", ", " }") + } + val flagString = showFlags(tree) match { + case "" => "0" + case s => s + } + println(flagString + annots) + } - def nodeinfo(tree: Tree): String = - if (infolevel == InfoLevel.Quiet) "" - else { - try { - val buf = new StringBuilder(" // sym=" + tree.symbol) - if (tree.hasSymbol) { - if (tree.symbol.isPrimaryConstructor) - buf.append(", isPrimaryConstructor") - else if (tree.symbol.isConstructor) - buf.append(", isConstructor") - if (tree.symbol != NoSymbol) - buf.append(", sym.owner=" + tree.symbol.owner) - buf.append(", sym.tpe=" + tree.symbol.tpe) - } - buf.append(", tpe=" + tree.tpe) - if (tree.tpe != null) { - var sym = tree.tpe.termSymbol - if (sym == NoSymbol) sym = tree.tpe.typeSymbol - buf.append(", tpe.sym=" + sym) - if (sym != NoSymbol) { - buf.append(", tpe.sym.owner=" + sym.owner) - if ((infolevel > InfoLevel.Normal) && - !(sym.owner eq definitions.ScalaPackageClass) && - !sym.isModuleClass && !sym.isPackageClass && - !sym.isJavaDefined) { - val members = for (m <- tree.tpe.decls) - yield m.toString() + ": " + m.tpe + ", " - buf.append(", tpe.decls=" + members) - } + def applyCommon(tree: Tree, fun: Tree, args: List[Tree]) { + printMultiline(tree) { + traverse(fun) + traverseList("Nil", _ + " arguments(s)")(args) + } + } + + def printMultiline(tree: Tree)(body: => Unit) { + printMultiline(tree.printingPrefix, showAttributes(tree))(body) + } + def printMultiline(prefix: String, comment: String)(body: => Unit) { + printLine(prefix + "(", comment) + indent(body) + println(")") + } + @inline private def indent[T](body: => T): T = { + level += 1 + try body + finally level -= 1 + } + + def traverseList(ifEmpty: String, comment: Int => String)(trees: List[Tree]) { + if (trees.isEmpty) + println(ifEmpty) + else + printMultiline("List", comment(trees.length))(trees foreach traverse) + } + + def traverse(tree: Tree) { + tree match { + case AppliedTypeTree(tpt, args) => applyCommon(tree, tpt, args) + case ApplyDynamic(fun, args) => applyCommon(tree, fun, args) + case Apply(fun, args) => applyCommon(tree, fun, args) + + case Block(stats, expr) => + printMultiline(tree) { + traverseList("{}", _ + " statement(s)")(stats) + traverse(expr) + } + case cd @ ClassDef(mods, name, tparams, impl) => + printMultiline(tree) { + printModifiers(cd) + println(showDefTreeName(cd)) + traverseList("[]", _ + " type parameter(s)")(tparams) + traverse(impl) + } + case md @ ModuleDef(mods, name, impl) => + printMultiline(tree) { + printModifiers(md) + println(showDefTreeName(md)) + traverse(impl) + } + case dd @ DefDef(mods, name, tparams, vparamss, tpt, rhs) => + printMultiline(tree) { + printModifiers(dd) + println(showDefTreeName(dd)) + traverseList("[]", _ + " type parameter(s)")(tparams) + vparamss match { + case Nil => println("Nil") + case Nil :: Nil => println("List(Nil)") + case xss => + printMultiline("List", xss.length + " parameter list(s)") { + xss foreach (xs => traverseList("()", _ + " parameter(s)")(xs)) } + } + traverse(tpt) + traverse(rhs) + } + case EmptyTree => + println(showName(nme.EMPTY)) + case lit @ Literal(value) => + println(showLiteral(lit)) + case New(tpt) => + printMultiline(tree)(traverse(tpt)) + case Super(This(qual), mix) => + println("Super(This(" + showName(qual) + "), " + showName(mix) + ")") + case Super(qual, mix) => + printMultiline(tree) { + traverse(qual) + showName(mix) + } + case Template(parents, self, body) => + printMultiline(tree) { + val ps0 = parents map { p => + if (p.tpe eq null) p match { + case x: RefTree => showRefTree(x) + case x => "" + x } - buf.toString - } catch { - case ex: Throwable => - return " // sym= <error> " + ex.getMessage + else showName(newTypeName(p.tpe.typeSymbol.fullName)) } + printLine(ps0 mkString ", ", "parents") + traverse(self) + traverseList("{}", _ + " statements in body")(body) } - def nodeinfo2(tree: Tree): String = - (if (comma) "," else "") + nodeinfo(tree) - - def applyCommon(name: String, tree: Tree, fun: Tree, args: List[Tree]) { - println(name + "(" + nodeinfo(tree)) - traverse(fun, level + 1, true) - if (args.isEmpty) - println(" Nil // no argument") - else { - val n = args.length - println(" List( // " + n + " arguments(s)") - for (i <- 0 until n) - traverse(args(i), level + 2, i < n-1) - println(" )") + case This(qual) => + println("This(\"" + showName(qual) + "\")" + showAttributes(tree)) + case TypeApply(fun, args) => + printMultiline(tree) { + traverse(fun) + traverseList("[]", _ + " type argument(s)")(args) } - printcln(")") - } + case tt @ TypeTree() => + println(showTypeTree(tt)) - tree match { - case AppliedTypeTree(tpt, args) => applyCommon("AppliedTypeTree", tree, tpt, args) - case Apply(fun, args) => applyCommon("Apply", tree, fun, args) - case ApplyDynamic(fun, args) => applyCommon("ApplyDynamic", tree, fun, args) + case Typed(expr, tpt) => + printMultiline(tree) { + traverse(expr) + traverse(tpt) + } + case vd @ ValDef(mods, name, tpt, rhs) => + printMultiline(tree) { + printModifiers(vd) + println(showDefTreeName(vd)) + traverse(tpt) + traverse(rhs) + } + case td @ TypeDef(mods, name, tparams, rhs) => + printMultiline(tree) { + printModifiers(td) + println(showDefTreeName(td)) + traverseList("[]", _ + " type parameter(s)")(tparams) + traverse(rhs) + } + + case PackageDef(pid, stats) => + printMultiline("PackageDef", "")(pid :: stats foreach traverse) - case Block(stats, expr) => - println("Block(" + nodeinfo(tree)) - if (stats.isEmpty) - println(" List(), // no statement") - else { - val n = stats.length - println(" List( // " + n + " statement(s)") - for (i <- 0 until n) - traverse(stats(i), level + 2, i < n-1) - println(" ),") - } - traverse(expr, level + 1, false) - printcln(")") - case ClassDef(mods, name, tparams, impl) => - println("ClassDef(" + nodeinfo(tree)) - println(" " + symflags(tree)) - println(" \"" + name + "\",") - if (tparams.isEmpty) - println(" List(), // no type parameter") - else { - val n = tparams.length - println(" List( // " + n + " type parameter(s)") - for (i <- 0 until n) - traverse(tparams(i), level + 2, i < n-1) - println(" ),") - } - traverse(impl, level + 1, false) - printcln(")") - case DefDef(mods, name, tparams, vparamss, tpt, rhs) => - println("DefDef(" + nodeinfo(tree)) - println(" " + symflags(tree)) - println(" \"" + name + "\",") - if (tparams.isEmpty) - println(" List(), // no type parameter") - else { - val n = tparams.length - println(" List( // " + n + " type parameter(s)") - for (i <- 0 until n) - traverse(tparams(i), level + 2, i < n-1) - println(" ),") - } - val n = vparamss.length - if (n == 1 && vparamss(0).isEmpty) - println(" List(List()), // no parameter") - else { - println(" List(") - for (i <- 0 until n) { - val m = vparamss(i).length - println(" List( // " + m + " parameter(s)") - for (j <- 0 until m) - traverse(vparamss(i)(j), level + 3, j < m-1) - println(" )") - } - println(" ),") - } - println(" " + tpt + ",") - traverse(rhs, level + 1, false) - printcln(")") - case EmptyTree => - printcln("EmptyTree") - case Ident(name) => - printcln("Ident(\"" + name + "\")" + nodeinfo2(tree)) - case Literal(value) => - printcln("Literal(" + value + ")") - case New(tpt) => - println("New(" + nodeinfo(tree)) - traverse(tpt, level + 1, false) - printcln(")") - case Select(qualifier, selector) => - println("Select(" + nodeinfo(tree)) - traverse(qualifier, level + 1, true) - printcln(" \"" + selector + "\")") - case Super(qual, mix) => - println("Super(\"" + mix + "\")" + nodeinfo(tree)) - traverse(qual, level + 1, true) - case Template(parents, self, body) => - println("Template(" + nodeinfo(tree)) - println(" " + parents.map(p => - if (p.tpe ne null) p.tpe.typeSymbol else "null-" + p - ) + ", // parents") - traverse(self, level + 1, true) - if (body.isEmpty) - println(" List() // no body") - else { - val n = body.length - println(" List( // body") - for (i <- 0 until n) - traverse(body(i), level + 2, i < n-1) - println(" )") - } - printcln(")") - case This(qual) => - println("This(\"" + qual + "\")" + nodeinfo2(tree)) - case TypeApply(fun, args) => - println("TypeApply(" + nodeinfo(tree)) - traverse(fun, level + 1, true) - if (args.isEmpty) - println(" List() // no argument") - else { - val n = args.length - println(" List(") - for (i <- 0 until n) - traverse(args(i), level + 1, i < n-1) - println(" )") - } - printcln(")") - case TypeTree() => - printcln("TypeTree()" + nodeinfo2(tree)) - case Typed(expr, tpt) => - println("Typed(" + nodeinfo(tree)) - traverse(expr, level + 1, true) - traverse(tpt, level + 1, false) - printcln(")") - case ValDef(mods, name, tpt, rhs) => - println("ValDef(" + nodeinfo(tree)) - println(" " + symflags(tree)) - println(" \"" + name + "\",") - traverse(tpt, level + 1, true) - traverse(rhs, level + 1, false) - printcln(")") - case PackageDef(pid, stats) => - println("PackageDef(") - traverse(pid, level + 1, false) - println(",\n") - for (stat <- stats) - traverse(stat, level + 1, false) - printcln(")") - case _ => - tree match { - case p: Product => - if (p.productArity != 0) { - println(p.productPrefix+"(") - for (elem <- (0 until p.productArity) map p.productElement) { - def printElem(elem: Any, level: Int): Unit = elem match { - case t: Tree => - traverse(t, level, false) - case xs: List[_] => - print("List(") - for (x <- xs) printElem(x, level+1) - printcln(")") - case _ => - println(elem.toString) - } - printElem(elem, level+1) - } - printcln(")") - } else printcln(p.productPrefix) - } - } + case _ => + tree match { + case t: RefTree => println(showRefTree(t)) + case t if t.productArity == 0 => println(tree.printingPrefix) + case t => printMultiline(tree)(tree.productIterator foreach traverseAny) + } } - buf setLength 0 - traverse(tree, 0, false) - buf.toString } } diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala index c1d6c1a4d4..3302c11127 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala @@ -352,144 +352,17 @@ abstract class TreeBrowsers { * Tree. */ object TreeInfo { - /** Return the case class name and the Name, if the node defines one */ - def treeName(t: Tree): (String, Name) = t match { - case ProgramTree(units) => - ("Program", EMPTY) - - case UnitTree(unit) => - ("CompilationUnit", newTermName("" + unit)) - - case DocDef(comment, definition) => - ("DocDef", EMPTY) - - case ClassDef(mods, name, tparams, impl) => - ("ClassDef", name) - - case PackageDef(packaged, impl) => - ("PackageDef", EMPTY) - - case ModuleDef(mods, name, impl) => - ("ModuleDef", name) - - case ValDef(mods, name, tpe, rhs) => - ("ValDef", name) - - case DefDef(mods, name, tparams, vparams, tpe, rhs) => - ("DefDef", name) - - case TypeDef(mods, name, tparams, rhs) => - ("TypeDef", name) - - case Import(expr, selectors) => - ("Import", EMPTY) - - case CaseDef(pat, guard, body) => - ("CaseDef", EMPTY) - - case Template(parents, self, body) => - ("Template", EMPTY) - - case LabelDef(name, params, rhs) => - ("LabelDef", name) - - case Block(stats, expr) => - ("Block", EMPTY) - - case Alternative(trees) => - ("Alternative", EMPTY) - - case Bind(name, rhs) => - ("Bind", name) - - case UnApply(fun, args) => - ("UnApply", EMPTY) - - case Match(selector, cases) => - ("Visitor", EMPTY) - - case Function(vparams, body) => - ("Function", EMPTY) - - case Assign(lhs, rhs) => - ("Assign", EMPTY) - - case If(cond, thenp, elsep) => - ("If", EMPTY) - - case Return(expr) => - ("Return", EMPTY) - - case Throw(expr) => - ("Throw", EMPTY) - - case New(init) => - ("New", EMPTY) - - case Typed(expr, tpe) => - ("Typed", EMPTY) - - case TypeApply(fun, args) => - ("TypeApply", EMPTY) - - case Apply(fun, args) => - ("Apply", EMPTY) - - case ApplyDynamic(qual, args) => - ("Apply", EMPTY) - - case Super(qualif, mix) => - ("Super", newTermName("mix: " + mix)) - - case This(qualifier) => - ("This", qualifier) - - case Select(qualifier, selector) => - ("Select", selector) - - case Ident(name) => - ("Ident", name) - - case Literal(value) => - ("Literal", EMPTY) - - case TypeTree() => - ("TypeTree", EMPTY) - - case Annotated(annot, arg) => - ("Annotated", EMPTY) - - case SingletonTypeTree(ref) => - ("SingletonType", EMPTY) - - case SelectFromTypeTree(qualifier, selector) => - ("SelectFromType", selector) - - case CompoundTypeTree(template) => - ("CompoundType", EMPTY) - - case AppliedTypeTree(tpe, args) => - ("AppliedType", EMPTY) - - case TypeBoundsTree(lo, hi) => - ("TypeBoundsTree", EMPTY) - - case ExistentialTypeTree(tpt, whereClauses) => - ("ExistentialTypeTree", EMPTY) - - case Try(block, catcher, finalizer) => - ("Try", EMPTY) - - case EmptyTree => - ("Empty", EMPTY) - - case ArrayValue(elemtpt, trees) => - ("ArrayValue", EMPTY) - - case Star(t) => - ("Star", EMPTY) - } + def treeName(t: Tree): (String, Name) = ((t.printingPrefix, t match { + case UnitTree(unit) => newTermName("" + unit) + case Super(_, mix) => newTermName("mix: " + mix) + case This(qual) => qual + case Select(_, selector) => selector + case Ident(name) => name + case SelectFromTypeTree(_, selector) => selector + case x: DefTree => x.name + case _ => EMPTY + })) /** Return a list of children for the given tree node */ def children(t: Tree): List[Tree] = t match { diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index 46ade7d889..93fa9a60f6 100644..100755 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -267,7 +267,7 @@ trait MarkupParsers { val (qname, attrMap) = xTag(()) if (ch == '/') { // empty element xToken("/>") - handle.element(r2p(start, start, curOffset), qname, attrMap, new ListBuffer[Tree]) + handle.element(r2p(start, start, curOffset), qname, attrMap, true, new ListBuffer[Tree]) } else { // handle content xToken('>') @@ -281,7 +281,7 @@ trait MarkupParsers { val pos = r2p(start, start, curOffset) qname match { case "xml:group" => handle.group(pos, ts) - case _ => handle.element(pos, qname, attrMap, ts) + case _ => handle.element(pos, qname, attrMap, false, ts) } } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index cd64c49b47..ccebcfa54d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -126,7 +126,7 @@ self => val global: Global import global._ - case class OpInfo(operand: Tree, operator: Name, targs: List[Tree], offset: Offset) + case class OpInfo(operand: Tree, operator: Name, offset: Offset) class SourceFileParser(val source: SourceFile) extends Parser { @@ -789,7 +789,7 @@ self => val rPos = top.pos val end = if (rPos.isDefined) rPos.endOrPoint else opPos.endOrPoint top = atPos(start, opinfo.offset, end) { - makeBinop(isExpr, opinfo.operand, opinfo.operator, top, opPos, opinfo.targs) + makeBinop(isExpr, opinfo.operand, opinfo.operator, top, opPos) } } top @@ -1440,17 +1440,6 @@ self => } } - def advanceStack(base: List[OpInfo], top: Tree): Tree = { - val newTop = reduceStack(true, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) - val op = in.name - val pos = in.offset - ident() - val targs = if (in.token == LBRACKET) exprTypeArgs() else Nil - opstack ::= OpInfo(newTop, op, targs, pos) - - newTop - } - /** {{{ * PostfixExpr ::= InfixExpr [Id [nl]] * InfixExpr ::= PrefixExpr @@ -1462,21 +1451,22 @@ self => var top = prefixExpr() while (isIdent) { - top = advanceStack(base, top) + top = reduceStack(true, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) + val op = in.name + opstack = OpInfo(top, op, in.offset) :: opstack + ident() newLineOptWhenFollowing(isExprIntroToken) - if (isExprIntro) { val next = prefixExpr() if (next == EmptyTree) return reduceStack(true, base, top, 0, true) top = next - } - else { + } else { val topinfo = opstack.head opstack = opstack.tail val od = stripParens(reduceStack(true, base, topinfo.operand, 0, true)) return atPos(od.pos.startOrPoint, topinfo.offset) { - applyTypeArgs(Select(od, topinfo.operator.encode), topinfo.targs) + Select(od, topinfo.operator.encode) } } } @@ -1816,7 +1806,7 @@ self => top = reduceStack( false, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) val op = in.name - opstack = OpInfo(top, op, Nil, in.offset) :: opstack + opstack = OpInfo(top, op, in.offset) :: opstack ident() top = simplePattern() } @@ -1906,11 +1896,6 @@ self => def exprTypeArgs() = outPattern.typeArgs() def exprSimpleType() = outPattern.simpleType() - def applyTypeArgs(sel: Tree, targs: List[Tree]): Tree = ( - if (targs.isEmpty) sel - else atPos(sel.pos)(TypeApply(sel, targs)) - ) - /** Default entry points into some pattern contexts. */ def pattern(): Tree = noSeq.pattern() def patterns(): List[Tree] = noSeq.patterns() diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index ffe65aec63..849437e4ff 100644..100755 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -101,7 +101,8 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { pre: Tree, label: Tree, attrs: Tree, - scope:Tree, + scope: Tree, + empty: Boolean, children: Seq[Tree]): Tree = { def starArgs = @@ -109,7 +110,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { else List(Typed(makeXMLseq(pos, children), wildStar)) def pat = Apply(_scala_xml__Elem, List(pre, label, wild, wild) ::: convertToTextPat(children)) - def nonpat = New(_scala_xml_Elem, List(List(pre, label, attrs, scope) ::: starArgs)) + def nonpat = New(_scala_xml_Elem, List(List(pre, label, attrs, scope, if (empty) Literal(Constant(true)) else Literal(Constant(false))) ::: starArgs)) atPos(pos) { if (isPattern) pat else nonpat } } @@ -140,7 +141,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { case (Some(pre), rest) => (const(pre), const(rest)) case _ => (wild, const(n)) } - mkXML(pos, true, prepat, labpat, null, null, args) + mkXML(pos, true, prepat, labpat, null, null, false, args) } protected def convertToTextPat(t: Tree): Tree = t match { @@ -188,7 +189,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { def unparsed(pos: Position, str: String): Tree = atPos(pos)( New(_scala_xml_Unparsed, LL(const(str))) ) - def element(pos: Position, qname: String, attrMap: mutable.Map[String, Tree], args: Seq[Tree]): Tree = { + def element(pos: Position, qname: String, attrMap: mutable.Map[String, Tree], empty: Boolean, args: Seq[Tree]): Tree = { def handleNamespaceBinding(pre: String, z: String): Tree = { def mkAssign(t: Tree): Tree = Assign( Ident(_tmpscope), @@ -259,6 +260,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { const(newlabel), makeSymbolicAttrs, Ident(_scope), + empty, args ) diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 4b7c03b72a..0bc88d1efd 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -174,14 +174,7 @@ abstract class TreeBuilder { } /** Create tree representing (unencoded) binary operation expression or pattern. */ - def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position, targs: List[Tree] = Nil): Tree = { - require(isExpr || targs.isEmpty, ((left, op, targs, right))) - - def mkSel(t: Tree) = { - val sel = atPos(opPos union t.pos)(Select(stripParens(t), op.encode)) - if (targs.isEmpty) sel else atPos(left.pos)(TypeApply(sel, targs)) - } - + def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position): Tree = { def mkNamed(args: List[Tree]) = if (isExpr) args map { case a @ Assign(id @ Ident(name), rhs) => @@ -194,17 +187,14 @@ abstract class TreeBuilder { } if (isExpr) { if (treeInfo.isLeftAssoc(op)) { - Apply(mkSel(left), arguments) - } - else { + Apply(atPos(opPos union left.pos) { Select(stripParens(left), op.encode) }, arguments) + } else { val x = freshTermName() Block( List(ValDef(Modifiers(SYNTHETIC), x, TypeTree(), stripParens(left))), - Apply(mkSel(right), List(Ident(x))) - ) + Apply(atPos(opPos union right.pos) { Select(stripParens(right), op.encode) }, List(Ident(x)))) } - } - else { + } else { Apply(Ident(op.encode), stripParens(left) :: arguments) } } @@ -272,29 +262,25 @@ abstract class TreeBuilder { else if (stats.length == 1) stats.head else Block(stats.init, stats.last) + def makeFilter(tree: Tree, condition: Tree, scrutineeName: String): Tree = { + val cases = List( + CaseDef(condition, EmptyTree, Literal(Constant(true))), + CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false))) + ) + val matchTree = makeVisitor(cases, false, scrutineeName) + + atPos(tree.pos)(Apply(Select(tree, nme.withFilter), matchTree :: Nil)) + } + /** Create tree for for-comprehension generator <val pat0 <- rhs0> */ def makeGenerator(pos: Position, pat: Tree, valeq: Boolean, rhs: Tree): Enumerator = { val pat1 = patvarTransformer.transform(pat) val rhs1 = - if (valeq) rhs - else matchVarPattern(pat1) match { - case Some(_) => - rhs - case None => - atPos(rhs.pos) { - Apply( - Select(rhs, nme.filter), - List( - makeVisitor( - List( - CaseDef(pat1.duplicate, EmptyTree, Literal(Constant(true))), - CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false)))), - false, - nme.CHECK_IF_REFUTABLE_STRING - ))) - } - } - if (valeq) ValEq(pos, pat1, rhs1) else ValFrom(pos, pat1, rhs1) + if (valeq || treeInfo.isVariablePattern(pat)) rhs + else makeFilter(rhs, pat1.duplicate, nme.CHECK_IF_REFUTABLE_STRING) + + if (valeq) ValEq(pos, pat1, rhs1) + else ValFrom(pos, pat1, rhs1) } def makeParam(pname: TermName, tpe: Tree) = diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index 5e5320ca9a..e35286b281 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -438,7 +438,9 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { if(!comment.throws.isEmpty) { <dt>Exceptions thrown</dt> <dd>{ - val exceptionsXml: Iterable[scala.xml.NodeSeq] = (for(exception <- comment.throws ) yield <span class="cmt">{Text(exception._1) ++ bodyToHtml(exception._2)}</span> ) + val exceptionsXml: Iterable[scala.xml.NodeSeq] = + for(exception <- comment.throws.toList.sortBy(_._1) ) yield + <span class="cmt">{Text(exception._1) ++ bodyToHtml(exception._2)}</span> exceptionsXml.reduceLeft(_ ++ Text("") ++ _) }</dd> } else NodeSeq.Empty diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala index dbbd6ab432..bc5cd4a958 100644 --- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala @@ -38,7 +38,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => val key = (sym, inTpl) if (commentCache isDefinedAt key) Some(commentCache(key)) - else { // not reached for use-case comments + else { val c = defineComment(sym, inTpl) if (c isDefined) commentCache += (sym, inTpl) -> c.get c diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala index d08a363a9d..88e3827403 100644 --- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala +++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala @@ -189,7 +189,7 @@ self: scala.tools.nsc.Global => override def validatePositions(tree: Tree) { def reportTree(prefix : String, tree : Tree) { val source = if (tree.pos.isDefined) tree.pos.source else "" - inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source) + inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.printingPrefix+" at "+tree.pos.show+source) inform("") inform(treeStatus(tree)) inform("") diff --git a/src/compiler/scala/tools/nsc/interpreter/Naming.scala b/src/compiler/scala/tools/nsc/interpreter/Naming.scala index 8e215cf63b..19266442cb 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Naming.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Naming.scala @@ -11,16 +11,18 @@ package interpreter */ trait Naming { def unmangle(str: String): String = { + val ESC = '\u001b' val cleaned = removeIWPackages(removeLineWrapper(str)) - var ctrlChars = 0 - cleaned map { ch => - if (ch.isControl && !ch.isWhitespace) { - ctrlChars += 1 - if (ctrlChars > 5) return "[line elided for control chars: possibly a scala signature]" - else '?' - } - else ch - } + // Looking to exclude binary data which hoses the terminal, but + // let through the subset of it we need, like whitespace and also + // <ESC> for ansi codes. + val binaryChars = cleaned count (ch => ch < 32 && !ch.isWhitespace && ch != ESC) + // Lots of binary chars - translate all supposed whitespace into spaces + if (binaryChars > 5) + cleaned map (ch => if (ch.isWhitespace) ' ' else if (ch < 32) '?' else ch) + // Not lots - preserve whitespace and ESC + else + cleaned map (ch => if (ch.isWhitespace || ch == ESC) ch else if (ch < 32) '?' else ch) } // The two name forms this is catching are the two sides of this assignment: diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 8ed44b5a31..b21fa4bc83 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -165,24 +165,19 @@ abstract class CleanUp extends Transform with ast.TreeDSL { varSym } - def addStaticMethodToClass(forName: String, forArgsTypes: List[Type], forResultType: Type) - (forBody: Pair[Symbol, List[Symbol]] => Tree): Symbol = { + def addStaticMethodToClass(forBody: (Symbol, Symbol) => Tree): Symbol = { + val methSym = currentClass.newMethod(mkTerm(nme.reflMethodName), ad.pos, STATIC | SYNTHETIC) + val params = methSym.newSyntheticValueParams(List(ClassClass.tpe)) + methSym setInfoAndEnter MethodType(params, MethodClass.tpe) - val methSym = currentClass.newMethod(mkTerm(forName), ad.pos, STATIC | SYNTHETIC) - val params = methSym.newSyntheticValueParams(forArgsTypes) - methSym setInfoAndEnter MethodType(params, forResultType) - - val methDef = typedPos( DefDef(methSym, forBody(methSym -> params)) ) + val methDef = typedPos(DefDef(methSym, forBody(methSym, params.head))) newStaticMembers append transform(methDef) - methSym } def fromTypesToClassArrayLiteral(paramTypes: List[Type]): Tree = ArrayValue(TypeTree(ClassClass.tpe), paramTypes map LIT) - def theTypeClassArray = arrayType(ClassClass.tpe) - /* ... */ def reflectiveMethodCache(method: String, paramTypes: List[Type]): Symbol = dispatchType match { case NO_CACHE => @@ -197,12 +192,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL { */ val reflParamsCacheSym: Symbol = - addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true) + addStaticVariableToClass(nme.reflParamsCacheName, arrayType(ClassClass.tpe), fromTypesToClassArrayLiteral(paramTypes), true) - addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe) { - case Pair(reflMethodSym, List(forReceiverSym)) => - (REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym)) - } + addStaticMethodToClass((_, forReceiverSym) => + gen.mkMethodCall(REF(forReceiverSym), Class_getMethod, Nil, List(LIT(method), safeREF(reflParamsCacheSym))) + ) case MONO_CACHE => @@ -226,7 +220,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { */ val reflParamsCacheSym: Symbol = - addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true) + addStaticVariableToClass(nme.reflParamsCacheName, arrayType(ClassClass.tpe), fromTypesToClassArrayLiteral(paramTypes), true) val reflMethodCacheSym: Symbol = addStaticVariableToClass(nme.reflMethodCacheName, MethodClass.tpe, NULL, false) @@ -237,17 +231,16 @@ abstract class CleanUp extends Transform with ast.TreeDSL { def isCacheEmpty(receiver: Symbol): Tree = reflClassCacheSym.IS_NULL() OR (reflClassCacheSym.GET() OBJ_NE REF(receiver)) - addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe) { - case Pair(reflMethodSym, List(forReceiverSym)) => - BLOCK( - IF (isCacheEmpty(forReceiverSym)) THEN BLOCK( - safeREF(reflMethodCacheSym) === ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))) , - safeREF(reflClassCacheSym) === gen.mkSoftRef(REF(forReceiverSym)), - UNIT - ) ENDIF, - safeREF(reflMethodCacheSym) - ) - } + addStaticMethodToClass((_, forReceiverSym) => + BLOCK( + IF (isCacheEmpty(forReceiverSym)) THEN BLOCK( + safeREF(reflMethodCacheSym) === ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))) , + safeREF(reflClassCacheSym) === gen.mkSoftRef(REF(forReceiverSym)), + UNIT + ) ENDIF, + safeREF(reflMethodCacheSym) + ) + ) case POLY_CACHE => @@ -273,7 +266,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { */ val reflParamsCacheSym: Symbol = - addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true) + addStaticVariableToClass(nme.reflParamsCacheName, arrayType(ClassClass.tpe), fromTypesToClassArrayLiteral(paramTypes), true) def mkNewPolyCache = gen.mkSoftRef(NEW(TypeTree(EmptyMethodCacheClass.tpe))) val reflPolyCacheSym: Symbol = ( @@ -281,26 +274,25 @@ abstract class CleanUp extends Transform with ast.TreeDSL { ) def getPolyCache = gen.mkCast(fn(safeREF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe) - addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe) - { case Pair(reflMethodSym, List(forReceiverSym)) => - val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe - - BLOCK( - IF (getPolyCache OBJ_EQ NULL) THEN (safeREF(reflPolyCacheSym) === mkNewPolyCache) ENDIF, - VAL(methodSym) === ((getPolyCache DOT methodCache_find)(REF(forReceiverSym))) , - IF (REF(methodSym) OBJ_!= NULL) . - THEN (Return(REF(methodSym))) - ELSE { - def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))) - def cacheRHS = ((getPolyCache DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) - BLOCK( - REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)), - safeREF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS), - Return(REF(methodSym)) - ) - } - ) - } + addStaticMethodToClass((reflMethodSym, forReceiverSym) => { + val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe + + BLOCK( + IF (getPolyCache OBJ_EQ NULL) THEN (safeREF(reflPolyCacheSym) === mkNewPolyCache) ENDIF, + VAL(methodSym) === ((getPolyCache DOT methodCache_find)(REF(forReceiverSym))) , + IF (REF(methodSym) OBJ_!= NULL) . + THEN (Return(REF(methodSym))) + ELSE { + def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))) + def cacheRHS = ((getPolyCache DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) + BLOCK( + REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)), + safeREF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS), + Return(REF(methodSym)) + ) + } + ) + }) } /* ### HANDLING METHODS NORMALLY COMPILED TO OPERATORS ### */ diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index dfadd8d60e..639e060812 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -96,7 +96,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { && !sym.accessed.hasFlag(PRESUPER) && !sym.isOuterAccessor && !(sym.owner isSubClass DelayedInitClass) - && !(sym.isGetter && (sym.accessed hasAnnotation TransientAttr)) + && !(sym.accessed hasAnnotation TransientAttr) ) /** Maps all parts of this type that refer to implementation classes to diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 8b3bc253fd..a59622d4df 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1099,7 +1099,7 @@ trait Infer { // since instantiateTypeVar wants to modify the skolem that corresponds to the method's type parameter, // and it uses the TypeVar's origin to locate it, deskolemize the existential skolem to the method tparam skolem // (the existential skolem was created by adaptConstrPattern to introduce the type slack necessary to soundly deal with variant type parameters) - case skolem if skolem.isExistentialSkolem => freshVar(skolem.deSkolemize.asInstanceOf[TypeSymbol]) + case skolem if skolem.isGADTSkolem => freshVar(skolem.deSkolemize.asInstanceOf[TypeSymbol]) case p => freshVar(p) } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index ec42d251ff..73369f09af 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1445,7 +1445,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R private def transformApply(tree: Apply): Tree = tree match { case Apply( - Select(qual, nme.filter), + Select(qual, nme.filter | nme.withFilter), List(Function( List(ValDef(_, pname, tpt, _)), Match(_, CaseDef(pat1, _, _) :: _)))) diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 1434002121..e17a271dd0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -157,7 +157,7 @@ trait TypeDiagnostics { } // todo: use also for other error messages - def existentialContext(tp: Type) = tp.existentialSkolems match { + def existentialContext(tp: Type) = tp.skolemsExceptMethodTypeParams match { case Nil => "" case xs => " where " + (disambiguate(xs map (_.existentialToString)) mkString ", ") } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c4880dd6d7..0dd4b37131 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -909,8 +909,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def apply(tp: Type) = mapOver(tp) match { case TypeRef(NoPrefix, tpSym, Nil) if variance != 0 && tpSym.isTypeParameterOrSkolem && tpSym.owner.isTerm => val bounds = if (variance == 1) TypeBounds.upper(tpSym.tpe) else TypeBounds.lower(tpSym.tpe) - val skolem = context.owner.newExistentialSkolem(tpSym, tpSym, unit.freshTypeName("?"+tpSym.name), bounds) - // println("mapping "+ tpSym +" to "+ skolem + " : "+ bounds +" -- pt= "+ pt) + // origin must be the type param so we can deskolemize + val skolem = context.owner.newGADTSkolem(unit.freshTypeName("?"+tpSym.name), tpSym, bounds) + // println("mapping "+ tpSym +" to "+ skolem + " : "+ bounds +" -- pt= "+ pt +" in "+ context.owner +" at "+ context.tree ) skolems += skolem skolem.tpe case tp1 => tp1 @@ -928,9 +929,19 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { freeVars foreach ctorContext.scope.enter newTyper(ctorContext).infer.inferConstructorInstance(tree1, clazz.typeParams, ptSafe) - // tree1's type-slack skolems will be deskolemized (to the method type parameter skolems) - // once the containing CaseDef has been type checked (see typedCase) - tree1 + // simplify types without losing safety, + // so that error messages don't unnecessarily refer to skolems + val extrapolate = new ExistentialExtrapolation(freeVars) extrapolate (_: Type) + val extrapolated = tree1.tpe match { + case MethodType(ctorArgs, res) => // ctorArgs are actually in a covariant position, since this is the type of the subpatterns of the pattern represented by this Apply node + ctorArgs foreach (p => p.info = extrapolate(p.info)) // no need to clone, this is OUR method type + copyMethodType(tree1.tpe, ctorArgs, extrapolate(res)) + case tp => tp + } + + // once the containing CaseDef has been type checked (see typedCase), + // tree1's remaining type-slack skolems will be deskolemized (to the method type parameter skolems) + tree1 setType extrapolated } else { tree } @@ -1095,7 +1106,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val found = tree.tpe val req = pt if (!found.isErroneous && !req.isErroneous) { - if (!context.reportErrors && isPastTyper && req.existentialSkolems.nonEmpty) { + if (!context.reportErrors && isPastTyper && req.skolemsExceptMethodTypeParams.nonEmpty) { // Ignore type errors raised in later phases that are due to mismatching types with existential skolems // We have lift crashing in 2.9 with an adapt failure in the pattern matcher. // Here's my hypothsis why this happens. The pattern matcher defines a variable of type @@ -1112,7 +1123,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // // val x = expr context.unit.warning(tree.pos, "recovering from existential Skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree) - adapt(tree, mode, deriveTypeWithWildcards(pt.existentialSkolems)(pt)) + adapt(tree, mode, deriveTypeWithWildcards(pt.skolemsExceptMethodTypeParams)(pt)) } else { // create an actual error AdaptTypeError(tree, found, req) @@ -2112,21 +2123,21 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // body1 = checkNoEscaping.locals(context.scope, pt, body1) val treeWithSkolems = treeCopy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe - // undo adaptConstrPattern's evil deeds, as they confuse the old pattern matcher - // TODO: Paul, can we do the deskolemization lazily in the old pattern matcher - object deskolemizeOnce extends TypeMap { - def apply(tp: Type): Type = mapOver(tp) match { - case TypeRef(pre, sym, args) if sym.isExistentialSkolem && sym.deSkolemize.isSkolem && sym.deSkolemize.owner.isTerm => - typeRef(NoPrefix, sym.deSkolemize, args) - case tp1 => tp1 - } - } - - new TypeMapTreeSubstituter(deskolemizeOnce).traverse(treeWithSkolems) + new TypeMapTreeSubstituter(deskolemizeGADTSkolems).traverse(treeWithSkolems) treeWithSkolems // now without skolems, actually } + // undo adaptConstrPattern's evil deeds, as they confuse the old pattern matcher + // the flags are used to avoid accidentally deskolemizing unrelated skolems of skolems + object deskolemizeGADTSkolems extends TypeMap { + def apply(tp: Type): Type = mapOver(tp) match { + case TypeRef(pre, sym, args) if sym.isGADTSkolem => + typeRef(NoPrefix, sym.deSkolemize, args) + case tp1 => tp1 + } + } + def typedCases(cases: List[CaseDef], pattp: Type, pt: Type): List[CaseDef] = cases mapConserve { cdef => newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt) @@ -3630,7 +3641,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val Select(qual, name) = fun tryTypedArgs(args, forArgMode(fun, mode)) match { case Some(args1) => - assert((args1.length == 0) || !args1.head.tpe.isErroneous, "try typed args is ok") val qual1 = if (!pt.isError) adaptToArguments(qual, name, args1, pt, true, true) else qual diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala index fbe92e5d84..f4ce6d6ef1 100755 --- a/src/compiler/scala/tools/nsc/util/DocStrings.scala +++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala @@ -26,6 +26,14 @@ object DocStrings { if (start < str.length && isIdentifierPart(str charAt start)) skipIdent(str, start + 1) else start + /** Returns index of string `str` following `start` skipping + * sequence of identifier characters. + */ + def skipTag(str: String, start: Int): Int = + if (start < str.length && (str charAt start) == '@') skipIdent(str, start + 1) + else start + + /** Returns index of string `str` after `start` skipping longest * sequence of space and tab characters, possibly also containing * a single `*` character or the `/``**` sequence. @@ -68,38 +76,46 @@ object DocStrings { /** Produces a string index, which is a list of ``sections'', i.e * pairs of start/end positions of all tagged sections in the string. - * Every section starts with a `@` and extends to the next `@`, or - * to the end of the comment string, but excluding the final two + * Every section starts with an at sign and extends to the next at sign, + * or to the end of the comment string, but excluding the final two * characters which terminate the comment. * * Also take usecases into account - they need to expand until the next * usecase or the end of the string, as they might include other sections * of their own */ - def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] = - findAll(str, 0) (idx => str(idx) == '@' && p(idx)) match { + def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] = { + var indices = findAll(str, 0) (idx => str(idx) == '@' && p(idx)) + indices = mergeUsecaseSections(str, indices) + indices = mergeInheritdocSections(str, indices) + + indices match { case List() => List() - case idxs => { - val idxs2 = mergeUsecaseSections(str, idxs) - idxs2 zip (idxs2.tail ::: List(str.length - 2)) - } + case idxs => idxs zip (idxs.tail ::: List(str.length - 2)) } + } /** * Merge sections following an usecase into the usecase comment, so they * can override the parent symbol's sections */ def mergeUsecaseSections(str: String, idxs: List[Int]): List[Int] = { - idxs.find(str.substring(_).startsWith("@usecase")) match { - case Some(firstUC) => - val commentSections = idxs.take(idxs.indexOf(firstUC)) - val usecaseSections = idxs.drop(idxs.indexOf(firstUC)).filter(str.substring(_).startsWith("@usecase")) + idxs.indexWhere(str.substring(_).startsWith("@usecase")) match { + case firstUCIndex if firstUCIndex != -1 => + val commentSections = idxs.take(firstUCIndex) + val usecaseSections = idxs.drop(firstUCIndex).filter(str.substring(_).startsWith("@usecase")) commentSections ::: usecaseSections - case None => + case _ => idxs } } + /** + * Merge the inheritdoc sections, as they never make sense on their own + */ + def mergeInheritdocSections(str: String, idxs: List[Int]): List[Int] = + idxs.filterNot(str.substring(_).startsWith("@inheritdoc")) + /** Does interval `iv` start with given `tag`? */ def startsWithTag(str: String, section: (Int, Int), tag: String): Boolean = @@ -108,12 +124,11 @@ object DocStrings { def startsWithTag(str: String, start: Int, tag: String): Boolean = str.startsWith(tag, start) && !isIdentifierPart(str charAt (start + tag.length)) - /** The first start tag of a list of tag intervals, * or the end of the whole comment string - 2 if list is empty */ def startTag(str: String, sections: List[(Int, Int)]) = sections match { - case List() => str.length - 2 + case Nil => str.length - 2 case (start, _) :: _ => start } @@ -155,4 +170,46 @@ object DocStrings { idx } } + + /** A map from the section tag to section parameters */ + def sectionTagMap(str: String, sections: List[(Int, Int)]): Map[String, (Int, Int)] = + Map() ++ { + for (section <- sections) yield + extractSectionTag(str, section) -> section + } + + /** Extract the section tag, treating the section tag as an indentifier */ + def extractSectionTag(str: String, section: (Int, Int)): String = + str.substring(section._1, skipTag(str, section._1)) + + /** Extract the section parameter */ + def extractSectionParam(str: String, section: (Int, Int)): String = { + assert(str.substring(section._1).startsWith("@param") || + str.substring(section._1).startsWith("@tparam") || + str.substring(section._1).startsWith("@throws")) + + val start = skipWhitespace(str, skipTag(str, section._1)) + val finish = skipIdent(str, start) + + str.substring(start, finish) + } + + /** Extract the section text, except for the tag and comment newlines */ + def extractSectionText(str: String, section: (Int, Int)): (Int, Int) = { + if (str.substring(section._1).startsWith("@param") || + str.substring(section._1).startsWith("@tparam") || + str.substring(section._1).startsWith("@throws")) + (skipWhitespace(str, skipIdent(str, skipWhitespace(str, skipTag(str, section._1)))), section._2) + else + (skipWhitespace(str, skipTag(str, section._1)), section._2) + } + + /** Cleanup section text */ + def cleanupSectionText(str: String) = { + var result = str.trim.replaceAll("\n\\s+\\*\\s+", " \n") + while (result.endsWith("\n")) + result = result.substring(0, str.length - 1) + result + } + } diff --git a/src/compiler/scala/tools/util/color/Ansi.scala b/src/compiler/scala/tools/util/color/Ansi.scala new file mode 100644 index 0000000000..1ed43579bb --- /dev/null +++ b/src/compiler/scala/tools/util/color/Ansi.scala @@ -0,0 +1,58 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2012 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.util +package color + +import collection.mutable + +object Ansi { + final val ESC = '\u001b' // <esc> + final val LBR = '\u005b' // [ + final val CSI = new String(Array(ESC, LBR)) // control sequence introducer + final val CSI_FINAL = "m" // control sequence final byte + + def colors = List(Black, Red, Green, Yellow, Blue, Magenta, Cyan, White) + def effects = List(Reset, Bright, Faint, Italic, Underline, Blink, Inverse, Hidden, Strikethrough) + + // No, that's not the finale of "CSI: Crime Scene Investigation." + + def colorizerFor(codes: Seq[Int]): String => String = + s => ansiCodeToString(codes) + s + ansiCodeToString(0) + + def ansiCodeToString(code: Int): String = CSI + code + CSI_FINAL + def ansiCodeToString(codes: Seq[Int]): String = codes.mkString(CSI, ";", CSI_FINAL) +} + +/** An ansi control sequence. The colorize function prepends + * the control sequence to the given String and appends a + * reset sequence. + */ +class Ansi(atoms0: List[AnsiAtom]) { + val atoms = atoms0 sortBy (x => (!x.isAttr, x.isInstanceOf[AnsiBackground])) + val colorize = Ansi colorizerFor codes + + def codes = atoms map (_.code) + def /(that: AnsiAtom) = new Ansi(atoms :+ that) + // This looks redundant with / , but isn't - it is a way + // to ensure that the argument will be a background color, + // even if a foreground color is passed as an argument + // (as it will be implicitly converted.) + def on(that: AnsiBackground) = this / that + + // Convenience functions. + def reset = this / Reset + def bright = this / Bright + def faint = this / Faint + def italic = this / Italic + def underline = this / Underline + def blink = this / Blink + def inverse = this / Inverse + def hidden = this / Hidden + def strikethrough = this / Strikethrough + + // adjectives first + override def toString = atoms mkString " " +} diff --git a/src/compiler/scala/tools/util/color/AnsiAtom.scala b/src/compiler/scala/tools/util/color/AnsiAtom.scala new file mode 100644 index 0000000000..5d5490f6e9 --- /dev/null +++ b/src/compiler/scala/tools/util/color/AnsiAtom.scala @@ -0,0 +1,51 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2012 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.util +package color + +case object Reset extends AnsiAttr(0) +case object Bright extends AnsiAttr(1) +case object Faint extends AnsiAttr(2) +case object Italic extends AnsiAttr(3) +case object Underline extends AnsiAttr(4) +case object Blink extends AnsiAttr(5) +case object Inverse extends AnsiAttr(7) +case object Hidden extends AnsiAttr(8) +case object Strikethrough extends AnsiAttr(9) + +case object Black extends AnsiForeground(30) +case object Red extends AnsiForeground(31) +case object Green extends AnsiForeground(32) +case object Yellow extends AnsiForeground(33) +case object Blue extends AnsiForeground(34) +case object Magenta extends AnsiForeground(35) +case object Cyan extends AnsiForeground(36) +case object White extends AnsiForeground(37) +case object Default extends AnsiForeground(39) + +/** One piece of an ansi control sequence. Either a color + * (foreground or background) or an attribute (e.g. bright, underline.) + * Control sequences are created from AnsiAtoms with the / operator. + */ +trait AnsiAtom { + def code: Int + def isAttr: Boolean +} +sealed abstract class AnsiAttr(val code: Int) extends AnsiAtom { + final def isAttr = true +} +sealed abstract class AnsiColor(val code: Int) extends AnsiAtom { + final def isAttr = false + def flip: AnsiColor +} +sealed abstract class AnsiForeground(code: Int) extends AnsiColor(code) { + require(30 <= code && code <= 39, code) + val flip: AnsiBackground = new AnsiBackground(this) +} +sealed class AnsiBackground(val flip: AnsiForeground) extends AnsiColor(flip.code + 10) { + require(40 <= code && code <= 49, code) + override def toString = "(on " + flip + " background)" +} diff --git a/src/compiler/scala/tools/util/color/CString.scala b/src/compiler/scala/tools/util/color/CString.scala new file mode 100644 index 0000000000..d0785eaeff --- /dev/null +++ b/src/compiler/scala/tools/util/color/CString.scala @@ -0,0 +1,28 @@ +package scala.tools.util +package color + +/** A colorized String. It's difficult to achieve precise + * formatting and selective string colorization simultaneously, + * because all length-based calculations will break down in + * the face of the ansi controls. It doesn't do much yet, but + * this is here to eventually make that transparent. + */ +final class CString(val uncolorized: String, val colorized: String) { + def visibleLength = uncolorized.length + def colorizedLength = colorized.length + def show() = Console println colorized + def bytes() = colorized map (ch => ch.toByte) + def > = show() + + def append(x: CString): CString = new CString(uncolorized + x.uncolorized, colorized + x.colorized) + def +(other: CString): CString = this append other + override def toString = colorized +} + +class CStringOps(str: String) { + /** Enables for example + * println("foo" in Red) + * println("foo" in Magenta.bright) + */ + def in(ansi: Ansi): CString = new CString(str, ansi colorize str) +} diff --git a/src/compiler/scala/tools/util/color/ColorNames.scala b/src/compiler/scala/tools/util/color/ColorNames.scala new file mode 100644 index 0000000000..ff4b01a9df --- /dev/null +++ b/src/compiler/scala/tools/util/color/ColorNames.scala @@ -0,0 +1,391 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2012 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.util.color + +/** Raw data adapted from perl's Term-ExtendedColor, which is published + * under perl's Artistic license: http://dev.perl.org/licenses/artistic.html + * + * These aren't actually in use yet. + */ +trait ColorNames { + type ColorType + def translateCode(ansiCode: String): ColorType + + private implicit def liftAnsiCode(code: String): ColorType = translateCode(code) + + // Possible alternative names or aliases, also from the perl: + // + // reset, clear, normal reset all attributes + // bold, bright bold or bright, depending on implementation + // faint decreased intensity (not widely supported) + // italic, cursive italic or cursive + // underline, underscore underline + // blink slow blink + // blink_ms rapid blink (only supported in MS DOS) + // reverse, inverse, negative reverse video + // conceal conceal, or hide (not widely supported) + + // Brightest to darkest color + val red1: ColorType = "5;196" + val red2: ColorType = "5;160" + val red3: ColorType = "5;124" + val red4: ColorType = "5;088" + val red5: ColorType = "5;052" + + val green1: ColorType = "5;156" + val green2: ColorType = "5;150" + val green3: ColorType = "5;120" + val green4: ColorType = "5;114" + val green5: ColorType = "5;084" + val green6: ColorType = "5;078" + val green7: ColorType = "5;155" + val green8: ColorType = "5;149" + val green9: ColorType = "5;119" + val green10: ColorType = "5;113" + val green11: ColorType = "5;083" + val green12: ColorType = "5;077" + val green13: ColorType = "5;047" + val green14: ColorType = "5;041" + val green15: ColorType = "5;118" + val green16: ColorType = "5;112" + val green17: ColorType = "5;082" + val green18: ColorType = "5;076" + val green19: ColorType = "5;046" + val green20: ColorType = "5;040" + val green21: ColorType = "5;034" + val green22: ColorType = "5;028" + val green23: ColorType = "5;022" + val green24: ColorType = "5;107" + val green25: ColorType = "5;071" + val green26: ColorType = "5;070" + val green27: ColorType = "5;064" + val green28: ColorType = "5;065" + + val blue1: ColorType = "5;075" + val blue2: ColorType = "5;074" + val blue3: ColorType = "5;073" + val blue4: ColorType = "5;039" + val blue5: ColorType = "5;038" + val blue6: ColorType = "5;037" + val blue7: ColorType = "5;033" + val blue8: ColorType = "5;032" + val blue9: ColorType = "5;031" + val blue10: ColorType = "5;027" + val blue11: ColorType = "5;026" + val blue12: ColorType = "5;025" + val blue13: ColorType = "5;021" + val blue14: ColorType = "5;020" + val blue15: ColorType = "5;019" + val blue16: ColorType = "5;018" + val blue17: ColorType = "5;017" + + val yellow1: ColorType = "5;228" + val yellow2: ColorType = "5;222" + val yellow3: ColorType = "5;192" + val yellow4: ColorType = "5;186" + val yellow5: ColorType = "5;227" + val yellow6: ColorType = "5;221" + val yellow7: ColorType = "5;191" + val yellow8: ColorType = "5;185" + val yellow9: ColorType = "5;226" + val yellow10: ColorType = "5;220" + val yellow11: ColorType = "5;190" + val yellow12: ColorType = "5;184" + val yellow13: ColorType = "5;214" + val yellow14: ColorType = "5;178" + val yellow15: ColorType = "5;208" + val yellow16: ColorType = "5;172" + val yellow17: ColorType = "5;202" + val yellow18: ColorType = "5;166" + + val magenta1: ColorType = "5;219" + val magenta2: ColorType = "5;183" + val magenta3: ColorType = "5;218" + val magenta4: ColorType = "5;182" + val magenta5: ColorType = "5;217" + val magenta6: ColorType = "5;181" + val magenta7: ColorType = "5;213" + val magenta8: ColorType = "5;177" + val magenta9: ColorType = "5;212" + val magenta10: ColorType = "5;176" + val magenta11: ColorType = "5;211" + val magenta12: ColorType = "5;175" + val magenta13: ColorType = "5;207" + val magenta14: ColorType = "5;171" + val magenta15: ColorType = "5;205" + val magenta16: ColorType = "5;169" + val magenta17: ColorType = "5;201" + val magenta18: ColorType = "5;165" + val magenta19: ColorType = "5;200" + val magenta20: ColorType = "5;164" + val magenta21: ColorType = "5;199" + val magenta22: ColorType = "5;163" + val magenta23: ColorType = "5;198" + val magenta24: ColorType = "5;162" + val magenta25: ColorType = "5;197" + val magenta26: ColorType = "5;161" + + val gray1: ColorType = "5;255" + val gray2: ColorType = "5;254" + val gray3: ColorType = "5;253" + val gray4: ColorType = "5;252" + val gray5: ColorType = "5;251" + val gray6: ColorType = "5;250" + val gray7: ColorType = "5;249" + val gray8: ColorType = "5;248" + val gray9: ColorType = "5;247" + val gray10: ColorType = "5;246" + val gray11: ColorType = "5;245" + val gray12: ColorType = "5;244" + val gray13: ColorType = "5;243" + val gray14: ColorType = "5;242" + val gray15: ColorType = "5;241" + val gray16: ColorType = "5;240" + val gray17: ColorType = "5;239" + val gray18: ColorType = "5;238" + val gray19: ColorType = "5;237" + val gray20: ColorType = "5;236" + val gray21: ColorType = "5;235" + val gray22: ColorType = "5;234" + val gray23: ColorType = "5;233" + val gray24: ColorType = "5;232" + + val purple1: ColorType = "5;147" + val purple2: ColorType = "5;146" + val purple3: ColorType = "5;145" + val purple4: ColorType = "5;141" + val purple5: ColorType = "5;140" + val purple6: ColorType = "5;139" + val purple7: ColorType = "5;135" + val purple8: ColorType = "5;134" + val purple9: ColorType = "5;133" + val purple10: ColorType = "5;129" + val purple11: ColorType = "5;128" + val purple12: ColorType = "5;127" + val purple13: ColorType = "5;126" + val purple14: ColorType = "5;125" + val purple15: ColorType = "5;111" + val purple16: ColorType = "5;110" + val purple17: ColorType = "5;109" + val purple18: ColorType = "5;105" + val purple19: ColorType = "5;104" + val purple20: ColorType = "5;103" + val purple21: ColorType = "5;099" + val purple22: ColorType = "5;098" + val purple23: ColorType = "5;097" + val purple24: ColorType = "5;096" + val purple25: ColorType = "5;093" + val purple26: ColorType = "5;092" + val purple27: ColorType = "5;091" + val purple28: ColorType = "5;090" + val purple29: ColorType = "5;055" + val purple30: ColorType = "5;054" + + val cyan1: ColorType = "5;159" + val cyan2: ColorType = "5;158" + val cyan3: ColorType = "5;157" + val cyan4: ColorType = "5;153" + val cyan5: ColorType = "5;152" + val cyan6: ColorType = "5;151" + val cyan7: ColorType = "5;123" + val cyan8: ColorType = "5;122" + val cyan9: ColorType = "5;121" + val cyan10: ColorType = "5;117" + val cyan11: ColorType = "5;116" + val cyan12: ColorType = "5;115" + val cyan13: ColorType = "5;087" + val cyan14: ColorType = "5;086" + val cyan15: ColorType = "5;085" + val cyan16: ColorType = "5;081" + val cyan17: ColorType = "5;080" + val cyan18: ColorType = "5;079" + val cyan19: ColorType = "5;051" + val cyan20: ColorType = "5;050" + val cyan21: ColorType = "5;049" + val cyan22: ColorType = "5;045" + val cyan23: ColorType = "5;044" + val cyan24: ColorType = "5;043" + + val orange1: ColorType = "5;208" + val orange2: ColorType = "5;172" + val orange3: ColorType = "5;202" + val orange4: ColorType = "5;166" + val orange5: ColorType = "5;130" + + // Approximations of X11 color mappings + // https://secure.wikimedia.org/wikipedia/en/wiki/X11%20colors + + val aquamarine1: ColorType = "5;086" + val aquamarine3: ColorType = "5;079" + val blueviolet: ColorType = "5;057" + val cadetblue1: ColorType = "5;072" + val cadetblue2: ColorType = "5;073" + val chartreuse1: ColorType = "5;118" + val chartreuse2: ColorType = "5;082" + val chartreuse3: ColorType = "5;070" + val chartreuse4: ColorType = "5;064" + val cornflowerblue: ColorType = "5;069" + val cornsilk1: ColorType = "5;230" + val darkblue: ColorType = "5;018" + val darkcyan: ColorType = "5;036" + val darkgoldenrod: ColorType = "5;136" + val darkgreen: ColorType = "5;022" + val darkkhaki: ColorType = "5;143" + val darkmagenta1: ColorType = "5;090" + val darkmagenta2: ColorType = "5;091" + val darkolivegreen1: ColorType = "5;191" + val darkolivegreen2: ColorType = "5;155" + val darkolivegreen3: ColorType = "5;107" + val darkolivegreen4: ColorType = "5;113" + val darkolivegreen5: ColorType = "5;149" + val darkorange3: ColorType = "5;130" + val darkorange4: ColorType = "5;166" + val darkorange1: ColorType = "5;208" + val darkred1: ColorType = "5;052" + val darkred2: ColorType = "5;088" + val darkseagreen1: ColorType = "5;158" + val darkseagreen2: ColorType = "5;157" + val darkseagreen3: ColorType = "5;150" + val darkseagreen4: ColorType = "5;071" + val darkslategray1: ColorType = "5;123" + val darkslategray2: ColorType = "5;087" + val darkslategray3: ColorType = "5;116" + val darkturquoise: ColorType = "5;044" + val darkviolet: ColorType = "5;128" + val deeppink1: ColorType = "5;198" + val deeppink2: ColorType = "5;197" + val deeppink3: ColorType = "5;162" + val deeppink4: ColorType = "5;125" + val deepskyblue1: ColorType = "5;039" + val deepskyblue2: ColorType = "5;038" + val deepskyblue3: ColorType = "5;031" + val deepskyblue4: ColorType = "5;023" + val dodgerblue1: ColorType = "5;033" + val dodgerblue2: ColorType = "5;027" + val dodgerblue3: ColorType = "5;026" + val gold1: ColorType = "5;220" + val gold3: ColorType = "5;142" + val greenyellow: ColorType = "5;154" + val grey0: ColorType = "5;016" + val grey100: ColorType = "5;231" + val grey11: ColorType = "5;234" + val grey15: ColorType = "5;235" + val grey19: ColorType = "5;236" + val grey23: ColorType = "5;237" + val grey27: ColorType = "5;238" + val grey30: ColorType = "5;239" + val grey3: ColorType = "5;232" + val grey35: ColorType = "5;240" + val grey37: ColorType = "5;059" + val grey39: ColorType = "5;241" + val grey42: ColorType = "5;242" + val grey46: ColorType = "5;243" + val grey50: ColorType = "5;244" + val grey53: ColorType = "5;102" + val grey54: ColorType = "5;245" + val grey58: ColorType = "5;246" + val grey62: ColorType = "5;247" + val grey63: ColorType = "5;139" + val grey66: ColorType = "5;248" + val grey69: ColorType = "5;145" + val grey70: ColorType = "5;249" + val grey74: ColorType = "5;250" + val grey7: ColorType = "5;233" + val grey78: ColorType = "5;251" + val grey82: ColorType = "5;252" + val grey84: ColorType = "5;188" + val grey85: ColorType = "5;253" + val grey89: ColorType = "5;254" + val grey93: ColorType = "5;255" + val honeydew2: ColorType = "5;194" + val hotpink2: ColorType = "5;169" + val hotpink3: ColorType = "5;132" + val hotpink: ColorType = "5;205" + val indianred1: ColorType = "5;203" + val indianred: ColorType = "5;167" + val khaki1: ColorType = "5;228" + val khaki3: ColorType = "5;185" + val lightcoral: ColorType = "5;210" + val lightcyan1: ColorType = "5;195" + val lightcyan3: ColorType = "5;152" + val lightgoldenrod1: ColorType = "5;227" + val lightgoldenrod2: ColorType = "5;186" + val lightgoldenrod3: ColorType = "5;179" + val lightgreen: ColorType = "5;119" + val lightpink1: ColorType = "5;217" + val lightpink3: ColorType = "5;174" + val lightpink4: ColorType = "5;095" + val lightsalmon1: ColorType = "5;216" + val lightsalmon3: ColorType = "5;137" + val lightseagreen: ColorType = "5;037" + val lightskyblue1: ColorType = "5;153" + val lightskyblue3: ColorType = "5;109" + val lightslateblue: ColorType = "5;105" + val lightslategrey: ColorType = "5;103" + val lightsteelblue1: ColorType = "5;189" + val lightsteelblue3: ColorType = "5;146" + val lightsteelblue: ColorType = "5;147" + val lightyellow3: ColorType = "5;187" + val mediumorchid1: ColorType = "5;171" + val mediumorchid3: ColorType = "5;133" + val mediumorchid: ColorType = "5;134" + val mediumpurple1: ColorType = "5;141" + val mediumpurple2: ColorType = "5;135" + val mediumpurple3: ColorType = "5;097" + val mediumpurple4: ColorType = "5;060" + val mediumpurple: ColorType = "5;104" + val mediumspringgreen: ColorType = "5;049" + val mediumturquoise: ColorType = "5;080" + val mediumvioletred: ColorType = "5;126" + val mistyrose1: ColorType = "5;224" + val mistyrose3: ColorType = "5;181" + val navajowhite1: ColorType = "5;223" + val navajowhite3: ColorType = "5;144" + val navyblue: ColorType = "5;017" + val orangered1: ColorType = "5;202" + val orchid1: ColorType = "5;213" + val orchid2: ColorType = "5;212" + val orchid: ColorType = "5;170" + val palegreen1: ColorType = "5;121" + val palegreen3: ColorType = "5;077" + val paleturquoise1: ColorType = "5;159" + val paleturquoise4: ColorType = "5;066" + val palevioletred1: ColorType = "5;211" + val pink1: ColorType = "5;218" + val pink3: ColorType = "5;175" + val plum1: ColorType = "5;219" + val plum2: ColorType = "5;183" + val plum3: ColorType = "5;176" + val plum4: ColorType = "5;096" + val purple: ColorType = "5;129" + val rosybrown: ColorType = "5;138" + val royalblue1: ColorType = "5;063" + val salmon1: ColorType = "5;209" + val sandybrown: ColorType = "5;215" + val seagreen1: ColorType = "5;084" + val seagreen2: ColorType = "5;083" + val seagreen3: ColorType = "5;078" + val skyblue1: ColorType = "5;117" + val skyblue2: ColorType = "5;111" + val skyblue3: ColorType = "5;074" + val slateblue1: ColorType = "5;099" + val slateblue3: ColorType = "5;061" + val springgreen1: ColorType = "5;048" + val springgreen2: ColorType = "5;042" + val springgreen3: ColorType = "5;035" + val springgreen4: ColorType = "5;029" + val steelblue1: ColorType = "5;075" + val steelblue3: ColorType = "5;068" + val steelblue: ColorType = "5;067" + val tan: ColorType = "5;180" + val thistle1: ColorType = "5;225" + val thistle3: ColorType = "5;182" + val turquoise2: ColorType = "5;045" + val turquoise4: ColorType = "5;030" + val violet: ColorType = "5;177" + val wheat1: ColorType = "5;229" + val wheat4: ColorType = "5;101" +} diff --git a/src/compiler/scala/tools/util/color/package.scala b/src/compiler/scala/tools/util/color/package.scala new file mode 100644 index 0000000000..7c7c7dab74 --- /dev/null +++ b/src/compiler/scala/tools/util/color/package.scala @@ -0,0 +1,21 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2012 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.util + +/** + * Wrappers around ansi colors. + * + * @author Paul Phillips + * @version 2.10 + */ +package object color { + implicit def implicitLiftAnsiAtom(c: AnsiAtom): Ansi = new Ansi(List(c)) + implicit def implicitColorToBackground(c: AnsiColor): AnsiBackground = c match { + case x: AnsiBackground => x + case x: AnsiForeground => x.flip + } + implicit def implicitCStringOps(str: String): CStringOps = new CStringOps(str) +} diff --git a/src/library/scala/collection/SeqExtractors.scala b/src/library/scala/collection/SeqExtractors.scala new file mode 100644 index 0000000000..cb3cb27f18 --- /dev/null +++ b/src/library/scala/collection/SeqExtractors.scala @@ -0,0 +1,21 @@ +package scala.collection + +/** An extractor used to head/tail deconstruct sequences. */ +object +: { + def unapply[T,Coll <: SeqLike[T, Coll]]( + t: Coll with SeqLike[T, Coll]): Option[(T, Coll)] = + if(t.isEmpty) None + else Some(t.head -> t.tail) +} + +/** An extractor used to init/last deconstruct sequences. */ +object :+ { + /** Splits a sequence into init :+ tail. + * @returns Some(init, tail) if sequence is non-empty. + * None otherwise. + */ + def unapply[T,Coll <: SeqLike[T, Coll]]( + t: Coll with SeqLike[T, Coll]): Option[(Coll, T)] = + if(t.isEmpty) None + else Some(t.init -> t.last) +} diff --git a/src/library/scala/collection/mutable/Ctrie.scala b/src/library/scala/collection/mutable/ConcurrentTrieMap.scala index cbec118aa9..1a44c8e423 100644 --- a/src/library/scala/collection/mutable/Ctrie.scala +++ b/src/library/scala/collection/mutable/ConcurrentTrieMap.scala @@ -13,7 +13,7 @@ package mutable import java.util.concurrent.atomic._ import collection.immutable.{ ListMap => ImmutableListMap } -import collection.parallel.mutable.ParCtrie +import collection.parallel.mutable.ParConcurrentTrieMap import generic._ import annotation.tailrec import annotation.switch @@ -31,16 +31,16 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends @inline final def CAS(old: MainNode[K, V], n: MainNode[K, V]) = INodeBase.updater.compareAndSet(this, old, n) - final def gcasRead(ct: Ctrie[K, V]): MainNode[K, V] = GCAS_READ(ct) + final def gcasRead(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = GCAS_READ(ct) - @inline final def GCAS_READ(ct: Ctrie[K, V]): MainNode[K, V] = { + @inline final def GCAS_READ(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = { val m = /*READ*/mainnode val prevval = /*READ*/m.prev if (prevval eq null) m else GCAS_Complete(m, ct) } - @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: Ctrie[K, V]): MainNode[K, V] = if (m eq null) null else { + @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = if (m eq null) null else { // complete the GCAS val prev = /*READ*/m.prev val ctr = ct.readRoot(true) @@ -72,7 +72,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends } } - @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: Ctrie[K, V]): Boolean = { + @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): Boolean = { n.WRITE_PREV(old) if (CAS(old, n)) { GCAS_Complete(n, ct) @@ -86,7 +86,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends nin } - final def copyToGen(ngen: Gen, ct: Ctrie[K, V]) = { + final def copyToGen(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = { val nin = new INode[K, V](ngen) val main = GCAS_READ(ct) nin.WRITE(main) @@ -97,7 +97,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends * * @return true if successful, false otherwise */ - @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Boolean = { + @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Boolean = { val m = GCAS_READ(ct) // use -Yinline! m match { @@ -143,7 +143,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends * @param cond null - don't care if the key was there; KEY_ABSENT - key wasn't there; KEY_PRESENT - key was there; other value `v` - key must be bound to `v` * @return null if unsuccessful, Option[V] otherwise (indicating previous value bound to the key) */ - @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Option[V] = { + @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = { val m = GCAS_READ(ct) // use -Yinline! m match { @@ -233,7 +233,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends * * @return null if no value has been found, RESTART if the operation wasn't successful, or any other value otherwise */ - @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): AnyRef = { + @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): AnyRef = { val m = GCAS_READ(ct) // use -Yinline! m match { @@ -276,7 +276,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends * @param v if null, will remove the key irregardless of the value; otherwise removes only if binding contains that exact key and value * @return null if not successful, an Option[V] indicating the previous value otherwise */ - final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Option[V] = { + final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = { val m = GCAS_READ(ct) // use -Yinline! m match { @@ -352,7 +352,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends } } - private def clean(nd: INode[K, V], ct: Ctrie[K, V], lev: Int) { + private def clean(nd: INode[K, V], ct: ConcurrentTrieMap[K, V], lev: Int) { val m = nd.GCAS_READ(ct) m match { case cn: CNode[K, V] => nd.GCAS(cn, cn.toCompressed(ct, lev, gen), ct) @@ -360,9 +360,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends } } - final def isNullInode(ct: Ctrie[K, V]) = GCAS_READ(ct) eq null + final def isNullInode(ct: ConcurrentTrieMap[K, V]) = GCAS_READ(ct) eq null - final def cachedSize(ct: Ctrie[K, V]): Int = { + final def cachedSize(ct: ConcurrentTrieMap[K, V]): Int = { val m = GCAS_READ(ct) m.cachedSize(ct) } @@ -438,7 +438,7 @@ extends MainNode[K, V] { if (updmap.size > 1) new LNode(updmap) else { val (k, v) = updmap.iterator.next - new TNode(k, v, Ctrie.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses + new TNode(k, v, ConcurrentTrieMap.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses } } def get(k: K) = listmap.get(k) @@ -455,7 +455,7 @@ extends CNodeBase[K, V] { val currsz = READ_SIZE() if (currsz != -1) currsz else { - val sz = computeSize(ct.asInstanceOf[Ctrie[K, V]]) + val sz = computeSize(ct.asInstanceOf[ConcurrentTrieMap[K, V]]) while (READ_SIZE() == -1) CAS_SIZE(-1, sz) READ_SIZE() } @@ -466,7 +466,7 @@ extends CNodeBase[K, V] { // => if there are concurrent size computations, they start // at different positions, so they are more likely to // to be independent - private def computeSize(ct: Ctrie[K, V]): Int = { + private def computeSize(ct: ConcurrentTrieMap[K, V]): Int = { var i = 0 var sz = 0 val offset = math.abs(util.Random.nextInt()) % array.length @@ -511,7 +511,7 @@ extends CNodeBase[K, V] { /** Returns a copy of this cnode such that all the i-nodes below it are copied * to the specified generation `ngen`. */ - final def renewed(ngen: Gen, ct: Ctrie[K, V]) = { + final def renewed(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = { var i = 0 val arr = array val len = arr.length @@ -542,7 +542,7 @@ extends CNodeBase[K, V] { // returns the version of this node with at least some null-inodes // removed (those existing when the op began) // - if there are only null-i-nodes below, returns null - final def toCompressed(ct: Ctrie[K, V], lev: Int, gen: Gen) = { + final def toCompressed(ct: ConcurrentTrieMap[K, V], lev: Int, gen: Gen) = { var bmp = bitmap var i = 0 val arr = array @@ -594,7 +594,7 @@ private[mutable] object CNode { val yidx = (yhc >>> lev) & 0x1f val bmp = (1 << xidx) | (1 << yidx) if (xidx == yidx) { - val subinode = new INode[K, V](gen)//(Ctrie.inodeupdater) + val subinode = new INode[K, V](gen)//(ConcurrentTrieMap.inodeupdater) subinode.mainnode = dual(x, xhc, y, yhc, lev + 5, gen) new CNode(bmp, Array(subinode), gen) } else { @@ -613,7 +613,7 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai } -/** A concurrent hash-trie or Ctrie is a concurrent thread-safe lock-free +/** A concurrent hash-trie or ConcurrentTrieMap is a concurrent thread-safe lock-free * implementation of a hash array mapped trie. It is used to implement the * concurrent map abstraction. It has particularly scalable concurrent insert * and remove operations and is memory-efficient. It supports O(1), atomic, @@ -627,20 +627,20 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai * @since 2.10 */ @SerialVersionUID(0L - 6402774413839597105L) -final class Ctrie[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[Ctrie[K, V], AnyRef]) +final class ConcurrentTrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[ConcurrentTrieMap[K, V], AnyRef]) extends ConcurrentMap[K, V] - with MapLike[K, V, Ctrie[K, V]] - with CustomParallelizable[(K, V), ParCtrie[K, V]] + with MapLike[K, V, ConcurrentTrieMap[K, V]] + with CustomParallelizable[(K, V), ParConcurrentTrieMap[K, V]] with Serializable { - import Ctrie.computeHash + import ConcurrentTrieMap.computeHash private var rootupdater = rtupd @volatile var root = r def this() = this( INode.newRootNode, - AtomicReferenceFieldUpdater.newUpdater(classOf[Ctrie[K, V]], classOf[AnyRef], "root") + AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root") ) /* internal methods */ @@ -652,22 +652,22 @@ extends ConcurrentMap[K, V] out.writeObject(k) out.writeObject(v) } - out.writeObject(CtrieSerializationEnd) + out.writeObject(ConcurrentTrieMapSerializationEnd) } private def readObject(in: java.io.ObjectInputStream) { root = INode.newRootNode - rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[Ctrie[K, V]], classOf[AnyRef], "root") + rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root") var obj: AnyRef = null do { obj = in.readObject() - if (obj != CtrieSerializationEnd) { + if (obj != ConcurrentTrieMapSerializationEnd) { val k = obj.asInstanceOf[K] val v = in.readObject().asInstanceOf[V] update(k, v) } - } while (obj != CtrieSerializationEnd) + } while (obj != ConcurrentTrieMapSerializationEnd) } @inline final def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.compareAndSet(this, ov, nv) @@ -760,37 +760,37 @@ extends ConcurrentMap[K, V] override def seq = this - override def par = new ParCtrie(this) + override def par = new ParConcurrentTrieMap(this) - override def empty: Ctrie[K, V] = new Ctrie[K, V] + override def empty: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V] final def isReadOnly = rootupdater eq null final def nonReadOnly = rootupdater ne null - /** Returns a snapshot of this Ctrie. + /** Returns a snapshot of this ConcurrentTrieMap. * This operation is lock-free and linearizable. * * The snapshot is lazily updated - the first time some branch - * in the snapshot or this Ctrie are accessed, they are rewritten. + * in the snapshot or this ConcurrentTrieMap are accessed, they are rewritten. * This means that the work of rebuilding both the snapshot and this - * Ctrie is distributed across all the threads doing updates or accesses + * ConcurrentTrieMap is distributed across all the threads doing updates or accesses * subsequent to the snapshot creation. */ - @tailrec final def snapshot(): Ctrie[K, V] = { + @tailrec final def snapshot(): ConcurrentTrieMap[K, V] = { val r = RDCSS_READ_ROOT() val expmain = r.gcasRead(this) - if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new Ctrie(r.copyToGen(new Gen, this), rootupdater) + if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r.copyToGen(new Gen, this), rootupdater) else snapshot() } - /** Returns a read-only snapshot of this Ctrie. + /** Returns a read-only snapshot of this ConcurrentTrieMap. * This operation is lock-free and linearizable. * * The snapshot is lazily updated - the first time some branch - * of this Ctrie are accessed, it is rewritten. The work of creating + * of this ConcurrentTrieMap are accessed, it is rewritten. The work of creating * the snapshot is thus distributed across subsequent updates - * and accesses on this Ctrie by all threads. + * and accesses on this ConcurrentTrieMap by all threads. * Note that the snapshot itself is never rewritten unlike when calling * the `snapshot` method, but the obtained snapshot cannot be modified. * @@ -799,7 +799,7 @@ extends ConcurrentMap[K, V] @tailrec final def readOnlySnapshot(): collection.Map[K, V] = { val r = RDCSS_READ_ROOT() val expmain = r.gcasRead(this) - if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new Ctrie(r, null) + if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r, null) else readOnlySnapshot() } @@ -872,7 +872,7 @@ extends ConcurrentMap[K, V] def iterator: Iterator[(K, V)] = if (nonReadOnly) readOnlySnapshot().iterator - else new CtrieIterator(0, this) + else new ConcurrentTrieMapIterator(0, this) private def cachedSize() = { val r = RDCSS_READ_ROOT() @@ -883,17 +883,17 @@ extends ConcurrentMap[K, V] if (nonReadOnly) readOnlySnapshot().size else cachedSize() - override def stringPrefix = "Ctrie" + override def stringPrefix = "ConcurrentTrieMap" } -object Ctrie extends MutableMapFactory[Ctrie] { +object ConcurrentTrieMap extends MutableMapFactory[ConcurrentTrieMap] { val inodeupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[INodeBase[_, _]], classOf[MainNode[_, _]], "mainnode") - implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), Ctrie[K, V]] = new MapCanBuildFrom[K, V] + implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), ConcurrentTrieMap[K, V]] = new MapCanBuildFrom[K, V] - def empty[K, V]: Ctrie[K, V] = new Ctrie[K, V] + def empty[K, V]: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V] @inline final def computeHash[K](k: K): Int = { var hcode = k.hashCode @@ -905,7 +905,7 @@ object Ctrie extends MutableMapFactory[Ctrie] { } -private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ctrie[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] { +private[collection] class ConcurrentTrieMapIterator[K, V](var level: Int, private var ct: ConcurrentTrieMap[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] { var stack = new Array[Array[BasicNode]](7) var stackpos = new Array[Int](7) var depth = -1 @@ -971,9 +971,9 @@ private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ct } } else current = null - protected def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new CtrieIterator[K, V](_lev, _ct, _mustInit) + protected def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ConcurrentTrieMapIterator[K, V](_lev, _ct, _mustInit) - protected def dupTo(it: CtrieIterator[K, V]) = { + protected def dupTo(it: ConcurrentTrieMapIterator[K, V]) = { it.level = this.level it.ct = this.ct it.depth = this.depth @@ -993,7 +993,7 @@ private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ct } /** Returns a sequence of iterators over subsets of this iterator. - * It's used to ease the implementation of splitters for a parallel version of the Ctrie. + * It's used to ease the implementation of splitters for a parallel version of the ConcurrentTrieMap. */ protected def subdivide(): Seq[Iterator[(K, V)]] = if (subiter ne null) { // the case where an LNode is being iterated @@ -1043,7 +1043,7 @@ private[mutable] object RestartException extends util.control.ControlThrowable /** Only used for ctrie serialization. */ @SerialVersionUID(0L - 7237891413820527142L) -private[mutable] case object CtrieSerializationEnd +private[mutable] case object ConcurrentTrieMapSerializationEnd private[mutable] object Debug { diff --git a/src/library/scala/collection/parallel/mutable/ParCtrie.scala b/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala index 470972adad..a6495161ea 100644 --- a/src/library/scala/collection/parallel/mutable/ParCtrie.scala +++ b/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala @@ -20,12 +20,12 @@ import scala.collection.mutable.LNode import scala.collection.mutable.CNode import scala.collection.mutable.SNode import scala.collection.mutable.INode -import scala.collection.mutable.Ctrie -import scala.collection.mutable.CtrieIterator +import scala.collection.mutable.ConcurrentTrieMap +import scala.collection.mutable.ConcurrentTrieMapIterator -/** Parallel Ctrie collection. +/** Parallel ConcurrentTrieMap collection. * * It has its bulk operations parallelized, but uses the snapshot operation * to create the splitter. This means that parallel bulk operations can be @@ -34,24 +34,24 @@ import scala.collection.mutable.CtrieIterator * @author Aleksandar Prokopec * @since 2.10 */ -final class ParCtrie[K, V] private[collection] (private val ctrie: Ctrie[K, V]) +final class ParConcurrentTrieMap[K, V] private[collection] (private val ctrie: ConcurrentTrieMap[K, V]) extends ParMap[K, V] - with GenericParMapTemplate[K, V, ParCtrie] - with ParMapLike[K, V, ParCtrie[K, V], Ctrie[K, V]] - with ParCtrieCombiner[K, V] + with GenericParMapTemplate[K, V, ParConcurrentTrieMap] + with ParMapLike[K, V, ParConcurrentTrieMap[K, V], ConcurrentTrieMap[K, V]] + with ParConcurrentTrieMapCombiner[K, V] with Serializable { - def this() = this(new Ctrie) + def this() = this(new ConcurrentTrieMap) - override def mapCompanion: GenericParMapCompanion[ParCtrie] = ParCtrie + override def mapCompanion: GenericParMapCompanion[ParConcurrentTrieMap] = ParConcurrentTrieMap - override def empty: ParCtrie[K, V] = ParCtrie.empty + override def empty: ParConcurrentTrieMap[K, V] = ParConcurrentTrieMap.empty - protected[this] override def newCombiner = ParCtrie.newCombiner + protected[this] override def newCombiner = ParConcurrentTrieMap.newCombiner override def seq = ctrie - def splitter = new ParCtrieSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[Ctrie[K, V]], true) + def splitter = new ParConcurrentTrieMapSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[ConcurrentTrieMap[K, V]], true) override def clear() = ctrie.clear() @@ -87,11 +87,11 @@ extends ParMap[K, V] } } - override def stringPrefix = "ParCtrie" + override def stringPrefix = "ParConcurrentTrieMap" /* tasks */ - /** Computes Ctrie size in parallel. */ + /** Computes ConcurrentTrieMap size in parallel. */ class Size(offset: Int, howmany: Int, array: Array[BasicNode]) extends Task[Int, Size] { var result = -1 def leaf(prev: Option[Int]) = { @@ -118,15 +118,15 @@ extends ParMap[K, V] } -private[collection] class ParCtrieSplitter[K, V](lev: Int, ct: Ctrie[K, V], mustInit: Boolean) -extends CtrieIterator[K, V](lev, ct, mustInit) +private[collection] class ParConcurrentTrieMapSplitter[K, V](lev: Int, ct: ConcurrentTrieMap[K, V], mustInit: Boolean) +extends ConcurrentTrieMapIterator[K, V](lev, ct, mustInit) with IterableSplitter[(K, V)] { // only evaluated if `remaining` is invoked (which is not used by most tasks) lazy val totalsize = ct.par.size var iterated = 0 - protected override def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new ParCtrieSplitter[K, V](_lev, _ct, _mustInit) + protected override def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ParConcurrentTrieMapSplitter[K, V](_lev, _ct, _mustInit) override def shouldSplitFurther[S](coll: collection.parallel.ParIterable[S], parallelismLevel: Int) = { val maxsplits = 3 + Integer.highestOneBit(parallelismLevel) @@ -153,15 +153,15 @@ extends CtrieIterator[K, V](lev, ct, mustInit) } -/** Only used within the `ParCtrie`. */ -private[mutable] trait ParCtrieCombiner[K, V] extends Combiner[(K, V), ParCtrie[K, V]] { +/** Only used within the `ParConcurrentTrieMap`. */ +private[mutable] trait ParConcurrentTrieMapCombiner[K, V] extends Combiner[(K, V), ParConcurrentTrieMap[K, V]] { - def combine[N <: (K, V), NewTo >: ParCtrie[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else { + def combine[N <: (K, V), NewTo >: ParConcurrentTrieMap[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else { throw new UnsupportedOperationException("This shouldn't have been called in the first place.") - val thiz = this.asInstanceOf[ParCtrie[K, V]] - val that = other.asInstanceOf[ParCtrie[K, V]] - val result = new ParCtrie[K, V] + val thiz = this.asInstanceOf[ParConcurrentTrieMap[K, V]] + val that = other.asInstanceOf[ParConcurrentTrieMap[K, V]] + val result = new ParConcurrentTrieMap[K, V] result ++= thiz.iterator result ++= that.iterator @@ -174,13 +174,13 @@ private[mutable] trait ParCtrieCombiner[K, V] extends Combiner[(K, V), ParCtrie[ } -object ParCtrie extends ParMapFactory[ParCtrie] { +object ParConcurrentTrieMap extends ParMapFactory[ParConcurrentTrieMap] { - def empty[K, V]: ParCtrie[K, V] = new ParCtrie[K, V] + def empty[K, V]: ParConcurrentTrieMap[K, V] = new ParConcurrentTrieMap[K, V] - def newCombiner[K, V]: Combiner[(K, V), ParCtrie[K, V]] = new ParCtrie[K, V] + def newCombiner[K, V]: Combiner[(K, V), ParConcurrentTrieMap[K, V]] = new ParConcurrentTrieMap[K, V] - implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParCtrie[K, V]] = new CanCombineFromMap[K, V] + implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParConcurrentTrieMap[K, V]] = new CanCombineFromMap[K, V] } diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 366af34ee9..1ef1911fd3 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -64,6 +64,9 @@ package object scala { type ::[A] = scala.collection.immutable.::[A] val :: = scala.collection.immutable.:: + val +: = scala.collection.+: + val :+ = scala.collection.:+ + type Stream[+A] = scala.collection.immutable.Stream[A] val Stream = scala.collection.immutable.Stream val #:: = scala.collection.immutable.Stream.#:: diff --git a/src/library/scala/reflect/api/Modifier.scala b/src/library/scala/reflect/api/Modifier.scala index cbfe91e59b..1b67929e15 100644 --- a/src/library/scala/reflect/api/Modifier.scala +++ b/src/library/scala/reflect/api/Modifier.scala @@ -2,7 +2,7 @@ package scala.reflect.api import collection.{ immutable, mutable } -sealed abstract class Modifier { +abstract class Modifier private[api] () { def name: String def isKeyword: Boolean def sourceString: String = if (isKeyword) "`" + name + "`" else name diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala index 21b55e9c0e..43865915d3 100644 --- a/src/library/scala/reflect/api/TreePrinters.scala +++ b/src/library/scala/reflect/api/TreePrinters.scala @@ -41,7 +41,7 @@ trait TreePrinters { self: Universe => else if (tree.original != null) print(".setOriginal(", tree.original, ")") case tree: Tree => - print(tree.productPrefix+"(") + print(tree.printingPrefix+"(") val it = tree.productIterator while (it.hasNext) { it.next() match { diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index a355207ff0..a8276dc853 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -76,6 +76,12 @@ trait Trees { self: Universe => private[this] var rawpos: Position = NoPosition + /** Prefix under which to print this tree type. Defaults to product + * prefix (e.g. DefTree) but because that is used in reification + * it cannot be altered without breaking reflection. + */ + def printingPrefix = productPrefix + def pos = rawpos def pos_=(pos: Position) = rawpos = pos def setPos(pos: Position): this.type = { rawpos = pos; this } @@ -249,6 +255,7 @@ trait Trees { self: Universe => * are in DefTrees. */ trait RefTree extends SymTree { + def qualifier: Tree // empty for Idents def name: Name } @@ -489,16 +496,14 @@ trait Trees { self: Universe => /** Factory method for object creation `new tpt(args_1)...(args_n)` * A `New(t, as)` is expanded to: `(new t).<init>(as)` */ - def New(tpt: Tree, argss: List[List[Tree]]): Tree = { - // todo. we need to expose names in scala.reflect.api - val superRef: Tree = Select(New(tpt), nme.CONSTRUCTOR) - if (argss.isEmpty) Apply(superRef, Nil) - else (superRef /: argss) (Apply) + def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match { + case Nil => new ApplyConstructor(tpt, Nil) + case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply) } /** 0-1 argument list new, based on a type. */ def New(tpe: Type, args: Tree*): Tree = - New(TypeTree(tpe), List(args.toList)) + new ApplyConstructor(TypeTree(tpe), args.toList) /** Type annotation, eliminated by explicit outer */ case class Typed(expr: Tree, tpt: Tree) @@ -537,6 +542,10 @@ trait Trees { self: Universe => class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args) + class ApplyConstructor(tpt: Tree, args: List[Tree]) extends Apply(Select(New(tpt), nme.CONSTRUCTOR), args) { + override def printingPrefix = "ApplyConstructor" + } + /** Dynamic value application. * In a dynamic application q.f(as) * - q is stored in qual @@ -575,7 +584,9 @@ trait Trees { self: Universe => Select(qualifier, sym.name) setSymbol sym /** Identifier <name> */ - case class Ident(name: Name) extends RefTree + case class Ident(name: Name) extends RefTree { + def qualifier: Tree = EmptyTree + } def Ident(name: String): Ident = Ident(newTermName(name)) diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index 0c7772cd07..38ca89b98b 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -72,10 +72,11 @@ private[scala] trait PropertiesTrait { * it is an RC, Beta, etc. or was built from source, or if the version * cannot be read. */ - val releaseVersion = scalaPropOrNone("version.number") flatMap { s => - val segments = s split '.' - if (segments.size == 4 && segments.last == "final") Some(segments take 3 mkString ".") else None - } + val releaseVersion = + for { + v <- scalaPropOrNone("maven.version.number") + if !(v endsWith "-SNAPSHOT") + } yield v /** The development Scala version, if this is not a final release. * The precise contents are not guaranteed, but it aims to provide a @@ -85,15 +86,12 @@ private[scala] trait PropertiesTrait { * @return Some(version) if this is a non-final version, None if this * is a final release or the version cannot be read. */ - val developmentVersion = scalaPropOrNone("version.number") flatMap { s => - val segments = s split '.' - if (segments.isEmpty || segments.last == "final") - None - else if (segments.last startsWith "r") - Some(s takeWhile (ch => ch != '-')) // Cutting e.g. 2.10.0.r24774-b20110417125606 to 2.10.0.r24774 - else - Some(s) - } + val developmentVersion = + for { + v <- scalaPropOrNone("maven.version.number") + if v endsWith "-SNAPSHOT" + ov <- scalaPropOrNone("version.number") + } yield ov /** Either the development or release version if known, otherwise * the empty string. diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala index df52b34f87..cc244a5b88 100644..100755 --- a/src/library/scala/xml/Elem.scala +++ b/src/library/scala/xml/Elem.scala @@ -17,8 +17,18 @@ package scala.xml * @author Burak Emir <bqe@google.com> */ object Elem { - def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*) = - new Elem(prefix, label, attributes, scope, child:_*) + /** Build an Elem, setting its minimizeEmpty property to <code>true</code> if it has no children. Note that this + * default may not be exactly what you want, as some XML dialects don't permit some elements to be minimized. + * + * @deprecated This factory method is retained for backward compatibility; please use the other one, with which you + * can specify your own preference for minimizeEmpty. + */ + @deprecated + def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*): Elem = + apply(prefix, label, attributes, scope, child.isEmpty, child: _*) + + def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, child: Node*): Elem = + new Elem(prefix,label,attributes,scope, minimizeEmpty, child:_*) def unapplySeq(n: Node) = n match { case _: SpecialNode | _: Group => None @@ -29,11 +39,13 @@ object Elem { /** The case class `Elem` extends the `Node` class, * providing an immutable data object representing an XML element. * - * @param prefix namespace prefix (may be null, but not the empty string) - * @param label the element name - * @param attribute the attribute map - * @param scope the scope containing the namespace bindings - * @param child the children of this node + * @param prefix namespace prefix (may be null, but not the empty string) + * @param label the element name + * @param attributes1 the attribute map + * @param scope the scope containing the namespace bindings + * @param minimizeEmpty `true` if this element should be serialized as minimized (i.e. "<el/>") when + * empty; `false` if it should be written out in long form. + * @param child the children of this node * * Copyright 2008 Google Inc. All Rights Reserved. * @author Burak Emir <bqe@google.com> @@ -43,9 +55,15 @@ class Elem( val label: String, attributes1: MetaData, override val scope: NamespaceBinding, + val minimizeEmpty: Boolean, val child: Node*) extends Node with Serializable { + @deprecated("This constructor is retained for backward compatibility. Please use the primary constructor, which lets you specify your own preference for `minimizeEmpty`.", "2.10") + def this(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*) = { + this(prefix, label, attributes, scope, child.isEmpty, child: _*) + } + final override def doCollectNamespaces = true final override def doTransform = true @@ -83,8 +101,9 @@ extends Node with Serializable label: String = this.label, attributes: MetaData = this.attributes, scope: NamespaceBinding = this.scope, + minimizeEmpty: Boolean = this.minimizeEmpty, child: Seq[Node] = this.child.toSeq - ): Elem = Elem(prefix, label, attributes, scope, child: _*) + ): Elem = Elem(prefix, label, attributes, scope, minimizeEmpty, child: _*) /** Returns concatenation of `text(n)` for each child `n`. */ diff --git a/src/library/scala/xml/Node.scala b/src/library/scala/xml/Node.scala index 2ead18fe08..02e34e1bdc 100644..100755 --- a/src/library/scala/xml/Node.scala +++ b/src/library/scala/xml/Node.scala @@ -159,7 +159,7 @@ abstract class Node extends NodeSeq { * @return ... */ def buildString(stripComments: Boolean): String = - Utility.toXML(this, stripComments = stripComments).toString + Utility.serialize(this, stripComments = stripComments).toString /** * Same as `toString('''false''')`. diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/library/scala/xml/PrettyPrinter.scala index ea39b51352..64dbd00f2f 100644..100755 --- a/src/library/scala/xml/PrettyPrinter.scala +++ b/src/library/scala/xml/PrettyPrinter.scala @@ -161,7 +161,7 @@ class PrettyPrinter(width: Int, step: Int) { case _ => val test = { val sb = new StringBuilder() - Utility.toXML(node, pscope, sb, false) + Utility.serialize(node, pscope, sb, false) if (doPreserve(node)) sb.toString else TextBuffer.fromString(sb.toString).toText(0).data } diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index fc20b892b9..9f944c0e92 100644..100755 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -181,6 +181,13 @@ object Utility extends AnyRef with parsing.TokenTests { // sb.toString() // } + /** + * Serialize the provided Node to the provided StringBuilder. + * <p/> + * Note that calling this source-compatible method will result in the same old, arguably almost universally unwanted, + * behaviour. + */ + @deprecated("Please use `serialize` instead and specify a `minimizeTags` parameter", "2.10") def toXML( x: Node, pscope: NamespaceBinding = TopScope, @@ -190,29 +197,51 @@ object Utility extends AnyRef with parsing.TokenTests { preserveWhitespace: Boolean = false, minimizeTags: Boolean = false): StringBuilder = { + serialize(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, if (minimizeTags) MinimizeMode.Always else MinimizeMode.Never) + } + + /** + * Serialize an XML Node to a StringBuilder. + * + * This is essentially a minor rework of `toXML` that can't have the same name due to an unfortunate + * combination of named/default arguments and overloading. + * + * @todo use a Writer instead + */ + def serialize( + x: Node, + pscope: NamespaceBinding = TopScope, + sb: StringBuilder = new StringBuilder, + stripComments: Boolean = false, + decodeEntities: Boolean = true, + preserveWhitespace: Boolean = false, + minimizeTags: MinimizeMode.Value = MinimizeMode.Default): StringBuilder = + { x match { - case c: Comment => if (!stripComments) c buildString sb else sb - case x: SpecialNode => x buildString sb - case g: Group => - g.nodes foreach {toXML(_, x.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)} - sb - case _ => + case c: Comment if !stripComments => c buildString sb + case s: SpecialNode => s buildString sb + case g: Group => for (c <- g.nodes) serialize(c, g.scope, sb, minimizeTags = minimizeTags) ; sb + case el: Elem => // print tag with namespace declarations sb.append('<') - x.nameToString(sb) - if (x.attributes ne null) x.attributes.buildString(sb) - x.scope.buildString(sb, pscope) - if (x.child.isEmpty && minimizeTags) { + el.nameToString(sb) + if (el.attributes ne null) el.attributes.buildString(sb) + el.scope.buildString(sb, pscope) + if (el.child.isEmpty && + (minimizeTags == MinimizeMode.Always || + (minimizeTags == MinimizeMode.Default && el.minimizeEmpty))) + { // no children, so use short form: <xyz .../> - sb.append(" />") + sb.append("/>") } else { // children, so use long form: <xyz ...>...</xyz> sb.append('>') - sequenceToXML(x.child, x.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) + sequenceToXML(el.child, el.scope, sb, stripComments) sb.append("</") - x.nameToString(sb) + el.nameToString(sb) sb.append('>') } + case _ => throw new IllegalArgumentException("Don't know how to serialize a " + x.getClass.getName) } } @@ -223,20 +252,20 @@ object Utility extends AnyRef with parsing.TokenTests { stripComments: Boolean = false, decodeEntities: Boolean = true, preserveWhitespace: Boolean = false, - minimizeTags: Boolean = false): Unit = + minimizeTags: MinimizeMode.Value = MinimizeMode.Default): Unit = { if (children.isEmpty) return else if (children forall isAtomAndNotText) { // add space val it = children.iterator val f = it.next - toXML(f, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) + serialize(f, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) while (it.hasNext) { val x = it.next sb.append(' ') - toXML(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) + serialize(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) } } - else children foreach { toXML(_, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) } + else children foreach { serialize(_, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) } } /** diff --git a/src/library/scala/xml/XML.scala b/src/library/scala/xml/XML.scala index bc3033d081..4beba91899 100644..100755 --- a/src/library/scala/xml/XML.scala +++ b/src/library/scala/xml/XML.scala @@ -26,6 +26,21 @@ object Source def fromSysId(sysID: String) = new InputSource(sysID) def fromString(string: String) = fromReader(new StringReader(string)) } + +/** + * Governs how empty elements (i.e. those without child elements) should be serialized. + */ +object MinimizeMode extends Enumeration { + /** Minimize empty tags if they were originally empty when parsed, or if they were constructed with [[scala.xml.Elem]]`#minimizeEmpty` == true */ + val Default = Value + + /** Always minimize empty tags. Note that this may be problematic for XHTML, in which case [[scala.xml.Xhtml]]`#toXhtml` should be used instead. */ + val Always = Value + + /** Never minimize empty tags. */ + val Never = Value +} + import Source._ /** The object `XML` provides constants, and functions to load @@ -83,10 +98,10 @@ object XML extends XMLLoader[Elem] * @param xmlDecl if true, write xml declaration * @param doctype if not null, write doctype declaration */ - final def write(w: java.io.Writer, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType) { + final def write(w: java.io.Writer, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType, minimizeTags: MinimizeMode.Value = MinimizeMode.Default) { /* TODO: optimize by giving writer parameter to toXML*/ if (xmlDecl) w.write("<?xml version='1.0' encoding='" + enc + "'?>\n") if (doctype ne null) w.write( doctype.toString() + "\n") - w.write(Utility.toXML(node).toString) + w.write(Utility.serialize(node, minimizeTags = minimizeTags).toString) } } diff --git a/src/library/scala/xml/factory/Binder.scala b/src/library/scala/xml/factory/Binder.scala index a8b0ed585b..b4fe153bd8 100644..100755 --- a/src/library/scala/xml/factory/Binder.scala +++ b/src/library/scala/xml/factory/Binder.scala @@ -43,13 +43,13 @@ abstract class Binder(val preserveWS: Boolean) extends ValidatingMarkupHandler { result &+ text(0, x.data) case x:EntityRef => result &+ entityRef(0, x.entityName) - case _ => - elemStart(0, n.prefix, n.label, n.attributes, n.scope) + case x:Elem => + elemStart(0, x.prefix, x.label, x.attributes, x.scope) val old = result result = new NodeBuffer() - for (m <- n.child) traverse(m) - result = old &+ elem(0, n.prefix, n.label, n.attributes, n.scope, NodeSeq.fromSeq(result)).toList; - elemEnd(0, n.prefix, n.label) + for (m <- x.child) traverse(m) + result = old &+ elem(0, x.prefix, x.label, x.attributes, x.scope, x.minimizeEmpty, NodeSeq.fromSeq(result)).toList; + elemEnd(0, x.prefix, x.label) } final def validate(n: Node): Node = { diff --git a/src/library/scala/xml/parsing/ConstructingHandler.scala b/src/library/scala/xml/parsing/ConstructingHandler.scala index 60c19138c3..7e61674682 100644..100755 --- a/src/library/scala/xml/parsing/ConstructingHandler.scala +++ b/src/library/scala/xml/parsing/ConstructingHandler.scala @@ -21,8 +21,8 @@ abstract class ConstructingHandler extends MarkupHandler val preserveWS: Boolean def elem(pos: Int, pre: String, label: String, attrs: MetaData, - pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq = - Elem(pre, label, attrs, pscope, nodes:_*) + pscope: NamespaceBinding, empty: Boolean, nodes: NodeSeq): NodeSeq = + Elem(pre, label, attrs, pscope, empty, nodes:_*) def procInstr(pos: Int, target: String, txt: String) = ProcInstr(target, txt) diff --git a/src/library/scala/xml/parsing/DefaultMarkupHandler.scala b/src/library/scala/xml/parsing/DefaultMarkupHandler.scala index 699c5b2b5f..e0258ba781 100644..100755 --- a/src/library/scala/xml/parsing/DefaultMarkupHandler.scala +++ b/src/library/scala/xml/parsing/DefaultMarkupHandler.scala @@ -16,7 +16,7 @@ package parsing abstract class DefaultMarkupHandler extends MarkupHandler { def elem(pos: Int, pre: String, label: String, attrs: MetaData, - scope:NamespaceBinding, args: NodeSeq) = NodeSeq.Empty + scope:NamespaceBinding, empty: Boolean, args: NodeSeq) = NodeSeq.Empty def procInstr(pos: Int, target: String, txt: String) = NodeSeq.Empty diff --git a/src/library/scala/xml/parsing/MarkupHandler.scala b/src/library/scala/xml/parsing/MarkupHandler.scala index 87e785a98f..83db2f177d 100644..100755 --- a/src/library/scala/xml/parsing/MarkupHandler.scala +++ b/src/library/scala/xml/parsing/MarkupHandler.scala @@ -75,10 +75,11 @@ abstract class MarkupHandler extends Logged * @param pre the prefix * @param label the local name * @param attrs the attributes (metadata) + * @param empty `true` if the element was previously empty; `false` otherwise. * @param args the children of this element * @return ... */ - def elem(pos: Int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding, args: NodeSeq): NodeSeq + def elem(pos: Int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding, empty: Boolean, args: NodeSeq): NodeSeq /** callback method invoked by MarkupParser after parsing PI. */ diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/library/scala/xml/parsing/MarkupParser.scala index 74781914e3..af9b5f47cf 100644..100755 --- a/src/library/scala/xml/parsing/MarkupParser.scala +++ b/src/library/scala/xml/parsing/MarkupParser.scala @@ -569,7 +569,7 @@ trait MarkupParser extends MarkupParserCommon with TokenTests tmp } } - val res = handle.elem(pos, pre, local, aMap, scope, ts) + val res = handle.elem(pos, pre, local, aMap, scope, ts == NodeSeq.Empty, ts) handle.elemEnd(pos, pre, local) res } diff --git a/src/library/scala/xml/pull/XMLEventReader.scala b/src/library/scala/xml/pull/XMLEventReader.scala index f84d91d138..c764d042c8 100755 --- a/src/library/scala/xml/pull/XMLEventReader.scala +++ b/src/library/scala/xml/pull/XMLEventReader.scala @@ -81,7 +81,7 @@ extends collection.AbstractIterator[XMLEvent] // memory usage optimization return one <ignore/> for top level to satisfy // MarkupParser.document() otherwise NodeSeq.Empty private var ignoreWritten = false - final def elem(pos: Int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq = + final def elem(pos: Int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, empty: Boolean, nodes: NodeSeq): NodeSeq = if (level == 1 && !ignoreWritten) {ignoreWritten = true; <ignore/> } else NodeSeq.Empty def procInstr(pos: Int, target: String, txt: String) = setEvent(EvProcInstr(target, txt)) diff --git a/src/partest/scala/tools/partest/CompilerTest.scala b/src/partest/scala/tools/partest/CompilerTest.scala index 1cb09b433a..994928c0f6 100644 --- a/src/partest/scala/tools/partest/CompilerTest.scala +++ b/src/partest/scala/tools/partest/CompilerTest.scala @@ -19,9 +19,42 @@ abstract class CompilerTest extends DirectTest { lazy val global: Global = newCompiler() lazy val units = compilationUnits(global)(sources: _ *) + import global._ + import definitions._ override def extraSettings = "-usejavacp -d " + testOutput.path - def sources: List[String] = List(code) def show() = (sources, units).zipped foreach check + + // Override at least one of these... + def code = "" + def sources: List[String] = List(code) + + // Utility functions + + class MkType(sym: Symbol) { + def apply[M](implicit m1: Manifest[M]): Type = + if (sym eq NoSymbol) NoType + else appliedType(sym.typeConstructor, List(m1) map (x => manifestToType(x))) + } + implicit def mkMkType(sym: Symbol) = new MkType(sym) + + def allMembers(root: Symbol): List[Symbol] = { + def loop(seen: Set[Symbol], roots: List[Symbol]): List[Symbol] = { + val latest = roots flatMap (_.info.members) filterNot (seen contains _) + if (latest.isEmpty) seen.toList.sortWith(_ isLess _) + else loop(seen ++ latest, latest) + } + loop(Set(), List(root)) + } + + class SymsInPackage(pkgName: String) { + def pkg = getRequiredModule(pkgName) + def classes = allMembers(pkg) filter (_.isClass) + def modules = allMembers(pkg) filter (_.isModule) + def symbols = classes ++ terms filterNot (_ eq NoSymbol) + def terms = allMembers(pkg) filter (s => s.isTerm && !s.isConstructor) + def tparams = classes flatMap (_.info.typeParams) + def tpes = symbols map (_.tpe) distinct + } } diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala index 07444f8d4b..4e7f36bdc9 100644 --- a/src/partest/scala/tools/partest/DirectTest.scala +++ b/src/partest/scala/tools/partest/DirectTest.scala @@ -69,7 +69,7 @@ abstract class DirectTest extends App { /** Constructor/main body **/ try show() - catch { case t => println(t) ; sys.exit(1) } + catch { case t => println(t) ; t.printStackTrace ; sys.exit(1) } /** Debugger interest only below this line **/ protected def isDebug = (sys.props contains "partest.debug") || (sys.env contains "PARTEST_DEBUG") diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala index 524dc06327..ad2e155182 100644 --- a/src/partest/scala/tools/partest/PartestTask.scala +++ b/src/partest/scala/tools/partest/PartestTask.scala @@ -299,6 +299,16 @@ class PartestTask extends Task with CompilationPathProperty { } } getOrElse sys.error("Provided classpath does not contain a Scala partest.") + val scalaActors = { + (classpath.list map { fs => new File(fs) }) find { f => + f.getName match { + case "scala-actors.jar" => true + case "actors" if (f.getParentFile.getName == "classes") => true + case _ => false + } + } + } getOrElse sys.error("Provided classpath does not contain a Scala actors.") + def scalacArgsFlat: Option[Seq[String]] = scalacArgs map (_ flatMap { a => val parts = a.getParts if(parts eq null) Seq[String]() else parts.toSeq @@ -324,6 +334,7 @@ class PartestTask extends Task with CompilationPathProperty { antFileManager.LATEST_LIB = scalaLibrary.getAbsolutePath antFileManager.LATEST_COMP = scalaCompiler.getAbsolutePath antFileManager.LATEST_PARTEST = scalaPartest.getAbsolutePath + antFileManager.LATEST_ACTORS = scalaActors.getAbsolutePath javacmd foreach (x => antFileManager.JAVACMD = x.getAbsolutePath) javaccmd foreach (x => antFileManager.JAVAC_CMD = x.getAbsolutePath) diff --git a/src/partest/scala/tools/partest/nest/AntRunner.scala b/src/partest/scala/tools/partest/nest/AntRunner.scala index 4795e5551a..e77385d6e9 100644 --- a/src/partest/scala/tools/partest/nest/AntRunner.scala +++ b/src/partest/scala/tools/partest/nest/AntRunner.scala @@ -22,6 +22,7 @@ class AntRunner extends DirectRunner { var LATEST_LIB: String = _ var LATEST_COMP: String = _ var LATEST_PARTEST: String = _ + var LATEST_ACTORS: String = _ val testRootPath: String = "test" val testRootDir: Directory = Directory(testRootPath) } diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala index 3d72227b04..fa533eeb10 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala @@ -83,6 +83,7 @@ class ConsoleFileManager extends FileManager { latestFile = testClassesDir.parent / "bin" latestLibFile = testClassesDir / "library" + latestActorsFile = testClassesDir / "library" / "actors" latestCompFile = testClassesDir / "compiler" latestPartestFile = testClassesDir / "partest" latestFjbgFile = testParent / "lib" / "fjbg.jar" @@ -92,6 +93,7 @@ class ConsoleFileManager extends FileManager { NestUI.verbose("Running on "+dir) latestFile = dir / "bin" latestLibFile = dir / "lib/scala-library.jar" + latestActorsFile = dir / "lib/scala-actors.jar" latestCompFile = dir / "lib/scala-compiler.jar" latestPartestFile = dir / "lib/scala-partest.jar" } @@ -100,6 +102,7 @@ class ConsoleFileManager extends FileManager { NestUI.verbose("Running build/quick") latestFile = prefixFile("build/quick/bin") latestLibFile = prefixFile("build/quick/classes/library") + latestActorsFile = prefixFile("build/quick/classes/library/actors") latestCompFile = prefixFile("build/quick/classes/compiler") latestPartestFile = prefixFile("build/quick/classes/partest") } @@ -109,6 +112,7 @@ class ConsoleFileManager extends FileManager { val p = testParent.getParentFile latestFile = prefixFileWith(p, "bin") latestLibFile = prefixFileWith(p, "lib/scala-library.jar") + latestActorsFile = prefixFileWith(p, "lib/scala-actors.jar") latestCompFile = prefixFileWith(p, "lib/scala-compiler.jar") latestPartestFile = prefixFileWith(p, "lib/scala-partest.jar") } @@ -117,6 +121,7 @@ class ConsoleFileManager extends FileManager { NestUI.verbose("Running dists/latest") latestFile = prefixFile("dists/latest/bin") latestLibFile = prefixFile("dists/latest/lib/scala-library.jar") + latestActorsFile = prefixFile("dists/latest/lib/scala-actors.jar") latestCompFile = prefixFile("dists/latest/lib/scala-compiler.jar") latestPartestFile = prefixFile("dists/latest/lib/scala-partest.jar") } @@ -125,6 +130,7 @@ class ConsoleFileManager extends FileManager { NestUI.verbose("Running build/pack") latestFile = prefixFile("build/pack/bin") latestLibFile = prefixFile("build/pack/lib/scala-library.jar") + latestActorsFile = prefixFile("build/pack/lib/scala-actors.jar") latestCompFile = prefixFile("build/pack/lib/scala-compiler.jar") latestPartestFile = prefixFile("build/pack/lib/scala-partest.jar") } @@ -159,14 +165,17 @@ class ConsoleFileManager extends FileManager { LATEST_LIB = latestLibFile.getAbsolutePath LATEST_COMP = latestCompFile.getAbsolutePath LATEST_PARTEST = latestPartestFile.getAbsolutePath + LATEST_ACTORS = latestActorsFile.getAbsolutePath } var LATEST_LIB: String = "" var LATEST_COMP: String = "" var LATEST_PARTEST: String = "" + var LATEST_ACTORS: String = "" var latestFile: File = _ var latestLibFile: File = _ + var latestActorsFile: File = _ var latestCompFile: File = _ var latestPartestFile: File = _ var latestFjbgFile: File = _ diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala index d3d50ca58c..20f435cfbb 100644 --- a/src/partest/scala/tools/partest/nest/DirectRunner.scala +++ b/src/partest/scala/tools/partest/nest/DirectRunner.scala @@ -57,13 +57,14 @@ trait DirectRunner { // for example, see how it's done in ReflectiveRunner //val consFM = new ConsoleFileManager //import consFM.{ latestCompFile, latestLibFile, latestPartestFile } - val latestCompFile = new File(fileManager.LATEST_COMP); - val latestLibFile = new File(fileManager.LATEST_LIB); - val latestPartestFile = new File(fileManager.LATEST_PARTEST); + val latestCompFile = new File(fileManager.LATEST_COMP) + val latestLibFile = new File(fileManager.LATEST_LIB) + val latestPartestFile = new File(fileManager.LATEST_PARTEST) + val latestActorsFile = new File(fileManager.LATEST_ACTORS) val scalacheckURL = PathSettings.scalaCheck.toURL val scalaCheckParentClassLoader = ScalaClassLoader.fromURLs( - List(scalacheckURL, latestCompFile.toURI.toURL, latestLibFile.toURI.toURL, latestPartestFile.toURI.toURL) + scalacheckURL :: (List(latestCompFile, latestLibFile, latestActorsFile, latestPartestFile).map(_.toURI.toURL)) ) Output.init() diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala index a4a94fe93e..6d9e64730f 100644 --- a/src/partest/scala/tools/partest/nest/FileManager.scala +++ b/src/partest/scala/tools/partest/nest/FileManager.scala @@ -62,6 +62,7 @@ trait FileManager extends FileUtil { var LATEST_LIB: String var LATEST_COMP: String var LATEST_PARTEST: String + var LATEST_ACTORS: String var showDiff = false var updateCheck = false diff --git a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala index 5cde63dc81..a0511774a9 100644 --- a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala +++ b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala @@ -48,9 +48,9 @@ class ReflectiveRunner { new ConsoleFileManager import fileManager. - { latestCompFile, latestLibFile, latestPartestFile, latestFjbgFile, latestScalapFile } + { latestCompFile, latestLibFile, latestPartestFile, latestFjbgFile, latestScalapFile, latestActorsFile } val files = - Array(latestCompFile, latestLibFile, latestPartestFile, latestFjbgFile, latestScalapFile) map (x => io.File(x)) + Array(latestCompFile, latestLibFile, latestPartestFile, latestFjbgFile, latestScalapFile, latestActorsFile) map (x => io.File(x)) val sepUrls = files map (_.toURL) var sepLoader = new URLClassLoader(sepUrls, null) diff --git a/src/partest/scala/tools/partest/nest/SBTRunner.scala b/src/partest/scala/tools/partest/nest/SBTRunner.scala index 4c6f417df5..750e270c18 100644 --- a/src/partest/scala/tools/partest/nest/SBTRunner.scala +++ b/src/partest/scala/tools/partest/nest/SBTRunner.scala @@ -15,6 +15,7 @@ object SBTRunner extends DirectRunner { var LATEST_LIB: String = _ var LATEST_COMP: String = _ var LATEST_PARTEST: String = _ + var LATEST_ACTORS: String = _ val testRootPath: String = "test" val testRootDir: Directory = Directory(testRootPath) } @@ -60,6 +61,9 @@ object SBTRunner extends DirectRunner { fileManager.LATEST_COMP = comp getOrElse sys.error("No scala-compiler found! Classpath = " + fileManager.CLASSPATH) val partest: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-partest.*\\.jar")).headOption fileManager.LATEST_PARTEST = partest getOrElse sys.error("No scala-partest found! Classpath = " + fileManager.CLASSPATH) + val actors: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-actors.*\\.jar")).headOption + fileManager.LATEST_ACTORS = actors getOrElse sys.error("No scala-actors found! Classpath = " + fileManager.CLASSPATH) + // TODO - Do something useful here!!! fileManager.JAVAC_CMD = "javac" fileManager.failed = config.justFailedTests diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index 3f2cb16082..cb6f2a0edc 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -55,6 +55,7 @@ class ScalaCheckFileManager(val origmanager: FileManager) extends FileManager { var LATEST_LIB: String = origmanager.LATEST_LIB var LATEST_COMP: String = origmanager.LATEST_COMP var LATEST_PARTEST: String = origmanager.LATEST_PARTEST + var LATEST_ACTORS: String = origmanager.LATEST_ACTORS } object Output { diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 196a769a17..243c9aa3be 100644..100755 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -301,7 +301,7 @@ scala> <a> /></a> res8: scala.xml.Elem = <a> -<b c="c" d="dd"></b></a> +<b c="c" d="dd"/></a> scala> diff --git a/test/files/jvm/serialization.check b/test/files/jvm/serialization.check index 81b68f0f5d..0b8055a6b9 100644 --- a/test/files/jvm/serialization.check +++ b/test/files/jvm/serialization.check @@ -192,8 +192,8 @@ x = TreeSet(1, 2, 3) y = TreeSet(1, 2, 3) x equals y: true, y equals x: true -x = Ctrie(1 -> one, 2 -> two, 3 -> three) -y = Ctrie(1 -> one, 2 -> two, 3 -> three) +x = ConcurrentTrieMap(1 -> one, 2 -> two, 3 -> three) +y = ConcurrentTrieMap(1 -> one, 2 -> two, 3 -> three) x equals y: true, y equals x: true x = xml:src="hello" @@ -287,8 +287,8 @@ x = ParHashMap(2 -> 4, 1 -> 2) y = ParHashMap(2 -> 4, 1 -> 2) x equals y: true, y equals x: true -x = ParCtrie(1 -> 2, 2 -> 4) -y = ParCtrie(1 -> 2, 2 -> 4) +x = ParConcurrentTrieMap(1 -> 2, 2 -> 4) +y = ParConcurrentTrieMap(1 -> 2, 2 -> 4) x equals y: true, y equals x: true x = ParHashSet(1, 2, 3) diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala index 75daa8903d..1e89036f37 100644 --- a/test/files/jvm/serialization.scala +++ b/test/files/jvm/serialization.scala @@ -286,7 +286,7 @@ object Test3_mutable { import scala.collection.mutable.{ ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList, HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue, - Stack, StringBuilder, WrappedArray, TreeSet, Ctrie} + Stack, StringBuilder, WrappedArray, TreeSet, ConcurrentTrieMap} // in alphabetic order try { @@ -386,9 +386,9 @@ object Test3_mutable { val _ts1: TreeSet[Int] = read(write(ts1)) check(ts1, _ts1) - // Ctrie - val ct1 = Ctrie[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three") - val _ct1: Ctrie[Int, String] = read(write(ct1)) + // ConcurrentTrieMap + val ct1 = ConcurrentTrieMap[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three") + val _ct1: ConcurrentTrieMap[Int, String] = read(write(ct1)) check(ct1, _ct1) } catch { @@ -613,9 +613,9 @@ object Test9_parallel { val _mpm: mutable.ParHashMap[Int, Int] = read(write(mpm)) check(mpm, _mpm) - // mutable.ParCtrie - val mpc = mutable.ParCtrie(1 -> 2, 2 -> 4) - val _mpc: mutable.ParCtrie[Int, Int] = read(write(mpc)) + // mutable.ParConcurrentTrieMap + val mpc = mutable.ParConcurrentTrieMap(1 -> 2, 2 -> 4) + val _mpc: mutable.ParConcurrentTrieMap[Int, Int] = read(write(mpc)) check(mpc, _mpc) // mutable.ParHashSet diff --git a/test/files/jvm/t0632.check b/test/files/jvm/t0632.check index 3185410a75..681bc9da92 100644..100755 --- a/test/files/jvm/t0632.check +++ b/test/files/jvm/t0632.check @@ -1,12 +1,12 @@ -<foo x="&"></foo> -<foo x="&"></foo> -<foo x="&"></foo> -<foo x="&"></foo> -<foo x="&amp;"></foo> -<foo x="&amp;"></foo> -<foo x="&amp;"></foo> -<foo x="&amp;"></foo> -<foo x="&&"></foo> -<foo x="&&"></foo> -<foo x="&&"></foo> -<foo x="&&"></foo> +<foo x="&"/> +<foo x="&"/> +<foo x="&"/> +<foo x="&"/> +<foo x="&amp;"/> +<foo x="&amp;"/> +<foo x="&amp;"/> +<foo x="&amp;"/> +<foo x="&&"/> +<foo x="&&"/> +<foo x="&&"/> +<foo x="&&"/> diff --git a/test/files/jvm/t1118.check b/test/files/jvm/t1118.check new file mode 100755 index 0000000000..d676b413c9 --- /dev/null +++ b/test/files/jvm/t1118.check @@ -0,0 +1,11 @@ + +<hi/> <!-- literal short --> +<there></there> <!-- literal long --> +<guys who="you all"></guys> <!-- literal long with attribute--> +<hows it="going"/> <!-- literal short with attribute --> +<this>is pretty cool</this> <!-- literal not empty --> + +<emptiness></emptiness> <!--programmatic long--> +<vide/> <!--programmatic short--> +<elem attr="value"/> <!--programmatic short with attribute--> +<elem2 attr2="value2"></elem2> <!--programmatic long with attribute--> diff --git a/test/files/jvm/t1118.scala b/test/files/jvm/t1118.scala new file mode 100755 index 0000000000..3c86547241 --- /dev/null +++ b/test/files/jvm/t1118.scala @@ -0,0 +1,21 @@ +import scala.xml._ + +object Test { + def main(args: Array[String]) { + println(<xml:group> +<hi/> <!-- literal short --> +<there></there> <!-- literal long --> +<guys who="you all"></guys> <!-- literal long with attribute--> +<hows it="going"/> <!-- literal short with attribute --> +<this>is pretty cool</this> <!-- literal not empty --> +</xml:group>) + + println(Elem(null, "emptiness", Null, TopScope, false) ++ Text(" ") ++ Comment("programmatic long")) + + println(Elem(null, "vide", Null, TopScope, true) ++ Text(" ") ++ Comment("programmatic short")) + + println(Elem(null, "elem", Attribute("attr", Text("value"), Null), TopScope, true) ++ Text(" ") ++ Comment ("programmatic short with attribute")) + + println(Elem(null, "elem2", Attribute("attr2", Text("value2"), Null), TopScope, false) ++ Text(" ") ++ Comment ("programmatic long with attribute")) + } +}
\ No newline at end of file diff --git a/test/files/jvm/unittest_xml.scala b/test/files/jvm/unittest_xml.scala index c03695f5c6..106334e625 100644 --- a/test/files/jvm/unittest_xml.scala +++ b/test/files/jvm/unittest_xml.scala @@ -89,7 +89,7 @@ object Test { assert(" a=\"2\" g=\"3\" j=\"2\" oo=\"2\"" == xml.Utility.sort(q.attributes).toString) val pp = new xml.PrettyPrinter(80,5) - assert("<a a=\"2\" g=\"3\" j=\"2\" oo=\"2\"></a>" == pp.format(q)) + assert("<a a=\"2\" g=\"3\" j=\"2\" oo=\"2\"/>" == pp.format(q)) <hi> <there/> diff --git a/test/files/jvm/xml01.check b/test/files/jvm/xml01.check index 5e82e9a729..d78e6df410 100644..100755 --- a/test/files/jvm/xml01.check +++ b/test/files/jvm/xml01.check @@ -3,6 +3,6 @@ xpath \ xpath \\ DESCENDANTS <book><author>Peter Buneman</author><author>Dan Suciu</author><title>Data on ze web</title></book> -- group nodes -<f><a></a><b></b><c></c></f> -<a></a><f><a></a><b></b><c></c></f><a></a><b></b><c></c> +<f><a/><b/><c/></f> +<a/><f><a/><b/><c/></f><a/><b/><c/> attribute value normalization diff --git a/test/files/jvm/xml03syntax.check b/test/files/jvm/xml03syntax.check index 9fbedc2ae6..edcdbdd2ba 100644..100755 --- a/test/files/jvm/xml03syntax.check +++ b/test/files/jvm/xml03syntax.check @@ -22,5 +22,5 @@ true 2 4 -node=<elem key="<b>hello</b>"></elem>, key=Some(<b>hello</b>) -node=<elem></elem>, key=None +node=<elem key="<b>hello</b>"/>, key=Some(<b>hello</b>) +node=<elem/>, key=None diff --git a/test/files/jvm/xml05.check b/test/files/jvm/xml05.check index 00e617c578..8d3e803bc8 100644 --- a/test/files/jvm/xml05.check +++ b/test/files/jvm/xml05.check @@ -4,7 +4,7 @@ Type :help for more information. scala> scala> <city name="San José"/> -res0: scala.xml.Elem = <city name="San José"></city> +res0: scala.xml.Elem = <city name="San José"/> scala> diff --git a/test/files/jvm/xmlattr.check b/test/files/jvm/xmlattr.check index af80b60fb2..a87420d86c 100644 --- a/test/files/jvm/xmlattr.check +++ b/test/files/jvm/xmlattr.check @@ -14,5 +14,5 @@ true true true true -<b x="&"></b> -<b x="&"></b> +<b x="&"/> +<b x="&"/> diff --git a/test/files/neg/t3015.check b/test/files/neg/t3015.check index 53221b7ca0..6948392bb0 100644 --- a/test/files/neg/t3015.check +++ b/test/files/neg/t3015.check @@ -1,5 +1,5 @@ t3015.scala:7: error: scrutinee is incompatible with pattern type; - found : _$1 where type +_$1 + found : _$1 required: String val b(foo) = "foo" ^ diff --git a/test/files/neg/t3481.check b/test/files/neg/t3481.check index 48e6ff357b..debe07275b 100644 --- a/test/files/neg/t3481.check +++ b/test/files/neg/t3481.check @@ -1,17 +1,17 @@ t3481.scala:5: error: type mismatch; found : String("hello") - required: _$1 where type +_$1 + required: _$1 f[A[Int]]("hello") ^ t3481.scala:11: error: type mismatch; - found : _$2 where type +_$2 + found : _$2 required: b.T (which expands to) _$2 def f[T <: B[_]](a: T#T, b: T) = b.m(a) ^ t3481.scala:12: error: type mismatch; found : String("Hello") - required: _$2 where type +_$2 + required: _$2 f("Hello", new B[Int]) ^ t3481.scala:18: error: type mismatch; diff --git a/test/files/neg/t4515.check b/test/files/neg/t4515.check index ce5350b35f..a60d16295f 100644 --- a/test/files/neg/t4515.check +++ b/test/files/neg/t4515.check @@ -1,6 +1,6 @@ t4515.scala:37: error: type mismatch; found : _0(in value $anonfun) where type _0(in value $anonfun) - required: (some other)_0(in value $anonfun) where type +(some other)_0(in value $anonfun) + required: (some other)_0(in value $anonfun) handler.onEvent(target, ctx.getEvent, node, ctx) ^ one error found diff --git a/test/files/neg/t5189b.check b/test/files/neg/t5189b.check index 7f78cbb438..46996e96d0 100644 --- a/test/files/neg/t5189b.check +++ b/test/files/neg/t5189b.check @@ -1,8 +1,11 @@ -t5189b.scala:25: error: type mismatch; - found : TestNeg.Wrapped[?T2] where type ?T2 <: T +t5189b.scala:38: error: type mismatch; + found : TestNeg.Wrapped[?T7] where type ?T7 <: T (this is a GADT skolem) required: TestNeg.Wrapped[T] -Note: ?T2 <: T, but class Wrapped is invariant in type W. +Note: ?T7 <: T, but class Wrapped is invariant in type W. You may wish to define W as +W instead. (SLS 4.5) case Wrapper/*[_ <: T ]*/(wrapped) => wrapped // : Wrapped[_ <: T], which is a subtype of Wrapped[T] if and only if Wrapped is covariant in its type parameter ^ -one error found +t5189b.scala:51: error: value foo is not a member of type parameter T + case Some(xs) => xs.foo // the error message should not refer to a skolem (testing extrapolation) + ^ +two errors found diff --git a/test/files/neg/t5189b.scala b/test/files/neg/t5189b.scala index 1750f14084..7c1871dc97 100644 --- a/test/files/neg/t5189b.scala +++ b/test/files/neg/t5189b.scala @@ -5,8 +5,21 @@ class TestPos { def unwrap[T](x: AbsWrapperCov[T]): T = x match { case Wrapper/*[_ <: T ]*/(x) => x // _ <: T, which is a subtype of T } + + def unwrapOption[T](x: Option[T]): T = x match { + case Some(xs) => xs + } + + + case class Down[+T](x: T) + case class Up[-T](f: T => Unit) + + def f1[T](x1: Down[T])(x2: Up[T]) = ((x1, x2)) match { + case (Down(x), Up(f)) => f(x) + } } + object TestNeg extends App { class AbsWrapperCov[+A] case class Wrapper[B](x: Wrapped[B]) extends AbsWrapperCov[B] @@ -33,6 +46,11 @@ object TestNeg extends App { // val w = new Wrapped(new A) // unwrap[Any](Wrapper(w)).cell = new B // w.cell.imNotAB + + def unwrapOption[T](x: Option[T]): T = x match { + case Some(xs) => xs.foo // the error message should not refer to a skolem (testing extrapolation) + } + } // class TestPos1 { diff --git a/test/files/neg/t5572.check b/test/files/neg/t5572.check new file mode 100644 index 0000000000..7b1e290861 --- /dev/null +++ b/test/files/neg/t5572.check @@ -0,0 +1,11 @@ +t5572.scala:16: error: type mismatch; + found : B + required: A + Z.transf(a, b) match { + ^ +t5572.scala:18: error: type mismatch; + found : A + required: B + run(sth, b) + ^ +two errors found diff --git a/test/files/neg/t5572.scala b/test/files/neg/t5572.scala new file mode 100644 index 0000000000..2da1209c61 --- /dev/null +++ b/test/files/neg/t5572.scala @@ -0,0 +1,23 @@ +class A +class B + +trait X + +object Z { + def transf(a: A, b: B): X = null +} + +class Test { + + def bar(): (A, B) + + def foo { + val (b, a) = bar() + Z.transf(a, b) match { + case sth => + run(sth, b) + } + } + + def run(x: X, z: B): Unit = () +} diff --git a/test/files/neg/t5589neg.check b/test/files/neg/t5589neg.check new file mode 100644 index 0000000000..b3ff16d7e4 --- /dev/null +++ b/test/files/neg/t5589neg.check @@ -0,0 +1,37 @@ +t5589neg.scala:2: warning: `withFilter' method does not yet exist on Either.RightProjection[Int,String], using `filter' method instead + def f5(x: Either[Int, String]) = for ((y1, y2: String) <- x.right) yield ((y1, y2)) + ^ +t5589neg.scala:2: error: constructor cannot be instantiated to expected type; + found : (T1, T2) + required: String + def f5(x: Either[Int, String]) = for ((y1, y2: String) <- x.right) yield ((y1, y2)) + ^ +t5589neg.scala:3: warning: `withFilter' method does not yet exist on Either.RightProjection[Int,String], using `filter' method instead + def f6(x: Either[Int, String]) = for ((y1, y2: Any) <- x.right) yield ((y1, y2)) + ^ +t5589neg.scala:3: error: constructor cannot be instantiated to expected type; + found : (T1, T2) + required: String + def f6(x: Either[Int, String]) = for ((y1, y2: Any) <- x.right) yield ((y1, y2)) + ^ +t5589neg.scala:4: error: constructor cannot be instantiated to expected type; + found : (T1,) + required: (String, Int) + def f7(x: Either[Int, (String, Int)]) = for (y1 @ Tuple1(y2) <- x.right) yield ((y1, y2)) + ^ +t5589neg.scala:4: error: not found: value y2 + def f7(x: Either[Int, (String, Int)]) = for (y1 @ Tuple1(y2) <- x.right) yield ((y1, y2)) + ^ +t5589neg.scala:5: error: constructor cannot be instantiated to expected type; + found : (T1, T2, T3) + required: (String, Int) + def f8(x: Either[Int, (String, Int)]) = for ((y1, y2, y3) <- x.right) yield ((y1, y2)) + ^ +t5589neg.scala:5: error: not found: value y1 + def f8(x: Either[Int, (String, Int)]) = for ((y1, y2, y3) <- x.right) yield ((y1, y2)) + ^ +t5589neg.scala:5: error: not found: value y2 + def f8(x: Either[Int, (String, Int)]) = for ((y1, y2, y3) <- x.right) yield ((y1, y2)) + ^ +two warnings found +7 errors found diff --git a/test/files/neg/t5589neg.scala b/test/files/neg/t5589neg.scala new file mode 100644 index 0000000000..31ff2c3693 --- /dev/null +++ b/test/files/neg/t5589neg.scala @@ -0,0 +1,6 @@ +class A { + def f5(x: Either[Int, String]) = for ((y1, y2: String) <- x.right) yield ((y1, y2)) + def f6(x: Either[Int, String]) = for ((y1, y2: Any) <- x.right) yield ((y1, y2)) + def f7(x: Either[Int, (String, Int)]) = for (y1 @ Tuple1(y2) <- x.right) yield ((y1, y2)) + def f8(x: Either[Int, (String, Int)]) = for ((y1, y2, y3) <- x.right) yield ((y1, y2)) +} diff --git a/test/files/neg/t5589neg2.check b/test/files/neg/t5589neg2.check new file mode 100644 index 0000000000..6af4955a83 --- /dev/null +++ b/test/files/neg/t5589neg2.check @@ -0,0 +1,9 @@ +t5589neg2.scala:7: error: constructor cannot be instantiated to expected type; + found : (T1, T2) + required: String + for (((((a, (b, (c, (d1, d2)))), es), fs), gs) <- x) yield (d :: es).mkString(", ") // not ok + ^ +t5589neg2.scala:7: error: not found: value d + for (((((a, (b, (c, (d1, d2)))), es), fs), gs) <- x) yield (d :: es).mkString(", ") // not ok + ^ +two errors found diff --git a/test/files/neg/t5589neg2.scala b/test/files/neg/t5589neg2.scala new file mode 100644 index 0000000000..b7c7ab7218 --- /dev/null +++ b/test/files/neg/t5589neg2.scala @@ -0,0 +1,13 @@ +class A { + def f1(x: List[((((Int, (Double, (Float, String))), List[String]), List[Int]), List[Float])]) = { + for (((((a, (b, (c, d))), es), fs), gs) <- x) yield (d :: es).mkString(", ") // ok + } + + def f2(x: List[((((Int, (Double, (Float, String))), List[String]), List[Int]), List[Float])]) = { + for (((((a, (b, (c, (d1, d2)))), es), fs), gs) <- x) yield (d :: es).mkString(", ") // not ok + } + + def f3(x: List[((((Int, (Double, (Float, String))), List[String]), List[Int]), List[Float])]) = { + for (((((a, (b, _)), es), fs), gs) <- x) yield (es ::: fs).mkString(", ") // ok + } +}
\ No newline at end of file diff --git a/test/files/pos/dotless-targs.scala b/test/files/pos/dotless-targs.scala deleted file mode 100644 index 8337352d18..0000000000 --- a/test/files/pos/dotless-targs.scala +++ /dev/null @@ -1,12 +0,0 @@ -class A { - def fn1 = List apply 1 - def fn2 = List apply[Int] 2 - - def f1 = "f1" isInstanceOf[String] - - def g1 = "g1" toList - def g2 = "g2" toList 2 - def g3 = "g3" apply 3 - - def h1 = List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) -} diff --git a/test/files/pos/irrefutable.scala b/test/files/pos/irrefutable.scala new file mode 100644 index 0000000000..0a792b644a --- /dev/null +++ b/test/files/pos/irrefutable.scala @@ -0,0 +1,22 @@ +// The test which this should perform but does not +// is that f1 is recognized as irrefutable and f2 is not +// This can be recognized via the generated classes: +// +// A$$anonfun$f1$1.class +// A$$anonfun$f2$1.class +// A$$anonfun$f2$2.class +// +// The extra one in $f2$ is the filter. +// +// !!! Marking with exclamation points so maybe someday +// this test will be finished. +class A { + case class Foo[T](x: T) + + def f1(xs: List[Foo[Int]]) = { + for (Foo(x: Int) <- xs) yield x + } + def f2(xs: List[Foo[Any]]) = { + for (Foo(x: Int) <- xs) yield x + } +} diff --git a/test/files/pos/t1336.scala b/test/files/pos/t1336.scala new file mode 100644 index 0000000000..63967985c7 --- /dev/null +++ b/test/files/pos/t1336.scala @@ -0,0 +1,10 @@ +object Foo { + def foreach( f : ((Int,Int)) => Unit ) { + println("foreach") + f(1,2) + } + + for( (a,b) <- this ) { + println((a,b)) + } +} diff --git a/test/files/pos/t5545/S_1.scala b/test/files/pos/t5545/S_1.scala new file mode 100644 index 0000000000..59ec1fd851 --- /dev/null +++ b/test/files/pos/t5545/S_1.scala @@ -0,0 +1,4 @@ +trait F[@specialized(Int) T1, R] { + def f(v1: T1): R + def g = v1 => f(v1) +} diff --git a/test/files/pos/t5545/S_2.scala b/test/files/pos/t5545/S_2.scala new file mode 100644 index 0000000000..59ec1fd851 --- /dev/null +++ b/test/files/pos/t5545/S_2.scala @@ -0,0 +1,4 @@ +trait F[@specialized(Int) T1, R] { + def f(v1: T1): R + def g = v1 => f(v1) +} diff --git a/test/files/pos/t5589.scala b/test/files/pos/t5589.scala new file mode 100644 index 0000000000..69cbb20391 --- /dev/null +++ b/test/files/pos/t5589.scala @@ -0,0 +1,22 @@ +class A { + // First three compile. + def f1(x: Either[Int, String]) = x.right map (y => y) + def f2(x: Either[Int, String]) = for (y <- x.right) yield y + def f3(x: Either[Int, (String, Int)]) = x.right map { case (y1, y2) => (y1, y2) } + // Last one fails. + def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2)) +/** +./a.scala:5: error: constructor cannot be instantiated to expected type; + found : (T1, T2) + required: Either[Nothing,(String, Int)] + def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2)) + ^ +./a.scala:5: error: not found: value y1 + def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2)) + ^ +./a.scala:5: error: not found: value y2 + def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2)) + ^ +three errors found +**/ +} diff --git a/test/files/run/color.check b/test/files/run/color.check new file mode 100644 index 0000000000..598cc145f0 --- /dev/null +++ b/test/files/run/color.check @@ -0,0 +1,693 @@ + +1 color +[30mthe quick brown fox[0m Black +[31mthe quick brown fox[0m Red +[32mthe quick brown fox[0m Green +[33mthe quick brown fox[0m Yellow +[34mthe quick brown fox[0m Blue +[35mthe quick brown fox[0m Magenta +[36mthe quick brown fox[0m Cyan +[37mthe quick brown fox[0m White + +1 effect +[0mthe quick brown fox[0m Reset +[1mthe quick brown fox[0m Bright +[2mthe quick brown fox[0m Faint +[3mthe quick brown fox[0m Italic +[4mthe quick brown fox[0m Underline +[5mthe quick brown fox[0m Blink +[7mthe quick brown fox[0m Inverse +[8mthe quick brown fox[0m Hidden +[9mthe quick brown fox[0m Strikethrough + +1 color 1 effect +[1;30mthe quick brown fox[0m Bright Black +[4;30mthe quick brown fox[0m Underline Black +[7;30mthe quick brown fox[0m Inverse Black +[1;31mthe quick brown fox[0m Bright Red +[4;31mthe quick brown fox[0m Underline Red +[7;31mthe quick brown fox[0m Inverse Red +[1;32mthe quick brown fox[0m Bright Green +[4;32mthe quick brown fox[0m Underline Green +[7;32mthe quick brown fox[0m Inverse Green +[1;33mthe quick brown fox[0m Bright Yellow +[4;33mthe quick brown fox[0m Underline Yellow +[7;33mthe quick brown fox[0m Inverse Yellow +[1;34mthe quick brown fox[0m Bright Blue +[4;34mthe quick brown fox[0m Underline Blue +[7;34mthe quick brown fox[0m Inverse Blue +[1;35mthe quick brown fox[0m Bright Magenta +[4;35mthe quick brown fox[0m Underline Magenta +[7;35mthe quick brown fox[0m Inverse Magenta +[1;36mthe quick brown fox[0m Bright Cyan +[4;36mthe quick brown fox[0m Underline Cyan +[7;36mthe quick brown fox[0m Inverse Cyan +[1;37mthe quick brown fox[0m Bright White +[4;37mthe quick brown fox[0m Underline White +[7;37mthe quick brown fox[0m Inverse White + +2 colors 0 effects +[30;40mthe quick brown fox[0m Black (on Black background) +[31;40mthe quick brown fox[0m Red (on Black background) +[32;40mthe quick brown fox[0m Green (on Black background) +[33;40mthe quick brown fox[0m Yellow (on Black background) +[34;40mthe quick brown fox[0m Blue (on Black background) +[35;40mthe quick brown fox[0m Magenta (on Black background) +[36;40mthe quick brown fox[0m Cyan (on Black background) +[37;40mthe quick brown fox[0m White (on Black background) +[30;41mthe quick brown fox[0m Black (on Red background) +[31;41mthe quick brown fox[0m Red (on Red background) +[32;41mthe quick brown fox[0m Green (on Red background) +[33;41mthe quick brown fox[0m Yellow (on Red background) +[34;41mthe quick brown fox[0m Blue (on Red background) +[35;41mthe quick brown fox[0m Magenta (on Red background) +[36;41mthe quick brown fox[0m Cyan (on Red background) +[37;41mthe quick brown fox[0m White (on Red background) +[30;42mthe quick brown fox[0m Black (on Green background) +[31;42mthe quick brown fox[0m Red (on Green background) +[32;42mthe quick brown fox[0m Green (on Green background) +[33;42mthe quick brown fox[0m Yellow (on Green background) +[34;42mthe quick brown fox[0m Blue (on Green background) +[35;42mthe quick brown fox[0m Magenta (on Green background) +[36;42mthe quick brown fox[0m Cyan (on Green background) +[37;42mthe quick brown fox[0m White (on Green background) +[30;43mthe quick brown fox[0m Black (on Yellow background) +[31;43mthe quick brown fox[0m Red (on Yellow background) +[32;43mthe quick brown fox[0m Green (on Yellow background) +[33;43mthe quick brown fox[0m Yellow (on Yellow background) +[34;43mthe quick brown fox[0m Blue (on Yellow background) +[35;43mthe quick brown fox[0m Magenta (on Yellow background) +[36;43mthe quick brown fox[0m Cyan (on Yellow background) +[37;43mthe quick brown fox[0m White (on Yellow background) +[30;44mthe quick brown fox[0m Black (on Blue background) +[31;44mthe quick brown fox[0m Red (on Blue background) +[32;44mthe quick brown fox[0m Green (on Blue background) +[33;44mthe quick brown fox[0m Yellow (on Blue background) +[34;44mthe quick brown fox[0m Blue (on Blue background) +[35;44mthe quick brown fox[0m Magenta (on Blue background) +[36;44mthe quick brown fox[0m Cyan (on Blue background) +[37;44mthe quick brown fox[0m White (on Blue background) +[30;45mthe quick brown fox[0m Black (on Magenta background) +[31;45mthe quick brown fox[0m Red (on Magenta background) +[32;45mthe quick brown fox[0m Green (on Magenta background) +[33;45mthe quick brown fox[0m Yellow (on Magenta background) +[34;45mthe quick brown fox[0m Blue (on Magenta background) +[35;45mthe quick brown fox[0m Magenta (on Magenta background) +[36;45mthe quick brown fox[0m Cyan (on Magenta background) +[37;45mthe quick brown fox[0m White (on Magenta background) +[30;46mthe quick brown fox[0m Black (on Cyan background) +[31;46mthe quick brown fox[0m Red (on Cyan background) +[32;46mthe quick brown fox[0m Green (on Cyan background) +[33;46mthe quick brown fox[0m Yellow (on Cyan background) +[34;46mthe quick brown fox[0m Blue (on Cyan background) +[35;46mthe quick brown fox[0m Magenta (on Cyan background) +[36;46mthe quick brown fox[0m Cyan (on Cyan background) +[37;46mthe quick brown fox[0m White (on Cyan background) +[30;47mthe quick brown fox[0m Black (on White background) +[31;47mthe quick brown fox[0m Red (on White background) +[32;47mthe quick brown fox[0m Green (on White background) +[33;47mthe quick brown fox[0m Yellow (on White background) +[34;47mthe quick brown fox[0m Blue (on White background) +[35;47mthe quick brown fox[0m Magenta (on White background) +[36;47mthe quick brown fox[0m Cyan (on White background) +[37;47mthe quick brown fox[0m White (on White background) + +2 colors 1 effect +[1;30;40mthe quick brown fox[0m Bright Black (on Black background) +[4;30;40mthe quick brown fox[0m Underline Black (on Black background) +[7;30;40mthe quick brown fox[0m Inverse Black (on Black background) +[1;31;40mthe quick brown fox[0m Bright Red (on Black background) +[4;31;40mthe quick brown fox[0m Underline Red (on Black background) +[7;31;40mthe quick brown fox[0m Inverse Red (on Black background) +[1;32;40mthe quick brown fox[0m Bright Green (on Black background) +[4;32;40mthe quick brown fox[0m Underline Green (on Black background) +[7;32;40mthe quick brown fox[0m Inverse Green (on Black background) +[1;33;40mthe quick brown fox[0m Bright Yellow (on Black background) +[4;33;40mthe quick brown fox[0m Underline Yellow (on Black background) +[7;33;40mthe quick brown fox[0m Inverse Yellow (on Black background) +[1;34;40mthe quick brown fox[0m Bright Blue (on Black background) +[4;34;40mthe quick brown fox[0m Underline Blue (on Black background) +[7;34;40mthe quick brown fox[0m Inverse Blue (on Black background) +[1;35;40mthe quick brown fox[0m Bright Magenta (on Black background) +[4;35;40mthe quick brown fox[0m Underline Magenta (on Black background) +[7;35;40mthe quick brown fox[0m Inverse Magenta (on Black background) +[1;36;40mthe quick brown fox[0m Bright Cyan (on Black background) +[4;36;40mthe quick brown fox[0m Underline Cyan (on Black background) +[7;36;40mthe quick brown fox[0m Inverse Cyan (on Black background) +[1;37;40mthe quick brown fox[0m Bright White (on Black background) +[4;37;40mthe quick brown fox[0m Underline White (on Black background) +[7;37;40mthe quick brown fox[0m Inverse White (on Black background) +[1;30;41mthe quick brown fox[0m Bright Black (on Red background) +[4;30;41mthe quick brown fox[0m Underline Black (on Red background) +[7;30;41mthe quick brown fox[0m Inverse Black (on Red background) +[1;31;41mthe quick brown fox[0m Bright Red (on Red background) +[4;31;41mthe quick brown fox[0m Underline Red (on Red background) +[7;31;41mthe quick brown fox[0m Inverse Red (on Red background) +[1;32;41mthe quick brown fox[0m Bright Green (on Red background) +[4;32;41mthe quick brown fox[0m Underline Green (on Red background) +[7;32;41mthe quick brown fox[0m Inverse Green (on Red background) +[1;33;41mthe quick brown fox[0m Bright Yellow (on Red background) +[4;33;41mthe quick brown fox[0m Underline Yellow (on Red background) +[7;33;41mthe quick brown fox[0m Inverse Yellow (on Red background) +[1;34;41mthe quick brown fox[0m Bright Blue (on Red background) +[4;34;41mthe quick brown fox[0m Underline Blue (on Red background) +[7;34;41mthe quick brown fox[0m Inverse Blue (on Red background) +[1;35;41mthe quick brown fox[0m Bright Magenta (on Red background) +[4;35;41mthe quick brown fox[0m Underline Magenta (on Red background) +[7;35;41mthe quick brown fox[0m Inverse Magenta (on Red background) +[1;36;41mthe quick brown fox[0m Bright Cyan (on Red background) +[4;36;41mthe quick brown fox[0m Underline Cyan (on Red background) +[7;36;41mthe quick brown fox[0m Inverse Cyan (on Red background) +[1;37;41mthe quick brown fox[0m Bright White (on Red background) +[4;37;41mthe quick brown fox[0m Underline White (on Red background) +[7;37;41mthe quick brown fox[0m Inverse White (on Red background) +[1;30;42mthe quick brown fox[0m Bright Black (on Green background) +[4;30;42mthe quick brown fox[0m Underline Black (on Green background) +[7;30;42mthe quick brown fox[0m Inverse Black (on Green background) +[1;31;42mthe quick brown fox[0m Bright Red (on Green background) +[4;31;42mthe quick brown fox[0m Underline Red (on Green background) +[7;31;42mthe quick brown fox[0m Inverse Red (on Green background) +[1;32;42mthe quick brown fox[0m Bright Green (on Green background) +[4;32;42mthe quick brown fox[0m Underline Green (on Green background) +[7;32;42mthe quick brown fox[0m Inverse Green (on Green background) +[1;33;42mthe quick brown fox[0m Bright Yellow (on Green background) +[4;33;42mthe quick brown fox[0m Underline Yellow (on Green background) +[7;33;42mthe quick brown fox[0m Inverse Yellow (on Green background) +[1;34;42mthe quick brown fox[0m Bright Blue (on Green background) +[4;34;42mthe quick brown fox[0m Underline Blue (on Green background) +[7;34;42mthe quick brown fox[0m Inverse Blue (on Green background) +[1;35;42mthe quick brown fox[0m Bright Magenta (on Green background) +[4;35;42mthe quick brown fox[0m Underline Magenta (on Green background) +[7;35;42mthe quick brown fox[0m Inverse Magenta (on Green background) +[1;36;42mthe quick brown fox[0m Bright Cyan (on Green background) +[4;36;42mthe quick brown fox[0m Underline Cyan (on Green background) +[7;36;42mthe quick brown fox[0m Inverse Cyan (on Green background) +[1;37;42mthe quick brown fox[0m Bright White (on Green background) +[4;37;42mthe quick brown fox[0m Underline White (on Green background) +[7;37;42mthe quick brown fox[0m Inverse White (on Green background) +[1;30;43mthe quick brown fox[0m Bright Black (on Yellow background) +[4;30;43mthe quick brown fox[0m Underline Black (on Yellow background) +[7;30;43mthe quick brown fox[0m Inverse Black (on Yellow background) +[1;31;43mthe quick brown fox[0m Bright Red (on Yellow background) +[4;31;43mthe quick brown fox[0m Underline Red (on Yellow background) +[7;31;43mthe quick brown fox[0m Inverse Red (on Yellow background) +[1;32;43mthe quick brown fox[0m Bright Green (on Yellow background) +[4;32;43mthe quick brown fox[0m Underline Green (on Yellow background) +[7;32;43mthe quick brown fox[0m Inverse Green (on Yellow background) +[1;33;43mthe quick brown fox[0m Bright Yellow (on Yellow background) +[4;33;43mthe quick brown fox[0m Underline Yellow (on Yellow background) +[7;33;43mthe quick brown fox[0m Inverse Yellow (on Yellow background) +[1;34;43mthe quick brown fox[0m Bright Blue (on Yellow background) +[4;34;43mthe quick brown fox[0m Underline Blue (on Yellow background) +[7;34;43mthe quick brown fox[0m Inverse Blue (on Yellow background) +[1;35;43mthe quick brown fox[0m Bright Magenta (on Yellow background) +[4;35;43mthe quick brown fox[0m Underline Magenta (on Yellow background) +[7;35;43mthe quick brown fox[0m Inverse Magenta (on Yellow background) +[1;36;43mthe quick brown fox[0m Bright Cyan (on Yellow background) +[4;36;43mthe quick brown fox[0m Underline Cyan (on Yellow background) +[7;36;43mthe quick brown fox[0m Inverse Cyan (on Yellow background) +[1;37;43mthe quick brown fox[0m Bright White (on Yellow background) +[4;37;43mthe quick brown fox[0m Underline White (on Yellow background) +[7;37;43mthe quick brown fox[0m Inverse White (on Yellow background) +[1;30;44mthe quick brown fox[0m Bright Black (on Blue background) +[4;30;44mthe quick brown fox[0m Underline Black (on Blue background) +[7;30;44mthe quick brown fox[0m Inverse Black (on Blue background) +[1;31;44mthe quick brown fox[0m Bright Red (on Blue background) +[4;31;44mthe quick brown fox[0m Underline Red (on Blue background) +[7;31;44mthe quick brown fox[0m Inverse Red (on Blue background) +[1;32;44mthe quick brown fox[0m Bright Green (on Blue background) +[4;32;44mthe quick brown fox[0m Underline Green (on Blue background) +[7;32;44mthe quick brown fox[0m Inverse Green (on Blue background) +[1;33;44mthe quick brown fox[0m Bright Yellow (on Blue background) +[4;33;44mthe quick brown fox[0m Underline Yellow (on Blue background) +[7;33;44mthe quick brown fox[0m Inverse Yellow (on Blue background) +[1;34;44mthe quick brown fox[0m Bright Blue (on Blue background) +[4;34;44mthe quick brown fox[0m Underline Blue (on Blue background) +[7;34;44mthe quick brown fox[0m Inverse Blue (on Blue background) +[1;35;44mthe quick brown fox[0m Bright Magenta (on Blue background) +[4;35;44mthe quick brown fox[0m Underline Magenta (on Blue background) +[7;35;44mthe quick brown fox[0m Inverse Magenta (on Blue background) +[1;36;44mthe quick brown fox[0m Bright Cyan (on Blue background) +[4;36;44mthe quick brown fox[0m Underline Cyan (on Blue background) +[7;36;44mthe quick brown fox[0m Inverse Cyan (on Blue background) +[1;37;44mthe quick brown fox[0m Bright White (on Blue background) +[4;37;44mthe quick brown fox[0m Underline White (on Blue background) +[7;37;44mthe quick brown fox[0m Inverse White (on Blue background) +[1;30;45mthe quick brown fox[0m Bright Black (on Magenta background) +[4;30;45mthe quick brown fox[0m Underline Black (on Magenta background) +[7;30;45mthe quick brown fox[0m Inverse Black (on Magenta background) +[1;31;45mthe quick brown fox[0m Bright Red (on Magenta background) +[4;31;45mthe quick brown fox[0m Underline Red (on Magenta background) +[7;31;45mthe quick brown fox[0m Inverse Red (on Magenta background) +[1;32;45mthe quick brown fox[0m Bright Green (on Magenta background) +[4;32;45mthe quick brown fox[0m Underline Green (on Magenta background) +[7;32;45mthe quick brown fox[0m Inverse Green (on Magenta background) +[1;33;45mthe quick brown fox[0m Bright Yellow (on Magenta background) +[4;33;45mthe quick brown fox[0m Underline Yellow (on Magenta background) +[7;33;45mthe quick brown fox[0m Inverse Yellow (on Magenta background) +[1;34;45mthe quick brown fox[0m Bright Blue (on Magenta background) +[4;34;45mthe quick brown fox[0m Underline Blue (on Magenta background) +[7;34;45mthe quick brown fox[0m Inverse Blue (on Magenta background) +[1;35;45mthe quick brown fox[0m Bright Magenta (on Magenta background) +[4;35;45mthe quick brown fox[0m Underline Magenta (on Magenta background) +[7;35;45mthe quick brown fox[0m Inverse Magenta (on Magenta background) +[1;36;45mthe quick brown fox[0m Bright Cyan (on Magenta background) +[4;36;45mthe quick brown fox[0m Underline Cyan (on Magenta background) +[7;36;45mthe quick brown fox[0m Inverse Cyan (on Magenta background) +[1;37;45mthe quick brown fox[0m Bright White (on Magenta background) +[4;37;45mthe quick brown fox[0m Underline White (on Magenta background) +[7;37;45mthe quick brown fox[0m Inverse White (on Magenta background) +[1;30;46mthe quick brown fox[0m Bright Black (on Cyan background) +[4;30;46mthe quick brown fox[0m Underline Black (on Cyan background) +[7;30;46mthe quick brown fox[0m Inverse Black (on Cyan background) +[1;31;46mthe quick brown fox[0m Bright Red (on Cyan background) +[4;31;46mthe quick brown fox[0m Underline Red (on Cyan background) +[7;31;46mthe quick brown fox[0m Inverse Red (on Cyan background) +[1;32;46mthe quick brown fox[0m Bright Green (on Cyan background) +[4;32;46mthe quick brown fox[0m Underline Green (on Cyan background) +[7;32;46mthe quick brown fox[0m Inverse Green (on Cyan background) +[1;33;46mthe quick brown fox[0m Bright Yellow (on Cyan background) +[4;33;46mthe quick brown fox[0m Underline Yellow (on Cyan background) +[7;33;46mthe quick brown fox[0m Inverse Yellow (on Cyan background) +[1;34;46mthe quick brown fox[0m Bright Blue (on Cyan background) +[4;34;46mthe quick brown fox[0m Underline Blue (on Cyan background) +[7;34;46mthe quick brown fox[0m Inverse Blue (on Cyan background) +[1;35;46mthe quick brown fox[0m Bright Magenta (on Cyan background) +[4;35;46mthe quick brown fox[0m Underline Magenta (on Cyan background) +[7;35;46mthe quick brown fox[0m Inverse Magenta (on Cyan background) +[1;36;46mthe quick brown fox[0m Bright Cyan (on Cyan background) +[4;36;46mthe quick brown fox[0m Underline Cyan (on Cyan background) +[7;36;46mthe quick brown fox[0m Inverse Cyan (on Cyan background) +[1;37;46mthe quick brown fox[0m Bright White (on Cyan background) +[4;37;46mthe quick brown fox[0m Underline White (on Cyan background) +[7;37;46mthe quick brown fox[0m Inverse White (on Cyan background) +[1;30;47mthe quick brown fox[0m Bright Black (on White background) +[4;30;47mthe quick brown fox[0m Underline Black (on White background) +[7;30;47mthe quick brown fox[0m Inverse Black (on White background) +[1;31;47mthe quick brown fox[0m Bright Red (on White background) +[4;31;47mthe quick brown fox[0m Underline Red (on White background) +[7;31;47mthe quick brown fox[0m Inverse Red (on White background) +[1;32;47mthe quick brown fox[0m Bright Green (on White background) +[4;32;47mthe quick brown fox[0m Underline Green (on White background) +[7;32;47mthe quick brown fox[0m Inverse Green (on White background) +[1;33;47mthe quick brown fox[0m Bright Yellow (on White background) +[4;33;47mthe quick brown fox[0m Underline Yellow (on White background) +[7;33;47mthe quick brown fox[0m Inverse Yellow (on White background) +[1;34;47mthe quick brown fox[0m Bright Blue (on White background) +[4;34;47mthe quick brown fox[0m Underline Blue (on White background) +[7;34;47mthe quick brown fox[0m Inverse Blue (on White background) +[1;35;47mthe quick brown fox[0m Bright Magenta (on White background) +[4;35;47mthe quick brown fox[0m Underline Magenta (on White background) +[7;35;47mthe quick brown fox[0m Inverse Magenta (on White background) +[1;36;47mthe quick brown fox[0m Bright Cyan (on White background) +[4;36;47mthe quick brown fox[0m Underline Cyan (on White background) +[7;36;47mthe quick brown fox[0m Inverse Cyan (on White background) +[1;37;47mthe quick brown fox[0m Bright White (on White background) +[4;37;47mthe quick brown fox[0m Underline White (on White background) +[7;37;47mthe quick brown fox[0m Inverse White (on White background) + +2 colors 2 effects +[1;4;30;40mthe quick brown fox[0m Bright Underline Black (on Black background) +[1;7;30;40mthe quick brown fox[0m Bright Inverse Black (on Black background) +[4;1;30;40mthe quick brown fox[0m Underline Bright Black (on Black background) +[4;7;30;40mthe quick brown fox[0m Underline Inverse Black (on Black background) +[7;1;30;40mthe quick brown fox[0m Inverse Bright Black (on Black background) +[7;4;30;40mthe quick brown fox[0m Inverse Underline Black (on Black background) +[1;4;31;40mthe quick brown fox[0m Bright Underline Red (on Black background) +[1;7;31;40mthe quick brown fox[0m Bright Inverse Red (on Black background) +[4;1;31;40mthe quick brown fox[0m Underline Bright Red (on Black background) +[4;7;31;40mthe quick brown fox[0m Underline Inverse Red (on Black background) +[7;1;31;40mthe quick brown fox[0m Inverse Bright Red (on Black background) +[7;4;31;40mthe quick brown fox[0m Inverse Underline Red (on Black background) +[1;4;32;40mthe quick brown fox[0m Bright Underline Green (on Black background) +[1;7;32;40mthe quick brown fox[0m Bright Inverse Green (on Black background) +[4;1;32;40mthe quick brown fox[0m Underline Bright Green (on Black background) +[4;7;32;40mthe quick brown fox[0m Underline Inverse Green (on Black background) +[7;1;32;40mthe quick brown fox[0m Inverse Bright Green (on Black background) +[7;4;32;40mthe quick brown fox[0m Inverse Underline Green (on Black background) +[1;4;33;40mthe quick brown fox[0m Bright Underline Yellow (on Black background) +[1;7;33;40mthe quick brown fox[0m Bright Inverse Yellow (on Black background) +[4;1;33;40mthe quick brown fox[0m Underline Bright Yellow (on Black background) +[4;7;33;40mthe quick brown fox[0m Underline Inverse Yellow (on Black background) +[7;1;33;40mthe quick brown fox[0m Inverse Bright Yellow (on Black background) +[7;4;33;40mthe quick brown fox[0m Inverse Underline Yellow (on Black background) +[1;4;34;40mthe quick brown fox[0m Bright Underline Blue (on Black background) +[1;7;34;40mthe quick brown fox[0m Bright Inverse Blue (on Black background) +[4;1;34;40mthe quick brown fox[0m Underline Bright Blue (on Black background) +[4;7;34;40mthe quick brown fox[0m Underline Inverse Blue (on Black background) +[7;1;34;40mthe quick brown fox[0m Inverse Bright Blue (on Black background) +[7;4;34;40mthe quick brown fox[0m Inverse Underline Blue (on Black background) +[1;4;35;40mthe quick brown fox[0m Bright Underline Magenta (on Black background) +[1;7;35;40mthe quick brown fox[0m Bright Inverse Magenta (on Black background) +[4;1;35;40mthe quick brown fox[0m Underline Bright Magenta (on Black background) +[4;7;35;40mthe quick brown fox[0m Underline Inverse Magenta (on Black background) +[7;1;35;40mthe quick brown fox[0m Inverse Bright Magenta (on Black background) +[7;4;35;40mthe quick brown fox[0m Inverse Underline Magenta (on Black background) +[1;4;36;40mthe quick brown fox[0m Bright Underline Cyan (on Black background) +[1;7;36;40mthe quick brown fox[0m Bright Inverse Cyan (on Black background) +[4;1;36;40mthe quick brown fox[0m Underline Bright Cyan (on Black background) +[4;7;36;40mthe quick brown fox[0m Underline Inverse Cyan (on Black background) +[7;1;36;40mthe quick brown fox[0m Inverse Bright Cyan (on Black background) +[7;4;36;40mthe quick brown fox[0m Inverse Underline Cyan (on Black background) +[1;4;37;40mthe quick brown fox[0m Bright Underline White (on Black background) +[1;7;37;40mthe quick brown fox[0m Bright Inverse White (on Black background) +[4;1;37;40mthe quick brown fox[0m Underline Bright White (on Black background) +[4;7;37;40mthe quick brown fox[0m Underline Inverse White (on Black background) +[7;1;37;40mthe quick brown fox[0m Inverse Bright White (on Black background) +[7;4;37;40mthe quick brown fox[0m Inverse Underline White (on Black background) +[1;4;30;41mthe quick brown fox[0m Bright Underline Black (on Red background) +[1;7;30;41mthe quick brown fox[0m Bright Inverse Black (on Red background) +[4;1;30;41mthe quick brown fox[0m Underline Bright Black (on Red background) +[4;7;30;41mthe quick brown fox[0m Underline Inverse Black (on Red background) +[7;1;30;41mthe quick brown fox[0m Inverse Bright Black (on Red background) +[7;4;30;41mthe quick brown fox[0m Inverse Underline Black (on Red background) +[1;4;31;41mthe quick brown fox[0m Bright Underline Red (on Red background) +[1;7;31;41mthe quick brown fox[0m Bright Inverse Red (on Red background) +[4;1;31;41mthe quick brown fox[0m Underline Bright Red (on Red background) +[4;7;31;41mthe quick brown fox[0m Underline Inverse Red (on Red background) +[7;1;31;41mthe quick brown fox[0m Inverse Bright Red (on Red background) +[7;4;31;41mthe quick brown fox[0m Inverse Underline Red (on Red background) +[1;4;32;41mthe quick brown fox[0m Bright Underline Green (on Red background) +[1;7;32;41mthe quick brown fox[0m Bright Inverse Green (on Red background) +[4;1;32;41mthe quick brown fox[0m Underline Bright Green (on Red background) +[4;7;32;41mthe quick brown fox[0m Underline Inverse Green (on Red background) +[7;1;32;41mthe quick brown fox[0m Inverse Bright Green (on Red background) +[7;4;32;41mthe quick brown fox[0m Inverse Underline Green (on Red background) +[1;4;33;41mthe quick brown fox[0m Bright Underline Yellow (on Red background) +[1;7;33;41mthe quick brown fox[0m Bright Inverse Yellow (on Red background) +[4;1;33;41mthe quick brown fox[0m Underline Bright Yellow (on Red background) +[4;7;33;41mthe quick brown fox[0m Underline Inverse Yellow (on Red background) +[7;1;33;41mthe quick brown fox[0m Inverse Bright Yellow (on Red background) +[7;4;33;41mthe quick brown fox[0m Inverse Underline Yellow (on Red background) +[1;4;34;41mthe quick brown fox[0m Bright Underline Blue (on Red background) +[1;7;34;41mthe quick brown fox[0m Bright Inverse Blue (on Red background) +[4;1;34;41mthe quick brown fox[0m Underline Bright Blue (on Red background) +[4;7;34;41mthe quick brown fox[0m Underline Inverse Blue (on Red background) +[7;1;34;41mthe quick brown fox[0m Inverse Bright Blue (on Red background) +[7;4;34;41mthe quick brown fox[0m Inverse Underline Blue (on Red background) +[1;4;35;41mthe quick brown fox[0m Bright Underline Magenta (on Red background) +[1;7;35;41mthe quick brown fox[0m Bright Inverse Magenta (on Red background) +[4;1;35;41mthe quick brown fox[0m Underline Bright Magenta (on Red background) +[4;7;35;41mthe quick brown fox[0m Underline Inverse Magenta (on Red background) +[7;1;35;41mthe quick brown fox[0m Inverse Bright Magenta (on Red background) +[7;4;35;41mthe quick brown fox[0m Inverse Underline Magenta (on Red background) +[1;4;36;41mthe quick brown fox[0m Bright Underline Cyan (on Red background) +[1;7;36;41mthe quick brown fox[0m Bright Inverse Cyan (on Red background) +[4;1;36;41mthe quick brown fox[0m Underline Bright Cyan (on Red background) +[4;7;36;41mthe quick brown fox[0m Underline Inverse Cyan (on Red background) +[7;1;36;41mthe quick brown fox[0m Inverse Bright Cyan (on Red background) +[7;4;36;41mthe quick brown fox[0m Inverse Underline Cyan (on Red background) +[1;4;37;41mthe quick brown fox[0m Bright Underline White (on Red background) +[1;7;37;41mthe quick brown fox[0m Bright Inverse White (on Red background) +[4;1;37;41mthe quick brown fox[0m Underline Bright White (on Red background) +[4;7;37;41mthe quick brown fox[0m Underline Inverse White (on Red background) +[7;1;37;41mthe quick brown fox[0m Inverse Bright White (on Red background) +[7;4;37;41mthe quick brown fox[0m Inverse Underline White (on Red background) +[1;4;30;42mthe quick brown fox[0m Bright Underline Black (on Green background) +[1;7;30;42mthe quick brown fox[0m Bright Inverse Black (on Green background) +[4;1;30;42mthe quick brown fox[0m Underline Bright Black (on Green background) +[4;7;30;42mthe quick brown fox[0m Underline Inverse Black (on Green background) +[7;1;30;42mthe quick brown fox[0m Inverse Bright Black (on Green background) +[7;4;30;42mthe quick brown fox[0m Inverse Underline Black (on Green background) +[1;4;31;42mthe quick brown fox[0m Bright Underline Red (on Green background) +[1;7;31;42mthe quick brown fox[0m Bright Inverse Red (on Green background) +[4;1;31;42mthe quick brown fox[0m Underline Bright Red (on Green background) +[4;7;31;42mthe quick brown fox[0m Underline Inverse Red (on Green background) +[7;1;31;42mthe quick brown fox[0m Inverse Bright Red (on Green background) +[7;4;31;42mthe quick brown fox[0m Inverse Underline Red (on Green background) +[1;4;32;42mthe quick brown fox[0m Bright Underline Green (on Green background) +[1;7;32;42mthe quick brown fox[0m Bright Inverse Green (on Green background) +[4;1;32;42mthe quick brown fox[0m Underline Bright Green (on Green background) +[4;7;32;42mthe quick brown fox[0m Underline Inverse Green (on Green background) +[7;1;32;42mthe quick brown fox[0m Inverse Bright Green (on Green background) +[7;4;32;42mthe quick brown fox[0m Inverse Underline Green (on Green background) +[1;4;33;42mthe quick brown fox[0m Bright Underline Yellow (on Green background) +[1;7;33;42mthe quick brown fox[0m Bright Inverse Yellow (on Green background) +[4;1;33;42mthe quick brown fox[0m Underline Bright Yellow (on Green background) +[4;7;33;42mthe quick brown fox[0m Underline Inverse Yellow (on Green background) +[7;1;33;42mthe quick brown fox[0m Inverse Bright Yellow (on Green background) +[7;4;33;42mthe quick brown fox[0m Inverse Underline Yellow (on Green background) +[1;4;34;42mthe quick brown fox[0m Bright Underline Blue (on Green background) +[1;7;34;42mthe quick brown fox[0m Bright Inverse Blue (on Green background) +[4;1;34;42mthe quick brown fox[0m Underline Bright Blue (on Green background) +[4;7;34;42mthe quick brown fox[0m Underline Inverse Blue (on Green background) +[7;1;34;42mthe quick brown fox[0m Inverse Bright Blue (on Green background) +[7;4;34;42mthe quick brown fox[0m Inverse Underline Blue (on Green background) +[1;4;35;42mthe quick brown fox[0m Bright Underline Magenta (on Green background) +[1;7;35;42mthe quick brown fox[0m Bright Inverse Magenta (on Green background) +[4;1;35;42mthe quick brown fox[0m Underline Bright Magenta (on Green background) +[4;7;35;42mthe quick brown fox[0m Underline Inverse Magenta (on Green background) +[7;1;35;42mthe quick brown fox[0m Inverse Bright Magenta (on Green background) +[7;4;35;42mthe quick brown fox[0m Inverse Underline Magenta (on Green background) +[1;4;36;42mthe quick brown fox[0m Bright Underline Cyan (on Green background) +[1;7;36;42mthe quick brown fox[0m Bright Inverse Cyan (on Green background) +[4;1;36;42mthe quick brown fox[0m Underline Bright Cyan (on Green background) +[4;7;36;42mthe quick brown fox[0m Underline Inverse Cyan (on Green background) +[7;1;36;42mthe quick brown fox[0m Inverse Bright Cyan (on Green background) +[7;4;36;42mthe quick brown fox[0m Inverse Underline Cyan (on Green background) +[1;4;37;42mthe quick brown fox[0m Bright Underline White (on Green background) +[1;7;37;42mthe quick brown fox[0m Bright Inverse White (on Green background) +[4;1;37;42mthe quick brown fox[0m Underline Bright White (on Green background) +[4;7;37;42mthe quick brown fox[0m Underline Inverse White (on Green background) +[7;1;37;42mthe quick brown fox[0m Inverse Bright White (on Green background) +[7;4;37;42mthe quick brown fox[0m Inverse Underline White (on Green background) +[1;4;30;43mthe quick brown fox[0m Bright Underline Black (on Yellow background) +[1;7;30;43mthe quick brown fox[0m Bright Inverse Black (on Yellow background) +[4;1;30;43mthe quick brown fox[0m Underline Bright Black (on Yellow background) +[4;7;30;43mthe quick brown fox[0m Underline Inverse Black (on Yellow background) +[7;1;30;43mthe quick brown fox[0m Inverse Bright Black (on Yellow background) +[7;4;30;43mthe quick brown fox[0m Inverse Underline Black (on Yellow background) +[1;4;31;43mthe quick brown fox[0m Bright Underline Red (on Yellow background) +[1;7;31;43mthe quick brown fox[0m Bright Inverse Red (on Yellow background) +[4;1;31;43mthe quick brown fox[0m Underline Bright Red (on Yellow background) +[4;7;31;43mthe quick brown fox[0m Underline Inverse Red (on Yellow background) +[7;1;31;43mthe quick brown fox[0m Inverse Bright Red (on Yellow background) +[7;4;31;43mthe quick brown fox[0m Inverse Underline Red (on Yellow background) +[1;4;32;43mthe quick brown fox[0m Bright Underline Green (on Yellow background) +[1;7;32;43mthe quick brown fox[0m Bright Inverse Green (on Yellow background) +[4;1;32;43mthe quick brown fox[0m Underline Bright Green (on Yellow background) +[4;7;32;43mthe quick brown fox[0m Underline Inverse Green (on Yellow background) +[7;1;32;43mthe quick brown fox[0m Inverse Bright Green (on Yellow background) +[7;4;32;43mthe quick brown fox[0m Inverse Underline Green (on Yellow background) +[1;4;33;43mthe quick brown fox[0m Bright Underline Yellow (on Yellow background) +[1;7;33;43mthe quick brown fox[0m Bright Inverse Yellow (on Yellow background) +[4;1;33;43mthe quick brown fox[0m Underline Bright Yellow (on Yellow background) +[4;7;33;43mthe quick brown fox[0m Underline Inverse Yellow (on Yellow background) +[7;1;33;43mthe quick brown fox[0m Inverse Bright Yellow (on Yellow background) +[7;4;33;43mthe quick brown fox[0m Inverse Underline Yellow (on Yellow background) +[1;4;34;43mthe quick brown fox[0m Bright Underline Blue (on Yellow background) +[1;7;34;43mthe quick brown fox[0m Bright Inverse Blue (on Yellow background) +[4;1;34;43mthe quick brown fox[0m Underline Bright Blue (on Yellow background) +[4;7;34;43mthe quick brown fox[0m Underline Inverse Blue (on Yellow background) +[7;1;34;43mthe quick brown fox[0m Inverse Bright Blue (on Yellow background) +[7;4;34;43mthe quick brown fox[0m Inverse Underline Blue (on Yellow background) +[1;4;35;43mthe quick brown fox[0m Bright Underline Magenta (on Yellow background) +[1;7;35;43mthe quick brown fox[0m Bright Inverse Magenta (on Yellow background) +[4;1;35;43mthe quick brown fox[0m Underline Bright Magenta (on Yellow background) +[4;7;35;43mthe quick brown fox[0m Underline Inverse Magenta (on Yellow background) +[7;1;35;43mthe quick brown fox[0m Inverse Bright Magenta (on Yellow background) +[7;4;35;43mthe quick brown fox[0m Inverse Underline Magenta (on Yellow background) +[1;4;36;43mthe quick brown fox[0m Bright Underline Cyan (on Yellow background) +[1;7;36;43mthe quick brown fox[0m Bright Inverse Cyan (on Yellow background) +[4;1;36;43mthe quick brown fox[0m Underline Bright Cyan (on Yellow background) +[4;7;36;43mthe quick brown fox[0m Underline Inverse Cyan (on Yellow background) +[7;1;36;43mthe quick brown fox[0m Inverse Bright Cyan (on Yellow background) +[7;4;36;43mthe quick brown fox[0m Inverse Underline Cyan (on Yellow background) +[1;4;37;43mthe quick brown fox[0m Bright Underline White (on Yellow background) +[1;7;37;43mthe quick brown fox[0m Bright Inverse White (on Yellow background) +[4;1;37;43mthe quick brown fox[0m Underline Bright White (on Yellow background) +[4;7;37;43mthe quick brown fox[0m Underline Inverse White (on Yellow background) +[7;1;37;43mthe quick brown fox[0m Inverse Bright White (on Yellow background) +[7;4;37;43mthe quick brown fox[0m Inverse Underline White (on Yellow background) +[1;4;30;44mthe quick brown fox[0m Bright Underline Black (on Blue background) +[1;7;30;44mthe quick brown fox[0m Bright Inverse Black (on Blue background) +[4;1;30;44mthe quick brown fox[0m Underline Bright Black (on Blue background) +[4;7;30;44mthe quick brown fox[0m Underline Inverse Black (on Blue background) +[7;1;30;44mthe quick brown fox[0m Inverse Bright Black (on Blue background) +[7;4;30;44mthe quick brown fox[0m Inverse Underline Black (on Blue background) +[1;4;31;44mthe quick brown fox[0m Bright Underline Red (on Blue background) +[1;7;31;44mthe quick brown fox[0m Bright Inverse Red (on Blue background) +[4;1;31;44mthe quick brown fox[0m Underline Bright Red (on Blue background) +[4;7;31;44mthe quick brown fox[0m Underline Inverse Red (on Blue background) +[7;1;31;44mthe quick brown fox[0m Inverse Bright Red (on Blue background) +[7;4;31;44mthe quick brown fox[0m Inverse Underline Red (on Blue background) +[1;4;32;44mthe quick brown fox[0m Bright Underline Green (on Blue background) +[1;7;32;44mthe quick brown fox[0m Bright Inverse Green (on Blue background) +[4;1;32;44mthe quick brown fox[0m Underline Bright Green (on Blue background) +[4;7;32;44mthe quick brown fox[0m Underline Inverse Green (on Blue background) +[7;1;32;44mthe quick brown fox[0m Inverse Bright Green (on Blue background) +[7;4;32;44mthe quick brown fox[0m Inverse Underline Green (on Blue background) +[1;4;33;44mthe quick brown fox[0m Bright Underline Yellow (on Blue background) +[1;7;33;44mthe quick brown fox[0m Bright Inverse Yellow (on Blue background) +[4;1;33;44mthe quick brown fox[0m Underline Bright Yellow (on Blue background) +[4;7;33;44mthe quick brown fox[0m Underline Inverse Yellow (on Blue background) +[7;1;33;44mthe quick brown fox[0m Inverse Bright Yellow (on Blue background) +[7;4;33;44mthe quick brown fox[0m Inverse Underline Yellow (on Blue background) +[1;4;34;44mthe quick brown fox[0m Bright Underline Blue (on Blue background) +[1;7;34;44mthe quick brown fox[0m Bright Inverse Blue (on Blue background) +[4;1;34;44mthe quick brown fox[0m Underline Bright Blue (on Blue background) +[4;7;34;44mthe quick brown fox[0m Underline Inverse Blue (on Blue background) +[7;1;34;44mthe quick brown fox[0m Inverse Bright Blue (on Blue background) +[7;4;34;44mthe quick brown fox[0m Inverse Underline Blue (on Blue background) +[1;4;35;44mthe quick brown fox[0m Bright Underline Magenta (on Blue background) +[1;7;35;44mthe quick brown fox[0m Bright Inverse Magenta (on Blue background) +[4;1;35;44mthe quick brown fox[0m Underline Bright Magenta (on Blue background) +[4;7;35;44mthe quick brown fox[0m Underline Inverse Magenta (on Blue background) +[7;1;35;44mthe quick brown fox[0m Inverse Bright Magenta (on Blue background) +[7;4;35;44mthe quick brown fox[0m Inverse Underline Magenta (on Blue background) +[1;4;36;44mthe quick brown fox[0m Bright Underline Cyan (on Blue background) +[1;7;36;44mthe quick brown fox[0m Bright Inverse Cyan (on Blue background) +[4;1;36;44mthe quick brown fox[0m Underline Bright Cyan (on Blue background) +[4;7;36;44mthe quick brown fox[0m Underline Inverse Cyan (on Blue background) +[7;1;36;44mthe quick brown fox[0m Inverse Bright Cyan (on Blue background) +[7;4;36;44mthe quick brown fox[0m Inverse Underline Cyan (on Blue background) +[1;4;37;44mthe quick brown fox[0m Bright Underline White (on Blue background) +[1;7;37;44mthe quick brown fox[0m Bright Inverse White (on Blue background) +[4;1;37;44mthe quick brown fox[0m Underline Bright White (on Blue background) +[4;7;37;44mthe quick brown fox[0m Underline Inverse White (on Blue background) +[7;1;37;44mthe quick brown fox[0m Inverse Bright White (on Blue background) +[7;4;37;44mthe quick brown fox[0m Inverse Underline White (on Blue background) +[1;4;30;45mthe quick brown fox[0m Bright Underline Black (on Magenta background) +[1;7;30;45mthe quick brown fox[0m Bright Inverse Black (on Magenta background) +[4;1;30;45mthe quick brown fox[0m Underline Bright Black (on Magenta background) +[4;7;30;45mthe quick brown fox[0m Underline Inverse Black (on Magenta background) +[7;1;30;45mthe quick brown fox[0m Inverse Bright Black (on Magenta background) +[7;4;30;45mthe quick brown fox[0m Inverse Underline Black (on Magenta background) +[1;4;31;45mthe quick brown fox[0m Bright Underline Red (on Magenta background) +[1;7;31;45mthe quick brown fox[0m Bright Inverse Red (on Magenta background) +[4;1;31;45mthe quick brown fox[0m Underline Bright Red (on Magenta background) +[4;7;31;45mthe quick brown fox[0m Underline Inverse Red (on Magenta background) +[7;1;31;45mthe quick brown fox[0m Inverse Bright Red (on Magenta background) +[7;4;31;45mthe quick brown fox[0m Inverse Underline Red (on Magenta background) +[1;4;32;45mthe quick brown fox[0m Bright Underline Green (on Magenta background) +[1;7;32;45mthe quick brown fox[0m Bright Inverse Green (on Magenta background) +[4;1;32;45mthe quick brown fox[0m Underline Bright Green (on Magenta background) +[4;7;32;45mthe quick brown fox[0m Underline Inverse Green (on Magenta background) +[7;1;32;45mthe quick brown fox[0m Inverse Bright Green (on Magenta background) +[7;4;32;45mthe quick brown fox[0m Inverse Underline Green (on Magenta background) +[1;4;33;45mthe quick brown fox[0m Bright Underline Yellow (on Magenta background) +[1;7;33;45mthe quick brown fox[0m Bright Inverse Yellow (on Magenta background) +[4;1;33;45mthe quick brown fox[0m Underline Bright Yellow (on Magenta background) +[4;7;33;45mthe quick brown fox[0m Underline Inverse Yellow (on Magenta background) +[7;1;33;45mthe quick brown fox[0m Inverse Bright Yellow (on Magenta background) +[7;4;33;45mthe quick brown fox[0m Inverse Underline Yellow (on Magenta background) +[1;4;34;45mthe quick brown fox[0m Bright Underline Blue (on Magenta background) +[1;7;34;45mthe quick brown fox[0m Bright Inverse Blue (on Magenta background) +[4;1;34;45mthe quick brown fox[0m Underline Bright Blue (on Magenta background) +[4;7;34;45mthe quick brown fox[0m Underline Inverse Blue (on Magenta background) +[7;1;34;45mthe quick brown fox[0m Inverse Bright Blue (on Magenta background) +[7;4;34;45mthe quick brown fox[0m Inverse Underline Blue (on Magenta background) +[1;4;35;45mthe quick brown fox[0m Bright Underline Magenta (on Magenta background) +[1;7;35;45mthe quick brown fox[0m Bright Inverse Magenta (on Magenta background) +[4;1;35;45mthe quick brown fox[0m Underline Bright Magenta (on Magenta background) +[4;7;35;45mthe quick brown fox[0m Underline Inverse Magenta (on Magenta background) +[7;1;35;45mthe quick brown fox[0m Inverse Bright Magenta (on Magenta background) +[7;4;35;45mthe quick brown fox[0m Inverse Underline Magenta (on Magenta background) +[1;4;36;45mthe quick brown fox[0m Bright Underline Cyan (on Magenta background) +[1;7;36;45mthe quick brown fox[0m Bright Inverse Cyan (on Magenta background) +[4;1;36;45mthe quick brown fox[0m Underline Bright Cyan (on Magenta background) +[4;7;36;45mthe quick brown fox[0m Underline Inverse Cyan (on Magenta background) +[7;1;36;45mthe quick brown fox[0m Inverse Bright Cyan (on Magenta background) +[7;4;36;45mthe quick brown fox[0m Inverse Underline Cyan (on Magenta background) +[1;4;37;45mthe quick brown fox[0m Bright Underline White (on Magenta background) +[1;7;37;45mthe quick brown fox[0m Bright Inverse White (on Magenta background) +[4;1;37;45mthe quick brown fox[0m Underline Bright White (on Magenta background) +[4;7;37;45mthe quick brown fox[0m Underline Inverse White (on Magenta background) +[7;1;37;45mthe quick brown fox[0m Inverse Bright White (on Magenta background) +[7;4;37;45mthe quick brown fox[0m Inverse Underline White (on Magenta background) +[1;4;30;46mthe quick brown fox[0m Bright Underline Black (on Cyan background) +[1;7;30;46mthe quick brown fox[0m Bright Inverse Black (on Cyan background) +[4;1;30;46mthe quick brown fox[0m Underline Bright Black (on Cyan background) +[4;7;30;46mthe quick brown fox[0m Underline Inverse Black (on Cyan background) +[7;1;30;46mthe quick brown fox[0m Inverse Bright Black (on Cyan background) +[7;4;30;46mthe quick brown fox[0m Inverse Underline Black (on Cyan background) +[1;4;31;46mthe quick brown fox[0m Bright Underline Red (on Cyan background) +[1;7;31;46mthe quick brown fox[0m Bright Inverse Red (on Cyan background) +[4;1;31;46mthe quick brown fox[0m Underline Bright Red (on Cyan background) +[4;7;31;46mthe quick brown fox[0m Underline Inverse Red (on Cyan background) +[7;1;31;46mthe quick brown fox[0m Inverse Bright Red (on Cyan background) +[7;4;31;46mthe quick brown fox[0m Inverse Underline Red (on Cyan background) +[1;4;32;46mthe quick brown fox[0m Bright Underline Green (on Cyan background) +[1;7;32;46mthe quick brown fox[0m Bright Inverse Green (on Cyan background) +[4;1;32;46mthe quick brown fox[0m Underline Bright Green (on Cyan background) +[4;7;32;46mthe quick brown fox[0m Underline Inverse Green (on Cyan background) +[7;1;32;46mthe quick brown fox[0m Inverse Bright Green (on Cyan background) +[7;4;32;46mthe quick brown fox[0m Inverse Underline Green (on Cyan background) +[1;4;33;46mthe quick brown fox[0m Bright Underline Yellow (on Cyan background) +[1;7;33;46mthe quick brown fox[0m Bright Inverse Yellow (on Cyan background) +[4;1;33;46mthe quick brown fox[0m Underline Bright Yellow (on Cyan background) +[4;7;33;46mthe quick brown fox[0m Underline Inverse Yellow (on Cyan background) +[7;1;33;46mthe quick brown fox[0m Inverse Bright Yellow (on Cyan background) +[7;4;33;46mthe quick brown fox[0m Inverse Underline Yellow (on Cyan background) +[1;4;34;46mthe quick brown fox[0m Bright Underline Blue (on Cyan background) +[1;7;34;46mthe quick brown fox[0m Bright Inverse Blue (on Cyan background) +[4;1;34;46mthe quick brown fox[0m Underline Bright Blue (on Cyan background) +[4;7;34;46mthe quick brown fox[0m Underline Inverse Blue (on Cyan background) +[7;1;34;46mthe quick brown fox[0m Inverse Bright Blue (on Cyan background) +[7;4;34;46mthe quick brown fox[0m Inverse Underline Blue (on Cyan background) +[1;4;35;46mthe quick brown fox[0m Bright Underline Magenta (on Cyan background) +[1;7;35;46mthe quick brown fox[0m Bright Inverse Magenta (on Cyan background) +[4;1;35;46mthe quick brown fox[0m Underline Bright Magenta (on Cyan background) +[4;7;35;46mthe quick brown fox[0m Underline Inverse Magenta (on Cyan background) +[7;1;35;46mthe quick brown fox[0m Inverse Bright Magenta (on Cyan background) +[7;4;35;46mthe quick brown fox[0m Inverse Underline Magenta (on Cyan background) +[1;4;36;46mthe quick brown fox[0m Bright Underline Cyan (on Cyan background) +[1;7;36;46mthe quick brown fox[0m Bright Inverse Cyan (on Cyan background) +[4;1;36;46mthe quick brown fox[0m Underline Bright Cyan (on Cyan background) +[4;7;36;46mthe quick brown fox[0m Underline Inverse Cyan (on Cyan background) +[7;1;36;46mthe quick brown fox[0m Inverse Bright Cyan (on Cyan background) +[7;4;36;46mthe quick brown fox[0m Inverse Underline Cyan (on Cyan background) +[1;4;37;46mthe quick brown fox[0m Bright Underline White (on Cyan background) +[1;7;37;46mthe quick brown fox[0m Bright Inverse White (on Cyan background) +[4;1;37;46mthe quick brown fox[0m Underline Bright White (on Cyan background) +[4;7;37;46mthe quick brown fox[0m Underline Inverse White (on Cyan background) +[7;1;37;46mthe quick brown fox[0m Inverse Bright White (on Cyan background) +[7;4;37;46mthe quick brown fox[0m Inverse Underline White (on Cyan background) +[1;4;30;47mthe quick brown fox[0m Bright Underline Black (on White background) +[1;7;30;47mthe quick brown fox[0m Bright Inverse Black (on White background) +[4;1;30;47mthe quick brown fox[0m Underline Bright Black (on White background) +[4;7;30;47mthe quick brown fox[0m Underline Inverse Black (on White background) +[7;1;30;47mthe quick brown fox[0m Inverse Bright Black (on White background) +[7;4;30;47mthe quick brown fox[0m Inverse Underline Black (on White background) +[1;4;31;47mthe quick brown fox[0m Bright Underline Red (on White background) +[1;7;31;47mthe quick brown fox[0m Bright Inverse Red (on White background) +[4;1;31;47mthe quick brown fox[0m Underline Bright Red (on White background) +[4;7;31;47mthe quick brown fox[0m Underline Inverse Red (on White background) +[7;1;31;47mthe quick brown fox[0m Inverse Bright Red (on White background) +[7;4;31;47mthe quick brown fox[0m Inverse Underline Red (on White background) +[1;4;32;47mthe quick brown fox[0m Bright Underline Green (on White background) +[1;7;32;47mthe quick brown fox[0m Bright Inverse Green (on White background) +[4;1;32;47mthe quick brown fox[0m Underline Bright Green (on White background) +[4;7;32;47mthe quick brown fox[0m Underline Inverse Green (on White background) +[7;1;32;47mthe quick brown fox[0m Inverse Bright Green (on White background) +[7;4;32;47mthe quick brown fox[0m Inverse Underline Green (on White background) +[1;4;33;47mthe quick brown fox[0m Bright Underline Yellow (on White background) +[1;7;33;47mthe quick brown fox[0m Bright Inverse Yellow (on White background) +[4;1;33;47mthe quick brown fox[0m Underline Bright Yellow (on White background) +[4;7;33;47mthe quick brown fox[0m Underline Inverse Yellow (on White background) +[7;1;33;47mthe quick brown fox[0m Inverse Bright Yellow (on White background) +[7;4;33;47mthe quick brown fox[0m Inverse Underline Yellow (on White background) +[1;4;34;47mthe quick brown fox[0m Bright Underline Blue (on White background) +[1;7;34;47mthe quick brown fox[0m Bright Inverse Blue (on White background) +[4;1;34;47mthe quick brown fox[0m Underline Bright Blue (on White background) +[4;7;34;47mthe quick brown fox[0m Underline Inverse Blue (on White background) +[7;1;34;47mthe quick brown fox[0m Inverse Bright Blue (on White background) +[7;4;34;47mthe quick brown fox[0m Inverse Underline Blue (on White background) +[1;4;35;47mthe quick brown fox[0m Bright Underline Magenta (on White background) +[1;7;35;47mthe quick brown fox[0m Bright Inverse Magenta (on White background) +[4;1;35;47mthe quick brown fox[0m Underline Bright Magenta (on White background) +[4;7;35;47mthe quick brown fox[0m Underline Inverse Magenta (on White background) +[7;1;35;47mthe quick brown fox[0m Inverse Bright Magenta (on White background) +[7;4;35;47mthe quick brown fox[0m Inverse Underline Magenta (on White background) +[1;4;36;47mthe quick brown fox[0m Bright Underline Cyan (on White background) +[1;7;36;47mthe quick brown fox[0m Bright Inverse Cyan (on White background) +[4;1;36;47mthe quick brown fox[0m Underline Bright Cyan (on White background) +[4;7;36;47mthe quick brown fox[0m Underline Inverse Cyan (on White background) +[7;1;36;47mthe quick brown fox[0m Inverse Bright Cyan (on White background) +[7;4;36;47mthe quick brown fox[0m Inverse Underline Cyan (on White background) +[1;4;37;47mthe quick brown fox[0m Bright Underline White (on White background) +[1;7;37;47mthe quick brown fox[0m Bright Inverse White (on White background) +[4;1;37;47mthe quick brown fox[0m Underline Bright White (on White background) +[4;7;37;47mthe quick brown fox[0m Underline Inverse White (on White background) +[7;1;37;47mthe quick brown fox[0m Inverse Bright White (on White background) +[7;4;37;47mthe quick brown fox[0m Inverse Underline White (on White background) diff --git a/test/files/run/color.scala b/test/files/run/color.scala new file mode 100644 index 0000000000..a0af8477e7 --- /dev/null +++ b/test/files/run/color.scala @@ -0,0 +1,33 @@ +import scala.tools.util.color._ + +object Test { + // The ones which are somewhat widely supported. + def effects = List(Bright, Underline, Inverse) + + def demo(text: String) = { + def to_s(esc: Ansi): String = esc.atoms map { + case x: AnsiBackground => "" + x + case x => "%-10s" format x + } mkString " " + + def show(esc: Ansi) = println("%s %s".format(text in esc, to_s(esc))) + + println("\n1 color") + for (c <- Ansi.colors) show(c) + println("\n1 effect") + for (e <- Ansi.effects) show(e) + println("\n1 color 1 effect") + for (c <- Ansi.colors; e <- effects) show(c / e) + println("\n2 colors 0 effects") + for (c1 <- Ansi.colors ; c2 <- Ansi.colors) show(c2 on c1) + println("\n2 colors 1 effect") + for (c1 <- Ansi.colors ; c2 <- Ansi.colors ; e1 <- effects) show((c2 on c1) / e1) + println("\n2 colors 2 effects") + for (c1 <- Ansi.colors ; c2 <- Ansi.colors ; e1 <- effects ; e2 <- effects ; if e1 != e2) show((c2 on c1) / e1 / e2) + } + + def main(args: Array[String]): Unit = { + val str = if (args.size > 1) args mkString " " else "the quick brown fox" + demo(str) + } +} diff --git a/test/files/run/compiler-asSeenFrom.check b/test/files/run/compiler-asSeenFrom.check new file mode 100644 index 0000000000..f198e61072 --- /dev/null +++ b/test/files/run/compiler-asSeenFrom.check @@ -0,0 +1,323 @@ +class C { + type seen from prefix is + ---- ---------------- -- + C[List[T3]]#I[T1] D[A1] C[List[T3]]#I[A1] + C[List[T3]]#I[T1] D[T3] C[List[T3]]#I[T3] + C[List[T3]]#J[T1] D[A1] C[List[T3]]#J[A1] + C[List[T3]]#J[T1] D[T3] C[List[T3]]#J[T3] + C[T1]#I[Int] C[List[T3]] C[List[T3]]#I[Int] + C[T1]#I[Int] D[A1] C[A1]#I[Int] + C[T1]#I[Int] D[T3] C[T3]#I[Int] + C[T1]#I[List[Int]] C[List[T3]] C[List[T3]]#I[List[Int]] + C[T1]#I[List[Int]] D[A1] C[A1]#I[List[Int]] + C[T1]#I[List[Int]] D[T3] C[T3]#I[List[Int]] + C[T1]#I[T1] C[List[T3]] C[List[T3]]#I[List[T3]] + C[T1]#I[T1] D[A1] C[A1]#I[A1] + C[T1]#I[T1] D[T3] C[T3]#I[T3] + C[T1]#I[T2] C[List[T3]] C[List[T3]]#I[T2] + C[T1]#I[T2] D[A1] C[A1]#I[T2] + C[T1]#I[T2] D[T3] C[T3]#I[T2] + C[T1]#I[T3] C[List[T3]] C[List[T3]]#I[T3] + C[T1]#I[T3] D[A1] C[A1]#I[T3] + C[T1]#I[T3] D[T3] C[T3]#I[T3] + C[T1]#I[T4] C[List[T3]] C[List[T3]]#I[T4] + C[T1]#I[T4] D[A1] C[A1]#I[T4] + C[T1]#I[T4] D[T3] C[T3]#I[T4] + C[T1]#J[Int] C[List[T3]] C[List[T3]]#J[Int] + C[T1]#J[Int] D[A1] C[A1]#J[Int] + C[T1]#J[Int] D[T3] C[T3]#J[Int] + C[T1]#J[List[Int]] C[List[T3]] C[List[T3]]#J[List[Int]] + C[T1]#J[List[Int]] D[A1] C[A1]#J[List[Int]] + C[T1]#J[List[Int]] D[T3] C[T3]#J[List[Int]] + C[T1]#J[T1] C[List[T3]] C[List[T3]]#J[List[T3]] + C[T1]#J[T1] D[A1] C[A1]#J[A1] + C[T1]#J[T1] D[T3] C[T3]#J[T3] + C[T1]#J[T2] C[List[T3]] C[List[T3]]#J[T2] + C[T1]#J[T2] D[A1] C[A1]#J[T2] + C[T1]#J[T2] D[T3] C[T3]#J[T2] + C[T1]#J[T3] C[List[T3]] C[List[T3]]#J[T3] + C[T1]#J[T3] D[A1] C[A1]#J[T3] + C[T1]#J[T3] D[T3] C[T3]#J[T3] + C[T1]#J[T4] C[List[T3]] C[List[T3]]#J[T4] + C[T1]#J[T4] D[A1] C[A1]#J[T4] + C[T1]#J[T4] D[T3] C[T3]#J[T4] + D[T3]#J[T1] C[List[T3]] D[T3]#J[List[T3]] + D[T3]#J[T1] D[A1] D[T3]#J[A1] + D[A1]#J[T1] C[List[T3]] D[A1]#J[List[T3]] + D[A1]#J[T1] D[T3] D[A1]#J[T3] +} +class D { + type seen from prefix is + ---- ---------------- -- + C[List[T3]]#I[Int] D[A1] C[List[A1]]#I[Int] + C[List[T3]]#I[List[Int]] D[A1] C[List[A1]]#I[List[Int]] + C[List[T3]]#I[T1] D[A1] C[List[A1]]#I[T1] + C[List[T3]]#I[T2] D[A1] C[List[A1]]#I[T2] + C[List[T3]]#I[T3] D[A1] C[List[A1]]#I[A1] + C[List[T3]]#I[T4] D[A1] C[List[A1]]#I[T4] + C[List[T3]]#J[Int] D[A1] C[List[A1]]#J[Int] + C[List[T3]]#J[List[Int]] D[A1] C[List[A1]]#J[List[Int]] + C[List[T3]]#J[T1] D[A1] C[List[A1]]#J[T1] + C[List[T3]]#J[T2] D[A1] C[List[A1]]#J[T2] + C[List[T3]]#J[T3] D[A1] C[List[A1]]#J[A1] + C[List[T3]]#J[T4] D[A1] C[List[A1]]#J[T4] + C[T1]#I[T3] D[A1] C[T1]#I[A1] + C[T1]#J[T3] D[A1] C[T1]#J[A1] + D[T3]#J[Int] D[A1] D[A1]#J[Int] + D[T3]#J[List[Int]] D[A1] D[A1]#J[List[Int]] + D[T3]#J[T1] D[A1] D[A1]#J[T1] + D[T3]#J[T2] D[A1] D[A1]#J[T2] + D[T3]#J[T3] D[A1] D[A1]#J[A1] + D[T3]#J[T4] D[A1] D[A1]#J[T4] +} +class I { + type seen from prefix is + ---- ---------------- -- + C[List[T3]]#I[T1] D.this.J[T4] C[List[T3]]#I[List[T3]] + C[List[T3]]#I[T1] Z.dZ.J[A2] C[List[T3]]#I[List[A1]] + C[List[T3]]#I[T1] Z.dZ.J[P] C[List[T3]]#I[List[A1]] + C[List[T3]]#I[T2] D.this.J[T4] C[List[T3]]#I[T4] + C[List[T3]]#I[T2] Z.dZ.J[A2] C[List[T3]]#I[A2] + C[List[T3]]#I[T2] Z.dZ.J[P] C[List[T3]]#I[P] + C[List[T3]]#J[T1] D.this.J[T4] C[List[T3]]#J[List[T3]] + C[List[T3]]#J[T1] Z.dZ.J[A2] C[List[T3]]#J[List[A1]] + C[List[T3]]#J[T1] Z.dZ.J[P] C[List[T3]]#J[List[A1]] + C[List[T3]]#J[T2] D.this.J[T4] C[List[T3]]#J[T4] + C[List[T3]]#J[T2] Z.dZ.J[A2] C[List[T3]]#J[A2] + C[List[T3]]#J[T2] Z.dZ.J[P] C[List[T3]]#J[P] + C[T1]#I[Int] D.this.J[T4] C[List[T3]]#I[Int] + C[T1]#I[Int] Z.dZ.J[A2] C[List[A1]]#I[Int] + C[T1]#I[Int] Z.dZ.J[P] C[List[A1]]#I[Int] + C[T1]#I[List[Int]] D.this.J[T4] C[List[T3]]#I[List[Int]] + C[T1]#I[List[Int]] Z.dZ.J[A2] C[List[A1]]#I[List[Int]] + C[T1]#I[List[Int]] Z.dZ.J[P] C[List[A1]]#I[List[Int]] + C[T1]#I[T1] D.this.J[T4] C[List[T3]]#I[List[T3]] + C[T1]#I[T1] Z.dZ.J[A2] C[List[A1]]#I[List[A1]] + C[T1]#I[T1] Z.dZ.J[P] C[List[A1]]#I[List[A1]] + C[T1]#I[T2] D.this.J[T4] C[List[T3]]#I[T4] + C[T1]#I[T2] Z.dZ.J[A2] C[List[A1]]#I[A2] + C[T1]#I[T2] Z.dZ.J[P] C[List[A1]]#I[P] + C[T1]#I[T3] D.this.J[T4] C[List[T3]]#I[T3] + C[T1]#I[T3] Z.dZ.J[A2] C[List[A1]]#I[T3] + C[T1]#I[T3] Z.dZ.J[P] C[List[A1]]#I[T3] + C[T1]#I[T4] D.this.J[T4] C[List[T3]]#I[T4] + C[T1]#I[T4] Z.dZ.J[A2] C[List[A1]]#I[T4] + C[T1]#I[T4] Z.dZ.J[P] C[List[A1]]#I[T4] + C[T1]#J[Int] D.this.J[T4] C[List[T3]]#J[Int] + C[T1]#J[Int] Z.dZ.J[A2] C[List[A1]]#J[Int] + C[T1]#J[Int] Z.dZ.J[P] C[List[A1]]#J[Int] + C[T1]#J[List[Int]] D.this.J[T4] C[List[T3]]#J[List[Int]] + C[T1]#J[List[Int]] Z.dZ.J[A2] C[List[A1]]#J[List[Int]] + C[T1]#J[List[Int]] Z.dZ.J[P] C[List[A1]]#J[List[Int]] + C[T1]#J[T1] D.this.J[T4] C[List[T3]]#J[List[T3]] + C[T1]#J[T1] Z.dZ.J[A2] C[List[A1]]#J[List[A1]] + C[T1]#J[T1] Z.dZ.J[P] C[List[A1]]#J[List[A1]] + C[T1]#J[T2] D.this.J[T4] C[List[T3]]#J[T4] + C[T1]#J[T2] Z.dZ.J[A2] C[List[A1]]#J[A2] + C[T1]#J[T2] Z.dZ.J[P] C[List[A1]]#J[P] + C[T1]#J[T3] D.this.J[T4] C[List[T3]]#J[T3] + C[T1]#J[T3] Z.dZ.J[A2] C[List[A1]]#J[T3] + C[T1]#J[T3] Z.dZ.J[P] C[List[A1]]#J[T3] + C[T1]#J[T4] D.this.J[T4] C[List[T3]]#J[T4] + C[T1]#J[T4] Z.dZ.J[A2] C[List[A1]]#J[T4] + C[T1]#J[T4] Z.dZ.J[P] C[List[A1]]#J[T4] + D[T3]#J[T1] D.this.J[T4] D[T3]#J[List[T3]] + D[T3]#J[T1] Z.dZ.J[A2] D[T3]#J[List[A1]] + D[T3]#J[T1] Z.dZ.J[P] D[T3]#J[List[A1]] + D[T3]#J[T2] D.this.J[T4] D[T3]#J[T4] + D[T3]#J[T2] Z.dZ.J[A2] D[T3]#J[A2] + D[T3]#J[T2] Z.dZ.J[P] D[T3]#J[P] + D[A1]#J[T1] D.this.J[T4] D[A1]#J[List[T3]] + D[A1]#J[T1] Z.dZ.J[A2] D[A1]#J[List[A1]] + D[A1]#J[T1] Z.dZ.J[P] D[A1]#J[List[A1]] + D[A1]#J[T2] D.this.J[T4] D[A1]#J[T4] + D[A1]#J[T2] Z.dZ.J[A2] D[A1]#J[A2] + D[A1]#J[T2] Z.dZ.J[P] D[A1]#J[P] +} +class J { + type seen from prefix is + ---- ---------------- -- + C[List[T3]]#I[Int] Z.dZ.J[A2] C[List[A1]]#I[Int] + C[List[T3]]#I[Int] Z.dZ.J[P] C[List[A1]]#I[Int] + C[List[T3]]#I[List[Int]] Z.dZ.J[A2] C[List[A1]]#I[List[Int]] + C[List[T3]]#I[List[Int]] Z.dZ.J[P] C[List[A1]]#I[List[Int]] + C[List[T3]]#I[T1] Z.dZ.J[A2] C[List[A1]]#I[T1] + C[List[T3]]#I[T1] Z.dZ.J[P] C[List[A1]]#I[T1] + C[List[T3]]#I[T2] Z.dZ.J[A2] C[List[A1]]#I[T2] + C[List[T3]]#I[T2] Z.dZ.J[P] C[List[A1]]#I[T2] + C[List[T3]]#I[T3] Z.dZ.J[A2] C[List[A1]]#I[A1] + C[List[T3]]#I[T3] Z.dZ.J[P] C[List[A1]]#I[A1] + C[List[T3]]#I[T4] Z.dZ.J[A2] C[List[A1]]#I[A2] + C[List[T3]]#I[T4] Z.dZ.J[P] C[List[A1]]#I[P] + C[List[T3]]#J[Int] Z.dZ.J[A2] C[List[A1]]#J[Int] + C[List[T3]]#J[Int] Z.dZ.J[P] C[List[A1]]#J[Int] + C[List[T3]]#J[List[Int]] Z.dZ.J[A2] C[List[A1]]#J[List[Int]] + C[List[T3]]#J[List[Int]] Z.dZ.J[P] C[List[A1]]#J[List[Int]] + C[List[T3]]#J[T1] Z.dZ.J[A2] C[List[A1]]#J[T1] + C[List[T3]]#J[T1] Z.dZ.J[P] C[List[A1]]#J[T1] + C[List[T3]]#J[T2] Z.dZ.J[A2] C[List[A1]]#J[T2] + C[List[T3]]#J[T2] Z.dZ.J[P] C[List[A1]]#J[T2] + C[List[T3]]#J[T3] Z.dZ.J[A2] C[List[A1]]#J[A1] + C[List[T3]]#J[T3] Z.dZ.J[P] C[List[A1]]#J[A1] + C[List[T3]]#J[T4] Z.dZ.J[A2] C[List[A1]]#J[A2] + C[List[T3]]#J[T4] Z.dZ.J[P] C[List[A1]]#J[P] + C[T1]#I[T3] Z.dZ.J[A2] C[T1]#I[A1] + C[T1]#I[T3] Z.dZ.J[P] C[T1]#I[A1] + C[T1]#I[T4] Z.dZ.J[A2] C[T1]#I[A2] + C[T1]#I[T4] Z.dZ.J[P] C[T1]#I[P] + C[T1]#J[T3] Z.dZ.J[A2] C[T1]#J[A1] + C[T1]#J[T3] Z.dZ.J[P] C[T1]#J[A1] + C[T1]#J[T4] Z.dZ.J[A2] C[T1]#J[A2] + C[T1]#J[T4] Z.dZ.J[P] C[T1]#J[P] + D[T3]#J[Int] Z.dZ.J[A2] D[A1]#J[Int] + D[T3]#J[Int] Z.dZ.J[P] D[A1]#J[Int] + D[T3]#J[List[Int]] Z.dZ.J[A2] D[A1]#J[List[Int]] + D[T3]#J[List[Int]] Z.dZ.J[P] D[A1]#J[List[Int]] + D[T3]#J[T1] Z.dZ.J[A2] D[A1]#J[T1] + D[T3]#J[T1] Z.dZ.J[P] D[A1]#J[T1] + D[T3]#J[T2] Z.dZ.J[A2] D[A1]#J[T2] + D[T3]#J[T2] Z.dZ.J[P] D[A1]#J[T2] + D[T3]#J[T3] Z.dZ.J[A2] D[A1]#J[A1] + D[T3]#J[T3] Z.dZ.J[P] D[A1]#J[A1] + D[T3]#J[T4] Z.dZ.J[A2] D[A1]#J[A2] + D[T3]#J[T4] Z.dZ.J[P] D[A1]#J[P] + D[A1]#J[T3] Z.dZ.J[A2] D[A1]#J[A1] + D[A1]#J[T3] Z.dZ.J[P] D[A1]#J[A1] + D[A1]#J[T4] Z.dZ.J[A2] D[A1]#J[A2] + D[A1]#J[T4] Z.dZ.J[P] D[A1]#J[P] +} +class D { // after parser + private val cD: ll.C[List[T3]] + val cD: ll.C[List[T3]] +} + +class D { // after uncurry + private val cD: ll.C[List[T3]] + val cD(): ll.C[List[T3]] +} + +class D { // after erasure + private val cD: ll.C + val cD(): ll.C +} + +object Z { // after parser + def kz[P <: ll.Z.dZ.J[ll.A2]]: ll.Z.dZ.J[P] + private val jZ: ll.Z.dZ.J[ll.A2] + val jZ: ll.Z.dZ.J[ll.A2] + private val dZ: ll.D[ll.A1] + val dZ: ll.D[ll.A1] +} + +object Z { // after uncurry + def kz[P <: ll.Z.dZ.J[ll.A2]](): ll.Z.dZ.J[P] + private val jZ: ll.Z.dZ.J[ll.A2] + val jZ(): ll.Z.dZ.J[ll.A2] + private val dZ: ll.D[ll.A1] + val dZ(): ll.D[ll.A1] +} + +object Z { // after erasure + def kz(): ll.D#J + private val jZ: ll.D#J + val jZ(): ll.D#J + private val dZ: ll.D + val dZ(): ll.D +} + +object Z { // after flatten + def kz(): ll.D#D$J + private val jZ: ll.D#D$J + val jZ(): ll.D#D$J + private val dZ: ll.D + val dZ(): ll.D +} + +value dZ { // after parser + private val cD: ll.C[List[T3]] + val cD: ll.C[List[T3]] +} + +value dZ { // after parser + private val cD: ll.C[List[T3]] + val cD: ll.C[List[T3]] +} + +value dZ { // after uncurry + private val cD: ll.C[List[T3]] + val cD(): ll.C[List[T3]] +} + +value dZ { // after erasure + private val cD: ll.C + val cD(): ll.C +} + +value jZ { // after parser + def thisI(): I.this.type + def thisC(): C.this.type + def t2(): T2 + def t1(): T1 +} + +value jZ { // after parser + def thisI(): I.this.type + def thisC(): C.this.type + def t2(): T2 + def t1(): T1 +} + +value jZ { // after explicitouter + protected val $outer: D.this.type + val ll$D$J$$$outer(): D.this.type + val ll$C$I$$$outer(): C.this.type + def thisI(): I.this.type + def thisC(): C.this.type + def t2(): T2 + def t1(): T1 +} + +value jZ { // after erasure + protected val $outer: ll.D + val ll$D$J$$$outer(): ll.D + protected val $outer: ll.C + val ll$C$I$$$outer(): ll.C + def thisI(): ll.C#I + def thisC(): ll.C + def t2(): Object + def t1(): Object +} + +value jZ { // after flatten + protected val $outer: ll.D + val ll$D$J$$$outer(): ll.D + protected val $outer: ll.C + val ll$C$I$$$outer(): ll.C + def thisI(): ll.C#C$I + def thisC(): ll.C + def t2(): Object + def t1(): Object +} + +method kz { // after parser + def thisI(): I.this.type + def thisC(): C.this.type + def t2(): T2 + def t1(): T1 +} + +value $outer { // after parser + private val cD: ll.C[List[T3]] + val cD: ll.C[List[T3]] +} + +value $outer { // after uncurry + private val cD: ll.C[List[T3]] + val cD(): ll.C[List[T3]] +} + +value $outer { // after erasure + private val cD: ll.C + val cD(): ll.C +} + diff --git a/test/files/run/compiler-asSeenFrom.scala b/test/files/run/compiler-asSeenFrom.scala new file mode 100644 index 0000000000..1fc3a5ee71 --- /dev/null +++ b/test/files/run/compiler-asSeenFrom.scala @@ -0,0 +1,122 @@ +import scala.tools.nsc._ +import scala.tools.partest.CompilerTest +import scala.collection.{ mutable, immutable, generic } + +/** It's too messy but it's better than not having it. + */ +object Test extends CompilerTest { + import global._ + import definitions._ + + override def sources = List(lambdaLift) + def lambdaLift = """ +package ll { + class A1 + class A2 + class X + class C[T1]() { + class I[T2]() { + def t1(): T1 = ??? + def t2(): T2 = ??? + def thisC(): C.this.type = ??? + def thisI(): I.this.type = ??? + } + } + class D[T3]() extends C[T3]() { + val cD: C[List[T3]] = ??? + class J[T4]() extends cD.I[T4]() + } + object Z { + val dZ: D[A1] = ??? + val jZ: dZ.J[A2] = ??? + + def kz[P <: dZ.J[A2]]: dZ.J[P] = ??? + } +} +""" + + object syms extends SymsInPackage("ll") { + def isPossibleEnclosure(encl: Symbol, sym: Symbol) = sym.enclClassChain drop 1 exists (_ isSubClass encl) + def isInterestingPrefix(pre: Type) = pre.typeConstructor.typeParams.nonEmpty && pre.members.exists(_.isType) + + def asSeenPrefixes = tpes map (_.finalResultType) distinct + def typeRefPrefixes = asSeenPrefixes filter isInterestingPrefix + + def nestsIn(outer: Symbol) = classes filter (c => c.enclClassChain drop 1 exists(_ isSubClass outer)) + def typeRefs(targs: List[Type]) = ( + for (p <- typeRefPrefixes ; c <- classes filter (isPossibleEnclosure(p.typeSymbol, _)) ; a <- targs) yield + typeRef(p, c, List(a)) + ) + + val wfmt = "%-" + 25 + "s" + def to_s(x: Any): String = wfmt.format(x.toString.replaceAll("""\bll\.""", "")) + + def fmt(args: Any*): String = { + (args map to_s mkString " ").replaceAll("""\s+$""", "") + } + def fname(sym: Symbol) = { + val p = "" + sym.owner.name + val x = if (sym.owner.isPackageClass || sym.owner.isModuleClass || sym.owner.isTerm) "." else "#" + sym.kindString + " " + p + x + sym.name + } + + def permuteAsSeenFrom(targs: List[Type]) = ( + for { + tp <- typeRefs(targs filterNot (_ eq NoType)) + prefix <- asSeenPrefixes + if tp.prefix != prefix + site <- classes + seen = tp.asSeenFrom(prefix, site) + if tp != seen + if !seen.isInstanceOf[ExistentialType] + } + yield ((site, tp, prefix, seen)) + ) + + def block(label: Any)(lines: List[String]): List[String] = { + val first = "" + label + " {" + val last = "}" + + first +: lines.map(" " + _) :+ last + } + + def permute(targs: List[Type]): List[String] = { + permuteAsSeenFrom(targs).groupBy(_._1).toList.sortBy(_._1.toString) flatMap { + case (site, xs) => + block(fmt(site)) { + fmt("type", "seen from prefix", "is") :: + fmt("----", "----------------", "--") :: { + xs.groupBy(_._2).toList.sortBy(_._1.toString) flatMap { + case (tp, ys) => + (ys map { case (_, _, prefix, seen) => fmt(tp, prefix, seen) }).sorted.distinct + } + } + } + } + } + } + + def pretty(xs: List[_]) = if (xs.isEmpty) "" else xs.mkString("\n ", "\n ", "\n") + + def signaturesIn(info: Type): List[String] = ( + info.members + filterNot (s => s.isType || s.owner == ObjectClass || s.owner == AnyClass || s.isConstructor) + map (_.defString) + ) + + def check(source: String, unit: global.CompilationUnit) = { + import syms._ + + afterTyper { + val typeArgs = List[Type](IntClass.tpe, ListClass[Int]) ++ tparams.map(_.tpe) + permute(typeArgs) foreach println + } + for (x <- classes ++ terms) { + afterEachPhase(signaturesIn(x.tpe)) collect { + case (ph, sigs) if sigs.nonEmpty => + println(sigs.mkString(x + " { // after " + ph + "\n ", "\n ", "\n}\n")) + } + } + true + } +} diff --git a/test/files/run/ctries/concmap.scala b/test/files/run/ctries/concmap.scala index d73e33182a..bf8cc9d12f 100644 --- a/test/files/run/ctries/concmap.scala +++ b/test/files/run/ctries/concmap.scala @@ -1,7 +1,7 @@ -import collection.mutable.Ctrie +import collection.mutable.ConcurrentTrieMap object ConcurrentMapSpec extends Spec { @@ -11,13 +11,13 @@ object ConcurrentMapSpec extends Spec { def test() { "support put" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until initsz) assert(ct.put(new Wrap(i), i) == None) for (i <- 0 until initsz) assert(ct.put(new Wrap(i), -i) == Some(i)) } "support put if absent" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until initsz) ct.update(new Wrap(i), i) for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i)) for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i)) @@ -26,7 +26,7 @@ object ConcurrentMapSpec extends Spec { } "support remove if mapped to a specific value" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until initsz) ct.update(new Wrap(i), i) for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), -i - 1) == false) for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == true) @@ -34,7 +34,7 @@ object ConcurrentMapSpec extends Spec { } "support replace if mapped to a specific value" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until initsz) ct.update(new Wrap(i), i) for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i - 1, -i - 2) == false) for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == true) @@ -43,7 +43,7 @@ object ConcurrentMapSpec extends Spec { } "support replace if present" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until initsz) ct.update(new Wrap(i), i) for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i) == Some(i)) for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i) == Some(-i)) @@ -56,7 +56,7 @@ object ConcurrentMapSpec extends Spec { } "support replace if mapped to a specific value, using several threads" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] val sz = 55000 for (i <- 0 until sz) ct.update(new Wrap(i), i) @@ -89,7 +89,7 @@ object ConcurrentMapSpec extends Spec { } "support put if absent, several threads" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] val sz = 110000 class Updater(offs: Int) extends Thread { @@ -110,7 +110,7 @@ object ConcurrentMapSpec extends Spec { } "support remove if mapped to a specific value, several threads" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] val sz = 55000 for (i <- 0 until sz) ct.update(new Wrap(i), i) @@ -132,7 +132,7 @@ object ConcurrentMapSpec extends Spec { } "have all or none of the elements depending on the oddity" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] val sz = 65000 for (i <- 0 until sz) ct(new Wrap(i)) = i @@ -165,7 +165,7 @@ object ConcurrentMapSpec extends Spec { } "compute size correctly" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] val sz = 36450 for (i <- 0 until sz) ct(new Wrap(i)) = i @@ -174,7 +174,7 @@ object ConcurrentMapSpec extends Spec { } "compute size correctly in parallel" in { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] val sz = 36450 for (i <- 0 until sz) ct(new Wrap(i)) = i val pct = ct.par diff --git a/test/files/run/ctries/iterator.scala b/test/files/run/ctries/iterator.scala index 85a6ab7623..dbfab6b8a9 100644 --- a/test/files/run/ctries/iterator.scala +++ b/test/files/run/ctries/iterator.scala @@ -3,7 +3,7 @@ import collection._ -import collection.mutable.Ctrie +import collection.mutable.ConcurrentTrieMap @@ -11,7 +11,7 @@ object IteratorSpec extends Spec { def test() { "work for an empty trie" in { - val ct = new Ctrie + val ct = new ConcurrentTrieMap val it = ct.iterator it.hasNext shouldEqual (false) @@ -19,7 +19,7 @@ object IteratorSpec extends Spec { } def nonEmptyIteratorCheck(sz: Int) { - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct.put(new Wrap(i), i) val it = ct.iterator @@ -84,7 +84,7 @@ object IteratorSpec extends Spec { } def nonEmptyCollideCheck(sz: Int) { - val ct = new Ctrie[DumbHash, Int] + val ct = new ConcurrentTrieMap[DumbHash, Int] for (i <- 0 until sz) ct.put(new DumbHash(i), i) val it = ct.iterator @@ -144,7 +144,7 @@ object IteratorSpec extends Spec { val W = 15 val S = 5 val checks = 5 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct.put(new Wrap(i), i) class Modifier extends Thread { @@ -156,7 +156,7 @@ object IteratorSpec extends Spec { } } - def consistentIteration(ct: Ctrie[Wrap, Int], checks: Int) { + def consistentIteration(ct: ConcurrentTrieMap[Wrap, Int], checks: Int) { class Iter extends Thread { override def run() { val snap = ct.readOnlySnapshot() @@ -185,7 +185,7 @@ object IteratorSpec extends Spec { val sgroupsize = 10 val sgroupnum = 5 val removerslowdown = 50 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct.put(new Wrap(i), i) class Remover extends Thread { @@ -227,7 +227,7 @@ object IteratorSpec extends Spec { val sgroupsize = 10 val sgroupnum = 10 val inserterslowdown = 50 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] class Inserter extends Thread { override def run() { @@ -265,7 +265,7 @@ object IteratorSpec extends Spec { "work on a yet unevaluated snapshot" in { val sz = 50000 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct.update(new Wrap(i), i) val snap = ct.snapshot() @@ -276,7 +276,7 @@ object IteratorSpec extends Spec { "be duplicated" in { val sz = 50 - val ct = collection.parallel.mutable.ParCtrie((0 until sz) zip (0 until sz): _*) + val ct = collection.parallel.mutable.ParConcurrentTrieMap((0 until sz) zip (0 until sz): _*) val it = ct.splitter for (_ <- 0 until (sz / 2)) it.next() val dupit = it.dup diff --git a/test/files/run/ctries/lnode.scala b/test/files/run/ctries/lnode.scala index 88cbeed1f6..e480795956 100644 --- a/test/files/run/ctries/lnode.scala +++ b/test/files/run/ctries/lnode.scala @@ -1,7 +1,7 @@ -import collection.mutable.Ctrie +import collection.mutable.ConcurrentTrieMap object LNodeSpec extends Spec { @@ -11,19 +11,19 @@ object LNodeSpec extends Spec { def test() { "accept elements with the same hash codes" in { - val ct = new Ctrie[DumbHash, Int] + val ct = new ConcurrentTrieMap[DumbHash, Int] for (i <- 0 until initsz) ct.update(new DumbHash(i), i) } "lookup elements with the same hash codes" in { - val ct = new Ctrie[DumbHash, Int] + val ct = new ConcurrentTrieMap[DumbHash, Int] for (i <- 0 until initsz) ct.update(new DumbHash(i), i) for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == Some(i)) for (i <- initsz until secondsz) assert(ct.get(new DumbHash(i)) == None) } "remove elements with the same hash codes" in { - val ct = new Ctrie[DumbHash, Int] + val ct = new ConcurrentTrieMap[DumbHash, Int] for (i <- 0 until initsz) ct.update(new DumbHash(i), i) for (i <- 0 until initsz) { val remelem = ct.remove(new DumbHash(i)) @@ -33,7 +33,7 @@ object LNodeSpec extends Spec { } "put elements with the same hash codes if absent" in { - val ct = new Ctrie[DumbHash, Int] + val ct = new ConcurrentTrieMap[DumbHash, Int] for (i <- 0 until initsz) ct.put(new DumbHash(i), i) for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i) for (i <- 0 until initsz) assert(ct.putIfAbsent(new DumbHash(i), i) == Some(i)) @@ -42,7 +42,7 @@ object LNodeSpec extends Spec { } "replace elements with the same hash codes" in { - val ct = new Ctrie[DumbHash, Int] + val ct = new ConcurrentTrieMap[DumbHash, Int] for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None) for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i) for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i) == Some(i)) @@ -51,7 +51,7 @@ object LNodeSpec extends Spec { } "remove elements with the same hash codes if mapped to a specific value" in { - val ct = new Ctrie[DumbHash, Int] + val ct = new ConcurrentTrieMap[DumbHash, Int] for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None) for (i <- 0 until initsz) assert(ct.remove(new DumbHash(i), i) == true) } diff --git a/test/files/run/ctries/snapshot.scala b/test/files/run/ctries/snapshot.scala index 69073d3f06..3c816130b3 100644 --- a/test/files/run/ctries/snapshot.scala +++ b/test/files/run/ctries/snapshot.scala @@ -3,7 +3,7 @@ import collection._ -import collection.mutable.Ctrie +import collection.mutable.ConcurrentTrieMap @@ -11,11 +11,11 @@ object SnapshotSpec extends Spec { def test() { "support snapshots" in { - val ctn = new Ctrie + val ctn = new ConcurrentTrieMap ctn.snapshot() ctn.readOnlySnapshot() - val ct = new Ctrie[Int, Int] + val ct = new ConcurrentTrieMap[Int, Int] for (i <- 0 until 100) ct.put(i, i) ct.snapshot() ct.readOnlySnapshot() @@ -24,7 +24,7 @@ object SnapshotSpec extends Spec { "empty 2 quiescent snapshots in isolation" in { val sz = 4000 - class Worker(trie: Ctrie[Wrap, Int]) extends Thread { + class Worker(trie: ConcurrentTrieMap[Wrap, Int]) extends Thread { override def run() { for (i <- 0 until sz) { assert(trie.remove(new Wrap(i)) == Some(i)) @@ -35,7 +35,7 @@ object SnapshotSpec extends Spec { } } - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct.put(new Wrap(i), i) val snapt = ct.snapshot() @@ -96,7 +96,7 @@ object SnapshotSpec extends Spec { } // traverses the trie `rep` times and modifies each entry - class Modifier(trie: Ctrie[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread { + class Modifier(trie: ConcurrentTrieMap[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread { setName("Modifier %d".format(index)) override def run() { @@ -110,7 +110,7 @@ object SnapshotSpec extends Spec { } // removes all the elements from the trie - class Remover(trie: Ctrie[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread { + class Remover(trie: ConcurrentTrieMap[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread { setName("Remover %d".format(index)) override def run() { @@ -123,7 +123,7 @@ object SnapshotSpec extends Spec { val N = 100 val W = 10 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct(new Wrap(i)) = i val readonly = ct.readOnlySnapshot() val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) @@ -141,7 +141,7 @@ object SnapshotSpec extends Spec { val W = 100 val S = 5000 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct(new Wrap(i)) = i val threads = for (i <- 0 until W) yield new Remover(ct, i, W, sz) @@ -156,7 +156,7 @@ object SnapshotSpec extends Spec { val W = 10 val S = 7000 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct(new Wrap(i)) = i val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) @@ -165,7 +165,7 @@ object SnapshotSpec extends Spec { threads.foreach(_.join()) } - def consistentNonReadOnly(name: String, trie: Ctrie[Wrap, Int], sz: Int, N: Int) { + def consistentNonReadOnly(name: String, trie: ConcurrentTrieMap[Wrap, Int], sz: Int, N: Int) { @volatile var e: Exception = null // reads possible entries once and stores them @@ -223,7 +223,7 @@ object SnapshotSpec extends Spec { val W = 10 val S = 400 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct(new Wrap(i)) = i val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) @@ -241,7 +241,7 @@ object SnapshotSpec extends Spec { val S = 10 val modifytimes = 1200 val snaptimes = 600 - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct(new Wrap(i)) = i class Snapshooter extends Thread { diff --git a/test/files/run/existentials-in-compiler.scala b/test/files/run/existentials-in-compiler.scala index e4f6920145..8c04e4782c 100644 --- a/test/files/run/existentials-in-compiler.scala +++ b/test/files/run/existentials-in-compiler.scala @@ -6,7 +6,7 @@ object Test extends CompilerTest { import global._ import definitions._ - def code = """ + override def code = """ package extest { trait Bippy[A <: AnyRef, B] { } // wildcards trait BippyLike[A <: AnyRef, B <: List[A], This <: BippyLike[A, B, This] with Bippy[A, B]] // no wildcards diff --git a/test/files/run/matchonseq.check b/test/files/run/matchonseq.check new file mode 100644 index 0000000000..3fe554095a --- /dev/null +++ b/test/files/run/matchonseq.check @@ -0,0 +1,2 @@ +It worked! head=1 +It worked! last=3 diff --git a/test/files/run/matchonseq.scala b/test/files/run/matchonseq.scala new file mode 100644 index 0000000000..49b406a6ec --- /dev/null +++ b/test/files/run/matchonseq.scala @@ -0,0 +1,8 @@ +object Test extends App{ + Vector(1,2,3) match { + case head +: tail => println("It worked! head=" + head) + } + Vector(1,2,3) match { + case init :+ last => println("It worked! last=" + last) + } +} diff --git a/test/files/run/t0663.check b/test/files/run/t0663.check index 22b68b7f57..dd9be2af70 100644..100755 --- a/test/files/run/t0663.check +++ b/test/files/run/t0663.check @@ -1 +1 @@ -<feed></feed> +<feed/> diff --git a/test/files/run/t1620.check b/test/files/run/t1620.check index 979efc8227..afa1e6acd5 100644..100755 --- a/test/files/run/t1620.check +++ b/test/files/run/t1620.check @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE foo PUBLIC "-//Foo Corp//DTD 1.0//EN" "foo.dtd"> -<foo></foo> +<foo/> <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE foo PUBLIC "-//Foo Corp//DTD 1.0//EN"> -<foo></foo> +<foo/> diff --git a/test/files/run/t2124.check b/test/files/run/t2124.check index 2b8840209f..51b40469aa 100644..100755 --- a/test/files/run/t2124.check +++ b/test/files/run/t2124.check @@ -1 +1 @@ -<p><lost></lost><q></q></p> +<p><lost/><q/></p> diff --git a/test/files/run/t2125.check b/test/files/run/t2125.check index 2b8840209f..51b40469aa 100644..100755 --- a/test/files/run/t2125.check +++ b/test/files/run/t2125.check @@ -1 +1 @@ -<p><lost></lost><q></q></p> +<p><lost/><q/></p> diff --git a/test/files/run/t4574.check b/test/files/run/t4574.check new file mode 100644 index 0000000000..a4522fff24 --- /dev/null +++ b/test/files/run/t4574.check @@ -0,0 +1,2 @@ +I hereby refute null! +I denounce null as unListLike! diff --git a/test/files/run/t4574.scala b/test/files/run/t4574.scala new file mode 100644 index 0000000000..1dde496aca --- /dev/null +++ b/test/files/run/t4574.scala @@ -0,0 +1,13 @@ +object Test { + val xs: List[(Int, Int)] = List((2, 2), null) + + def expectMatchError[T](msg: String)(body: => T) { + try { body ; assert(false, "Should not succeed.") } + catch { case _: MatchError => println(msg) } + } + + def main(args: Array[String]): Unit = { + expectMatchError("I hereby refute null!")( for ((x, y) <- xs) yield x ) + expectMatchError("I denounce null as unListLike!")( (null: Any) match { case List(_*) => true } ) + } +} diff --git a/test/files/run/xml-attribute.check b/test/files/run/xml-attribute.check index 3ae2034684..3cfe3779fc 100644 --- a/test/files/run/xml-attribute.check +++ b/test/files/run/xml-attribute.check @@ -1,12 +1,12 @@ -<t></t> -<t></t> -<t></t> -<t></t> -<t></t> -<t b="1" d="2"></t> -<t b="1" d="2"></t> -<t b="1" d="2"></t> -<t a="1" d="2"></t> -<t b="1" d="2"></t> -<t a="1" b="2" c="3"></t> -<t g="1" e="2" p:a="3" f:e="4" mgruhu:ji="5"></t>
\ No newline at end of file +<t/> +<t/> +<t/> +<t/> +<t/> +<t b="1" d="2"/> +<t b="1" d="2"/> +<t b="1" d="2"/> +<t a="1" d="2"/> +<t b="1" d="2"/> +<t a="1" b="2" c="3"/> +<t g="1" e="2" p:a="3" f:e="4" mgruhu:ji="5"/> diff --git a/test/files/scalacheck/Ctrie.scala b/test/files/scalacheck/Ctrie.scala index 2950937278..b9d71b88a3 100644 --- a/test/files/scalacheck/Ctrie.scala +++ b/test/files/scalacheck/Ctrie.scala @@ -5,7 +5,7 @@ import org.scalacheck._ import Prop._ import org.scalacheck.Gen._ import collection._ -import collection.mutable.Ctrie +import collection.mutable.ConcurrentTrieMap @@ -16,7 +16,7 @@ case class Wrap(i: Int) { /** A check mainly oriented towards checking snapshot correctness. */ -object Test extends Properties("Ctrie") { +object Test extends Properties("ConcurrentTrieMap") { /* generators */ @@ -102,7 +102,7 @@ object Test extends Properties("Ctrie") { (numThreads, numElems) => val p = 3 //numThreads val sz = 102 //numElems - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] // checker val checker = spawn { @@ -134,7 +134,7 @@ object Test extends Properties("Ctrie") { property("update") = forAll(sizes) { (n: Int) => - val ct = new Ctrie[Int, Int] + val ct = new ConcurrentTrieMap[Int, Int] for (i <- 0 until n) ct(i) = i (0 until n) forall { case i => ct(i) == i @@ -143,7 +143,7 @@ object Test extends Properties("Ctrie") { property("concurrent update") = forAll(threadCountsAndSizes) { case (p, sz) => - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] inParallel(p) { idx => @@ -158,7 +158,7 @@ object Test extends Properties("Ctrie") { property("concurrent remove") = forAll(threadCounts, sizes) { (p, sz) => - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] for (i <- 0 until sz) ct(Wrap(i)) = i inParallel(p) { @@ -174,7 +174,7 @@ object Test extends Properties("Ctrie") { property("concurrent putIfAbsent") = forAll(threadCounts, sizes) { (p, sz) => - val ct = new Ctrie[Wrap, Int] + val ct = new ConcurrentTrieMap[Wrap, Int] val results = inParallel(p) { idx => diff --git a/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala b/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala index d1924f0ada..a04c0ff8d4 100644 --- a/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala +++ b/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala @@ -15,25 +15,25 @@ import scala.collection.parallel.ops._ -abstract class ParallelCtrieCheck[K, V](tp: String) extends ParallelMapCheck[K, V]("mutable.ParCtrie[" + tp + "]") { +abstract class ParallelConcurrentTrieMapCheck[K, V](tp: String) extends ParallelMapCheck[K, V]("mutable.ParConcurrentTrieMap[" + tp + "]") { // ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2) // ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2) - type CollType = ParCtrie[K, V] + type CollType = ParConcurrentTrieMap[K, V] def isCheckingViews = false def hasStrictOrder = false def ofSize(vals: Seq[Gen[(K, V)]], sz: Int) = { - val ct = new mutable.Ctrie[K, V] + val ct = new mutable.ConcurrentTrieMap[K, V] val gen = vals(rnd.nextInt(vals.size)) for (i <- 0 until sz) ct += sample(gen) ct } def fromTraversable(t: Traversable[(K, V)]) = { - val pct = new ParCtrie[K, V] + val pct = new ParConcurrentTrieMap[K, V] var i = 0 for (kv <- t.toList) { pct += kv @@ -45,7 +45,7 @@ abstract class ParallelCtrieCheck[K, V](tp: String) extends ParallelMapCheck[K, } -object IntIntParallelCtrieCheck extends ParallelCtrieCheck[Int, Int]("Int, Int") +object IntIntParallelConcurrentTrieMapCheck extends ParallelConcurrentTrieMapCheck[Int, Int]("Int, Int") with PairOperators[Int, Int] with PairValues[Int, Int] { @@ -58,7 +58,7 @@ with PairValues[Int, Int] def koperators = intoperators override def printDataStructureDebugInfo(ds: AnyRef) = ds match { - case pm: ParCtrie[k, v] => + case pm: ParConcurrentTrieMap[k, v] => println("Mutable parallel ctrie") case _ => println("could not match data structure type: " + ds.getClass) diff --git a/test/files/scalacheck/parallel-collections/pc.scala b/test/files/scalacheck/parallel-collections/pc.scala index 8a0dba3c25..0a91977da0 100644 --- a/test/files/scalacheck/parallel-collections/pc.scala +++ b/test/files/scalacheck/parallel-collections/pc.scala @@ -26,7 +26,7 @@ class ParCollProperties extends Properties("Parallel collections") { include(mutable.IntIntParallelHashMapCheck) // parallel ctrie - include(mutable.IntIntParallelCtrieCheck) + include(mutable.IntIntParallelConcurrentTrieMapCheck) // parallel mutable hash sets (tables) include(mutable.IntParallelHashSetCheck) diff --git a/test/scaladoc/resources/explicit-inheritance-override.scala b/test/scaladoc/resources/explicit-inheritance-override.scala new file mode 100644 index 0000000000..62ce653aea --- /dev/null +++ b/test/scaladoc/resources/explicit-inheritance-override.scala @@ -0,0 +1,48 @@ +// This tests the implicit comment inheritance capabilities of scaladoc for class inheritance (no $super, no @inheritdoc) +class InheritDocBase { + /** + * The base comment. And another sentence... + * + * @param arg1 The T term comment + * @param arg2 The string comment + * @tparam T the type of the first argument + * @throws SomeException if the function is not called with correct parameters + * @return The return comment + * @see The Manual + * @note Be careful! + * @example function[Int](3, "something") + * @author a Scala developer + * @version 0.0.2 + * @since 0.0.1 + * @todo Call mom. + */ + def function[T](arg1: T, arg2: String): Double = 0.0d +} + +class InheritDocDerived extends InheritDocBase { + /** + * Starting line + * + * @inheritdoc + * @inheritdoc + * + * Ending line + * + * @param arg1 Start1 @inheritdoc End1 + * @param arg2 Start2 @inheritdoc End2 + * @param arg3 Start3 ShouldWarn @inheritdoc End3 + * @tparam T StartT @inheritdoc EndT + * @tparam ShouldWarn StartSW @inheritdoc EndSW + * @throws SomeException StartEx @inheritdoc EndEx + * @throws SomeOtherException StartSOE Should Warn @inheritdoc EndSOE + * @return StartRet @inheritdoc EndRet + * @see StartSee @inheritdoc EndSee + * @note StartNote @inheritdoc EndNote + * @example StartExample @inheritdoc EndExample + * @author StartAuthor @inheritdoc EndAuthor + * @version StartVer @inheritdoc EndVer + * @since StartSince @inheritdoc EndSince + * @todo StartTodo @inheritdoc And dad! EndTodo + */ + override def function[T](arg1: T, arg2: String): Double = 1.0d +}
\ No newline at end of file diff --git a/test/scaladoc/resources/explicit-inheritance-usecase.scala b/test/scaladoc/resources/explicit-inheritance-usecase.scala new file mode 100644 index 0000000000..e10cec437a --- /dev/null +++ b/test/scaladoc/resources/explicit-inheritance-usecase.scala @@ -0,0 +1,47 @@ +// This tests the implicit comment inheritance capabilities of scaladoc for usecases (no $super, no @inheritdoc) +/** Testing use case inheritance */ +class UseCaseInheritDoc { + /** + * The base comment. And another sentence... + * + * @param arg1 The T term comment + * @param arg2 The string comment + * @tparam T the type of the first argument + * @throws SomeException if the function is not called with correct parameters + * @return The return comment + * @see The Manual + * @note Be careful! + * @example function[Int](3, "something") + * @author a Scala developer + * @version 0.0.2 + * @since 0.0.1 + * @todo Call mom. + * + * @usecase def function[T](arg1: T, arg2: String): Double + * + * Starting line + * + * @inheritdoc + * @inheritdoc + * + * Ending line + * + * @param arg1 Start1 @inheritdoc End1 + * @param arg2 Start2 @inheritdoc End2 + * @param arg3 Start3 ShouldWarn @inheritdoc End3 + * @tparam T StartT @inheritdoc EndT + * @tparam ShouldWarn StartSW @inheritdoc EndSW + * @throws SomeException StartEx @inheritdoc EndEx + * @throws SomeOtherException StartSOE Should Warn @inheritdoc EndSOE + * @return StartRet @inheritdoc EndRet + * @see StartSee @inheritdoc EndSee + * @note StartNote @inheritdoc EndNote + * @example StartExample @inheritdoc EndExample + * @author StartAuthor @inheritdoc EndAuthor + * @version StartVer @inheritdoc EndVer + * @since StartSince @inheritdoc EndSince + * @todo StartTodo @inheritdoc And dad! EndTodo + */ + def function[T](implicit arg1: T, arg2: String): Double = 0.0d +} + diff --git a/test/scaladoc/resources/implicit-inheritance-override.scala b/test/scaladoc/resources/implicit-inheritance-override.scala index 85b8e8d543..5d692f59ad 100644 --- a/test/scaladoc/resources/implicit-inheritance-override.scala +++ b/test/scaladoc/resources/implicit-inheritance-override.scala @@ -2,12 +2,12 @@ class Base { /** * The base comment. And another sentence... - * - * @param arg1 The T term comment - * @param arg2 The string comment + * + * @param arg1 The T term comment + * @param arg2 The string comment * @tparam T the type of the first argument * @return The return comment - */ + */ def function[T](arg1: T, arg2: String): Double = 0.0d } diff --git a/test/scaladoc/resources/inheritdoc-corner-cases.scala b/test/scaladoc/resources/inheritdoc-corner-cases.scala new file mode 100644 index 0000000000..8cd995e605 --- /dev/null +++ b/test/scaladoc/resources/inheritdoc-corner-cases.scala @@ -0,0 +1,78 @@ +// TEST1: Inherit from multiple classes +trait A { + /** + * Hello 1 comment + */ + def hello1 = 0 +} + +trait B { + /** + * Hello 2 comment + */ + def hello2 = 1 +} + +trait C extends B + +class D extends A with C { + /** + * Inherited: @inheritdoc + */ + override def hello1 = super.hello2 + + /** + * Inherited: @inheritdoc + */ + override def hello2 = super.hello1 +} + +// TEST2: Invalid inherit: no parents +trait E { + /** + * @inheritdoc + */ + def whereDidThisComeFrom +} + +// TEST3: Invalid inherit, but other parents present +trait F extends E { + /** + * @inheritdoc + */ + def howAboutThis +} + + +// TEST4: Inherit from something that inherits: inherit should propagate +trait G extends D { + /** + * @inheritdoc + */ + override def hello1 = 13 + + /** + * @inheritdoc + */ + override def hello2 = 14 +} + +// TEST5: Inherit missing parameters +trait H extends G { + /** + * Missing params + * @throws HelloException @inheritdoc + * @todo @inheritdoc + */ + override def hello1 = 15 +} + +// TEST6: Inherit from something that inherits in the usecase +trait I extends G { + /** + * @inheritdoc + * @usecase def hello1(i: Int) + * @inheritdoc + */ + override def hello1 = 13 +}
\ No newline at end of file diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.scala b/test/scaladoc/scala/html/HtmlFactoryTest.scala index 818230238d..7550faa536 100644 --- a/test/scaladoc/scala/html/HtmlFactoryTest.scala +++ b/test/scaladoc/scala/html/HtmlFactoryTest.scala @@ -21,9 +21,9 @@ object XMLUtil { } object Test extends Properties("HtmlFactory") { - - final val RESOURCES = "test/scaladoc/resources/" - + + final val RESOURCES = "test/scaladoc/resources/" + import scala.tools.nsc.doc.{DocFactory, Settings} import scala.tools.nsc.doc.model.IndexModelFactory import scala.tools.nsc.doc.html.HtmlFactory @@ -87,7 +87,7 @@ object Test extends Properties("HtmlFactory") { /** * This tests the text without the markup - ex: - * + * * <h4 class="signature"> * <span class="modifier_kind"> * <span class="modifier">implicit</span> @@ -97,24 +97,24 @@ object Test extends Properties("HtmlFactory") { * <span class="name">test</span><span class="params">()</span><span class="result">: <span name="scala.Int" class="extype">Int</span></span> * </span> * </h4> - * + * * becomes: - * + * * implicit def test(): Int - * + * * and is required to contain the text in the given checks - * + * * NOTE: Comparison is done ignoring all whitespace */ def checkText(scalaFile: String, debug: Boolean = true)(checks: (Option[String], String, Boolean)*): Boolean = { - val htmlFile = scalaFile.stripSuffix(".scala") + ".html" + val htmlFile = scalaFile.stripSuffix(".scala") + ".html" val htmlAllFiles = createTemplates(scalaFile) var result = true - + for ((fileHint, check, expected) <- checks) { // resolve the file to be checked val fileName = fileHint match { - case Some(file) => + case Some(file) => if (file endsWith ".html") file else @@ -122,20 +122,27 @@ object Test extends Properties("HtmlFactory") { case None => htmlFile } - val fileText = htmlAllFiles(fileName).text.replace('→',' ').replaceAll("\\s+","") - val checkText = check.replace('→',' ').replaceAll("\\s+","") + val fileTextPretty = htmlAllFiles(fileName).text.replace('→',' ').replaceAll("\\s+"," ") + val fileText = fileTextPretty.replaceAll(" ", "") + + val checkTextPretty = check.replace('→',' ').replaceAll("\\s+"," ") + val checkText = checkTextPretty.replaceAll(" ", "") + val checkValue = fileText.contains(checkText) == expected if (debug && (!checkValue)) { - Console.err.println("Check failed: ") - Console.err.println("HTML: " + fileText) - Console.err.println("Check: " + checkText) + Console.err.println("") + Console.err.println("HTML Check failed for resource file " + scalaFile + ":") + Console.err.println("Could not match: \n" + checkTextPretty) + Console.err.println("In the extracted HTML text: \n" + fileTextPretty) + Console.err.println("NOTE: The whitespaces are eliminated before matching!") + Console.err.println("") } - result &&= checkValue + result &&= checkValue } - + result } - + def shortComments(root: scala.xml.Node) = XMLUtil.stripGroup(root).descendant.flatMap { @@ -284,7 +291,7 @@ object Test extends Properties("HtmlFactory") { case _ => false } } - + property("Trac #4420 - no whitespace at end of line") = { val files = createTemplates("Trac4420.scala") @@ -432,47 +439,46 @@ object Test extends Properties("HtmlFactory") { createTemplate("SI_4898.scala") true } - + property("Use cases should override their original members") = checkText("SI_5054_q1.scala")( (None,"""def test(): Int""", true), (None,"""def test(implicit lost: Int): Int""", false) ) - property("Use cases should keep their flags - final should not be lost") = + property("Use cases should keep their flags - final should not be lost") = checkText("SI_5054_q2.scala")((None, """final def test(): Int""", true)) - - property("Use cases should keep their flags - implicit should not be lost") = + + property("Use cases should keep their flags - implicit should not be lost") = checkText("SI_5054_q3.scala")((None, """implicit def test(): Int""", true)) - - property("Use cases should keep their flags - real abstract should not be lost") = + + property("Use cases should keep their flags - real abstract should not be lost") = checkText("SI_5054_q4.scala")((None, """abstract def test(): Int""", true)) - property("Use cases should keep their flags - traits should not be affected") = + property("Use cases should keep their flags - traits should not be affected") = checkText("SI_5054_q5.scala")((None, """def test(): Int""", true)) - property("Use cases should keep their flags - traits should not be affected") = + property("Use cases should keep their flags - traits should not be affected") = checkText("SI_5054_q6.scala")((None, """abstract def test(): Int""", true)) - - property("Use case individual signature test") = + + property("Use case individual signature test") = checkText("SI_5054_q7.scala")( (None, """abstract def test2(explicit: Int): Int [use case] This takes the explicit value passed.""", true), (None, """abstract def test1(): Int [use case] This takes the implicit value in scope.""", true) ) - property("Display correct \"Definition classes\"") = - checkText("SI_5287.scala")( + property("Display correct \"Definition classes\"") = + checkText("SI_5287.scala")( (None, """def method(): Int [use case] The usecase explanation [use case] The usecase explanation Definition Classes SI_5287 SI_5287_B SI_5287_A""", true) - ) // the explanation appears twice, as small comment and full comment - - - property("Correct comment inheritance for overriding") = + ) // the explanation appears twice, as small comment and full comment + + property("Correct comment inheritance for overriding") = checkText("implicit-inheritance-override.scala")( - (Some("Base"), + (Some("Base"), """def function[T](arg1: T, arg2: String): Double The base comment. The base comment. And another sentence... @@ -481,7 +487,7 @@ object Test extends Properties("HtmlFactory") { arg2 The string comment returns The return comment """, true), - (Some("DerivedA"), + (Some("DerivedA"), """def function[T](arg1: T, arg2: String): Double Overriding the comment, the params and returns comments should stay the same. Overriding the comment, the params and returns comments should stay the same. @@ -490,21 +496,21 @@ object Test extends Properties("HtmlFactory") { arg2 The string comment returns The return comment """, true), - (Some("DerivedB"), + (Some("DerivedB"), """def function[T](arg1: T, arg2: String): Double T the type of the first argument arg1 The overridden T term comment arg2 The overridden string comment returns The return comment """, true), - (Some("DerivedC"), + (Some("DerivedC"), """def function[T](arg1: T, arg2: String): Double T the type of the first argument arg1 The T term comment arg2 The string comment returns The overridden return comment """, true), - (Some("DerivedD"), + (Some("DerivedD"), """def function[T](arg1: T, arg2: String): Double T The overriden type parameter comment arg1 The T term comment @@ -512,11 +518,11 @@ object Test extends Properties("HtmlFactory") { returns The return comment """, true) ) - + for (useCaseFile <- List("UseCaseInheritance", "UseCaseOverrideInheritance")) { - property("Correct comment inheritance for usecases") = + property("Correct comment inheritance for usecases") = checkText("implicit-inheritance-usecase.scala")( - (Some(useCaseFile), + (Some(useCaseFile), """def missing_arg[T](arg1: T): Double [use case] [use case] @@ -524,7 +530,7 @@ object Test extends Properties("HtmlFactory") { arg1 The T term comment returns The return comment """, true), - (Some(useCaseFile), + (Some(useCaseFile), """def missing_targ(arg1: Int, arg2: String): Double [use case] [use case] @@ -532,7 +538,7 @@ object Test extends Properties("HtmlFactory") { arg2 The string comment returns The return comment """, true), - (Some(useCaseFile), + (Some(useCaseFile), """def overridden_arg1[T](implicit arg1: T, arg2: String): Double [use case] [use case] @@ -541,7 +547,7 @@ object Test extends Properties("HtmlFactory") { arg2 The string comment returns The return comment """, true), - (Some(useCaseFile), + (Some(useCaseFile), """def overridden_targ[T](implicit arg1: T, arg2: String): Double [use case] [use case] @@ -550,7 +556,7 @@ object Test extends Properties("HtmlFactory") { arg2 The string comment returns The return comment """, true), - (Some(useCaseFile), + (Some(useCaseFile), """def overridden_return[T](implicit arg1: T, arg2: String): Double [use case] [use case] @@ -559,7 +565,7 @@ object Test extends Properties("HtmlFactory") { arg2 The string comment returns The overridden return comment """, true), - (Some(useCaseFile), + (Some(useCaseFile), """def added_arg[T](implicit arg1: T, arg2: String, arg3: Float): Double [use case] [use case] @@ -569,7 +575,7 @@ object Test extends Properties("HtmlFactory") { arg3 The added float comment returns The return comment """, true), - (Some(useCaseFile), + (Some(useCaseFile), """def overridden_comment[T](implicit arg1: T, arg2: String): Double [use case] The overridden comment. [use case] The overridden comment. @@ -578,8 +584,92 @@ object Test extends Properties("HtmlFactory") { arg2 The string comment returns The return comment """, true) - ) - } + ) + } + + property("Correct explicit inheritance for override") = + checkText("explicit-inheritance-override.scala")( + (Some("InheritDocDerived"), + """def function[T](arg1: T, arg2: String): Double + Starting line + Starting line + The base comment. And another sentence... + The base comment. And another sentence... + Ending line + T StartT the type of the first argument EndT + arg1 Start1 The T term comment End1 + arg2 Start2 The string comment End2 + returns StartRet The return comment EndRet + Definition Classes InheritDocDerived → InheritDocBase + Example: StartExample function[Int](3, "something") EndExample + Version StartVer 0.0.2 EndVer + Since StartSince 0.0.1 EndSince + Exceptions thrown + SomeException StartEx if the function is not called with correct parameters EndEx + SomeOtherException StartSOE Should Warn <invalid inheritdoc annotation> EndSOE + To do StartTodo Call mom. And dad! EndTodo + Note StartNote Be careful! EndNote + See also StartSee The Manual EndSee + """, true)) + + property("Correct explicit inheritance for usecase") = + checkText("explicit-inheritance-usecase.scala")( + (Some("UseCaseInheritDoc"), + """def function[T](arg1: T, arg2: String): Double + [use case] Starting line + [use case] Starting line + The base comment. And another sentence... + The base comment. And another sentence... + Ending line + T StartT the type of the first argument EndT + arg1 Start1 The T term comment End1 + arg2 Start2 The string comment End2 + returns StartRet The return comment EndRet + Example: StartExample function[Int](3,"something") EndExample + Version StartVer 0.0.2 EndVer + Since StartSince 0.0.1 EndSince + Exceptions thrown + SomeException StartEx if the function is not called with correct parameters EndEx + SomeOtherException StartSOE Should Warn <invalid inheritdoc annotation> EndSOE + To do StartTodo Call mom. And dad! EndTodo + Note StartNote Be careful! EndNote + See also StartSee The Manual EndSee + """, true)) + + property("Correct explicit inheritance in corner cases") = + checkText("inheritdoc-corner-cases.scala")( + (Some("D"), + """def hello1: Int + Inherited: Hello 1 comment + Inherited: Hello 1 comment + Definition Classes D → A + """, true), + (Some("D"), + """def hello2: Int + Inherited: Hello 2 comment + Inherited: Hello 2 comment + Definition Classes D → B + """, true), + (Some("G"), + """def hello1: Int + Inherited: Hello 1 comment + Inherited: Hello 1 comment + Definition Classes G → D → A + """, true), + (Some("G"), + """def hello2: Int + Inherited: Hello 2 comment + Inherited: Hello 2 comment + Definition Classes G → D → B + """, true), + (Some("I"), + """def hello1(i: Int): Unit + [use case] Inherited: Hello 1 comment + [use case] Inherited: Hello 1 comment + Definition Classes I → G → D → A + """, true) + // traits E, F and H shouldn't crash scaladoc but we don't need to check the output + ) property("Indentation normalization for code blocks") = { val files = createTemplates("code-indent.scala") diff --git a/tools/get-scala-commit-date b/tools/get-scala-commit-date new file mode 100755 index 0000000000..b2e4e10770 --- /dev/null +++ b/tools/get-scala-commit-date @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +# Usage: get-scala-commit-date [dir] +# Figures out current commit date of a git clone. +# If no dir is given, current working dir is used. +# +# Example build version string: +# 20120312 +# + +[[ $# -eq 0 ]] || cd "$1" + +lastcommitdate=$(git log --format="%ci" HEAD | head -n 1 | cut -d ' ' -f 1) +lastcommithours=$(git log --format="%ci" HEAD | head -n 1 | cut -d ' ' -f 2) + +# 20120324 +echo "${lastcommitdate//-/}-${lastcommithours//:/}" diff --git a/tools/get-scala-commit-date.bat b/tools/get-scala-commit-date.bat new file mode 100644 index 0000000000..a07155533f --- /dev/null +++ b/tools/get-scala-commit-date.bat @@ -0,0 +1,24 @@ +@echo off +rem +rem Usage: get-scala-revison.bat [dir] +rem Figures out current scala commit date of a git clone. +rem +rem If no dir is given, current working dir is used. + +@setlocal +set _DIR= +if "%*"=="" ( + for /f "delims=;" %%i in ('cd') do set "_DIR=%%i" +) else ( + set "_DIR=%~1" +) +cd %_DIR% + +rem TODO - Check with a real windows user that this works! +if exist .git\NUL ( + for /f "tokens=1delims= " in ('git log --format="%ci" -1') do set commitdate=%%a + echo %commitdate% +) + +:end +@endlocal diff --git a/tools/get-scala-commit-sha b/tools/get-scala-commit-sha new file mode 100755 index 0000000000..eab90a4215 --- /dev/null +++ b/tools/get-scala-commit-sha @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Usage: get-scala-commit-sha [dir] +# Figures out current commit sha of a git clone. +# If no dir is given, current working dir is used. +# +# Example build version string: +# 6f1c486d0ba +# + +[[ $# -eq 0 ]] || cd "$1" + +# printf %016s is not portable for 0-padding, has to be a digit. +# so we're stuck disassembling it. +hash=$(git log -1 --format="%H" HEAD) +hash=${hash#g} +hash=${hash:0:10} +echo "$hash" diff --git a/tools/get-scala-revision.bat b/tools/get-scala-commit-sha.bat index 48c7cbd94f..7a5afa11b1 100644 --- a/tools/get-scala-revision.bat +++ b/tools/get-scala-commit-sha.bat @@ -1,7 +1,7 @@ @echo off rem -rem Usage: get-scala-revison.bat [dir] -rem Figures out current scala revision of a git clone. +rem Usage: get-scala-commit-drift.bat [dir] +rem Figures out current scala commit drift, of a clone. rem rem If no dir is given, current working dir is used. @@ -14,9 +14,8 @@ if "%*"=="" ( ) cd %_DIR% -if exist .git\NUL ( - git describe --abbrev=10 --always --tags -) +rem TODO - truncate chars. +git log -1 --format="%H :end @endlocal diff --git a/tools/get-scala-revision b/tools/get-scala-revision deleted file mode 100755 index 4d97ec58ad..0000000000 --- a/tools/get-scala-revision +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -# -# Usage: get-scala-revision [dir] -# Figures out current scala revision of a git clone. -# If no dir is given, current working dir is used. -# -# Example build version string: -# v2.10.0-M1-0098-g6f1c486d0b-2012-02-01 -# - -[[ $# -eq 0 ]] || cd "$1" - -ensure_tag () { - sha=$1 - rev=$2 - - [[ -n $(git tag -l $rev) ]] || { - git tag -a -m "generated by get-scala-revision" $rev $sha - } -} - -# Ensure some baseline tags are present so if this repository's -# tags are screwed up or stale, we should still have a reference -# point for a build string. -ensure_tag 58cb15c40d v2.10.0-M1 -ensure_tag 29f3eace1e v2.9.1 -ensure_tag b0d78f6b9c v2.8.2 - -# the closest tag, obtained separately because we have to -# reconstruct the string around the padded distance. -tag=$(git describe --tags --match 'v2*' --abbrev=0) - -# printf %016s is not portable for 0-padding, has to be a digit. -# so we're stuck disassembling it. -described=$(git describe --tags --match 'v2*' --abbrev=10) -suffix="${described##${tag}-}" -counter=$(echo $suffix | cut -d - -f 1) -hash=$(echo $suffix | cut -d - -f 2) - -# remove any alphabetic characters before the version number -tag=$(echo $tag | sed "s/\([a-z_A-Z]*\)\(.*\)/\2/") - -# 2.10.0-M1-0098-g6f1c486d0b-2012-02-01 -printf "%s-%04d-%s-%s\n" "$tag" "$counter" "$hash" $(date "+%Y-%m-%d") diff --git a/tools/make-release-notes b/tools/make-release-notes new file mode 100755 index 0000000000..dcd206f7fc --- /dev/null +++ b/tools/make-release-notes @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# This tool is used to build a *scaffold* of a release note that you can fill in details with before posting to the list. +# It aims to provide *all* the information you need, and probably need to prune it before releasing. +# Author: jsuereth + +fixMessages() { + local tag1="$1" + local tag2="$2" + git log $tag1..$tag2 "--format=format: * %h - %s" --no-merges --grep "SI-" +} + +allcommitMessages() { + local tag1="$1" + local tag2="$2" + git log $tag1..$tag2 "--format=format: * %h - %s" --no-merges +} + +authors() { + local tag1="$1" + local tag2="$2" + git log $tag1..$tag2 --format=format:%an --no-merges | sort | uniq -c | sort -rh +} + + +message() { + local tag1="$1" + local tag2="$2" + + echo "A new release of Scala is available! Please point your build tools at ${tag2#v}" + echo + echo "Here's a list of the issues that have been fixed since ${tag1#v}: " + fixMessages "$tag1" "$tag2" + echo + echo + echo "Special thanks to all the contributions!" + echo "------- --------------------------------" + authors "$tag1" "$tag2" + echo "------- --------------------------------" + echo + echo + echo "Here's a complete list of changes:" + allcommitMessages "$tag1" "$tag2" +} + + +message "$1" "$2" + + diff --git a/tools/verify-jar-cache b/tools/verify-jar-cache index 1e86264ecb..8a376a6987 100755 --- a/tools/verify-jar-cache +++ b/tools/verify-jar-cache @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # Discovers files whose sha sum does not match the # sha embedded in their directory name from ~/.sbt/cache/scala. @@ -9,14 +9,14 @@ cd ~/.sbt/cache/scala unset failed unset removal -[[ $1 == "-f" ]] && removal=true +[[ "$1" == "-f" ]] && removal=true for file in $(find . -type f); do sha=$(echo "${file:2}" | sed 's/\/.*$//') sum=$(shasum "$file" | sed 's/ .*$//') if [[ $sum != $sha ]]; then failed=true - if [[ -n $removal ]]; then + if [[ -n "$removal" ]]; then echo "Removing corrupt file $file, shasum=$sum" rm -rf $sha else @@ -25,9 +25,9 @@ for file in $(find . -type f); do fi done -if [[ -z $failed ]]; then +if [[ -z "$failed" ]]; then echo "All cached files match their shas." -elif [[ -z $removal ]]; then +elif [[ -z "$removal" ]]; then echo "" echo "Run again with -f to remove the corrupt files." fi |