summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/classpath
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-08-09 15:42:44 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-08-19 09:26:40 +1000
commitc141254b97a48e47ed7a6bfa08922671cc639081 (patch)
tree5133679c28c00c65f64e8423fb5fe256f885dc86 /src/compiler/scala/tools/nsc/classpath
parentb8e4d1f692c5712990b45f50625627015112df32 (diff)
downloadscala-c141254b97a48e47ed7a6bfa08922671cc639081.tar.gz
scala-c141254b97a48e47ed7a6bfa08922671cc639081.tar.bz2
scala-c141254b97a48e47ed7a6bfa08922671cc639081.zip
Determistically enter classes from directory into package scope
On Linux, the directory listing is not automatically sorted on Mac. This leads to non-determistic ids of Symbols of the classes in a directory, which in turn leads to instability of the ordering of parents within inferred refinement types. Notable, with this patch, we will stably infer: ``` scala> case class C(); case class D(); List(C(), D()).head defined class C defined class D res0: Product with Serializable = C() ``` rather than sometimes getting `Serializable with Product` on Linux. As such, I've removed the workarounds for this instability in two test cases.
Diffstat (limited to 'src/compiler/scala/tools/nsc/classpath')
-rw-r--r--src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
index aba941e043..0d6925e8ac 100644
--- a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
@@ -5,6 +5,9 @@ package scala.tools.nsc.classpath
import java.io.File
import java.net.URL
+import java.util
+import java.util.Comparator
+
import scala.reflect.io.{AbstractFile, PlainFile}
import scala.tools.nsc.util.{ClassPath, ClassRepresentation}
import FileUtils._
@@ -87,9 +90,24 @@ trait JFileDirectoryLookup[FileEntryType <: ClassRepresentation] extends Directo
if (packageDir.exists && packageDir.isDirectory) Some(packageDir)
else None
}
- protected def listChildren(dir: File, filter: Option[File => Boolean]): Array[File] = filter match {
- case Some(f) => dir.listFiles(mkFileFilter(f))
- case None => dir.listFiles()
+ protected def listChildren(dir: File, filter: Option[File => Boolean]): Array[File] = {
+ val listing = filter match {
+ case Some(f) => dir.listFiles(mkFileFilter(f))
+ case None => dir.listFiles()
+ }
+
+ // Sort by file name for stable order of directory .class entries in package scope.
+ // This gives stable results ordering of base type sequences for unrelated classes
+ // with the same base type depth.
+ //
+ // Notably, this will stably infer`Product with Serializable`
+ // as the type of `ase class C(); case class D(); List(C(), D()).head`, rather than the opposite order.
+ // On Mac, the HFS performs this sorting transparently, but on Linux the order is unspecified.
+ //
+ // Note this behaviour can be enabled with in javac with `javac -XDsortfiles`, but that's only
+ // intended to improve determinism of the compiler for compiler hackers.
+ util.Arrays.sort(listing, (o1: File, o2: File) => o1.getName.compareTo(o2.getName))
+ listing
}
protected def getName(f: File): String = f.getName
protected def toAbstractFile(f: File): AbstractFile = new PlainFile(new scala.reflect.io.File(f))