diff options
author | Paul Phillips <paulp@improving.org> | 2010-02-04 18:50:47 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-02-04 18:50:47 +0000 |
commit | 7c19904e484f2021b186a81d335fa564a0638baf (patch) | |
tree | 07e68d7084af6292f85e42b09fa3823d10b99230 /src | |
parent | 67b215e9746dcd1f1ceeb54017eb1deeffbed940 (diff) | |
download | scala-7c19904e484f2021b186a81d335fa564a0638baf.tar.gz scala-7c19904e484f2021b186a81d335fa564a0638baf.tar.bz2 scala-7c19904e484f2021b186a81d335fa564a0638baf.zip |
Raised the level of abstraction (slightly, not ...
Raised the level of abstraction (slightly, not enough) on ClassPath by
defining the difference between optimized and regular classpaths in
terms of an arbitrary name filter instead of in terms of settings.XO.
Altered the decision logic to look at the value of -Yinline instead of
-optimise. Closes #2950. Review by rytz.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 16 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/MSILGlobal.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/util/ClassPath.scala | 111 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/util/MsilClassPath.scala | 16 | ||||
-rw-r--r-- | src/scalap/scala/tools/scalap/Main.scala | 6 |
5 files changed, 72 insertions, 79 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 76771173df..f82bae8afa 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -209,11 +209,17 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable } } - lazy val classPath: ClassPath[_] = new JavaClassPath( - settings.bootclasspath.value, settings.extdirs.value, - settings.classpath.value, settings.sourcepath.value, - settings.Xcodebase.value, settings.XO.value - ) + // Unless inlining is on, we can exclude $class.class files from the classpath. + protected def validClassPathName: String => Boolean = + if (settings.inline.value) _ => true + else ClassPath.noTraitImplFilter + + lazy val classPath: ClassPath[_] = + new JavaClassPath( + settings.bootclasspath.value, settings.extdirs.value, + settings.classpath.value, settings.sourcepath.value, + settings.Xcodebase.value, validClassPathName + ) if (settings.verbose.value) inform("[Classpath = " + classPath + "]") diff --git a/src/compiler/scala/tools/nsc/MSILGlobal.scala b/src/compiler/scala/tools/nsc/MSILGlobal.scala index 7225200b48..660c3398f0 100644 --- a/src/compiler/scala/tools/nsc/MSILGlobal.scala +++ b/src/compiler/scala/tools/nsc/MSILGlobal.scala @@ -26,7 +26,7 @@ class MSILGlobal(settings: Settings, reporter: Reporter) extends Global(settings override lazy val classPath: MsilClassPath = new MsilClassPath( settings.assemextdirs.value, settings.assemrefs.value, - settings.sourcepath.value, settings.XO.value + settings.sourcepath.value, validClassPathName ) override def rootLoader: LazyType = new loaders.NamespaceLoader(classPath) diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index db559891df..9bfe343aee 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -58,6 +58,14 @@ object ClassPath { def expandPath(path: String, expandStar: Boolean = true): List[String] = if (expandStar) splitPath(path).flatMap(expandS(_)) else splitPath(path) + + /** A useful name filter. */ + val noTraitImplFilter: String => Boolean = name => !(name endsWith "$class.class") + + import java.net.MalformedURLException + def specToURL(spec: String): Option[URL] = + try Some(new URL(spec)) + catch { case _: MalformedURLException => None } } /** @@ -99,22 +107,20 @@ abstract class ClassPath[T] { } } - /** Whether this classpath is being used for an optimized build. - * Why this is necessary is something which should really be documented, - * since it seems to have little to do with a ClassPath. + /** A filter which can be used to exclude entities from the classpath + * based on their name. */ - def isOptimized: Boolean + def validName: String => Boolean /** Filters for assessing validity of various entities. */ - def validClassFile(name: String) = - (name endsWith ".class") && (isOptimized || !(name endsWith "$class.class")) + def validClassFile(name: String) = (name endsWith ".class") && validName(name) + def validPackage(name: String) = (name != "META-INF") && (name != "") && (name.head != '.') + def validSourceFile(name: String) = validSourceExtensions exists (name endsWith _) + def validSourceExtensions = List(".scala", ".java") - def validPackage(name: String) = - !(name.equals("META-INF") || name.startsWith(".")) - - def validSourceFile(name: String) = - (name.endsWith(".scala") || name.endsWith(".java")) + /** Utility */ + protected final def dropExtension(name: String) = name take (name.lastIndexOf('.') - 1) /** * Find a ClassRep given a class name of the form "package.subpackage.ClassName". @@ -144,26 +150,16 @@ abstract class ClassPath[T] { /** * A Classpath containing source files */ -class SourcePath[T](dir: AbstractFile, val isOptimized: Boolean) extends ClassPath[T] { +class SourcePath[T](dir: AbstractFile, val validName: String => Boolean) extends ClassPath[T] { def name = dir.name - lazy val classes = { - val cls = new ListBuffer[ClassRep] - for (f <- dir.iterator) { - if (!f.isDirectory && validSourceFile(f.name)) - cls += ClassRep(None, Some(f)) - } - cls.toList - } + lazy val classes: List[ClassRep] = dir partialMap { + case f if !f.isDirectory && validSourceFile(f.name) => ClassRep(None, Some(f)) + } toList - lazy val packages = { - val pkg = new ListBuffer[SourcePath[T]] - for (f <- dir.iterator) { - if (f.isDirectory && validPackage(f.name)) - pkg += new SourcePath[T](f, isOptimized) - } - pkg.toList - } + lazy val packages: List[SourcePath[T]] = dir partialMap { + case f if f.isDirectory && validPackage(f.name) => new SourcePath[T](f, validName) + } toList val sourcepaths: List[AbstractFile] = List(dir) @@ -173,26 +169,16 @@ class SourcePath[T](dir: AbstractFile, val isOptimized: Boolean) extends ClassPa /** * A directory (or a .jar file) containing classfiles and packages */ -class DirectoryClassPath(dir: AbstractFile, val isOptimized: Boolean) extends ClassPath[AbstractFile] { +class DirectoryClassPath(dir: AbstractFile, val validName: String => Boolean) extends ClassPath[AbstractFile] { def name = dir.name - lazy val classes = { - val cls = new ListBuffer[ClassRep] - for (f <- dir.iterator) { - if (!f.isDirectory && validClassFile(f.name)) - cls += ClassRep(Some(f), None) - } - cls.toList - } + lazy val classes: List[ClassRep] = dir partialMap { + case f if !f.isDirectory && validClassFile(f.name) => ClassRep(Some(f), None) + } toList - lazy val packages = { - val pkg = new ListBuffer[DirectoryClassPath] - for (f <- dir.iterator) { - if (f.isDirectory && validPackage(f.name)) - pkg += new DirectoryClassPath(f, isOptimized) - } - pkg.toList - } + lazy val packages: List[DirectoryClassPath] = dir partialMap { + case f if f.isDirectory && validPackage(f.name) => new DirectoryClassPath(f, validName) + } toList val sourcepaths: List[AbstractFile] = Nil @@ -253,7 +239,7 @@ abstract class MergedClassPath[T] extends ClassPath[T] { private def newMergedClassPath(entrs: List[ClassPath[T]]): MergedClassPath[T] = new MergedClassPath[T] { protected val entries = entrs - override def isOptimized = outer.isOptimized + override def validName = outer.validName } override def toString() = "merged classpath "+ entries.mkString("(", "\n", ")") @@ -263,8 +249,14 @@ abstract class MergedClassPath[T] extends ClassPath[T] { * The classpath when compiling with target:jvm. Binary files (classfiles) are represented * as AbstractFile. nsc.io.ZipArchive is used to view zip/jar archives as directories. */ -class JavaClassPath(boot: String, ext: String, user: String, source: String, Xcodebase: String, val isOptimized: Boolean) -extends MergedClassPath[AbstractFile] { +class JavaClassPath( + boot: String, + ext: String, + user: String, + source: String, + Xcodebase: String, + val validName: String => Boolean = ClassPath.noTraitImplFilter +) extends MergedClassPath[AbstractFile] { protected val entries: List[ClassPath[AbstractFile]] = assembleEntries() @@ -273,7 +265,7 @@ extends MergedClassPath[AbstractFile] { val etr = new ListBuffer[ClassPath[AbstractFile]] def addFilesInPath(path: String, expand: Boolean, - ctr: AbstractFile => ClassPath[AbstractFile] = x => new DirectoryClassPath(x, isOptimized)) { + ctr: AbstractFile => ClassPath[AbstractFile] = x => new DirectoryClassPath(x, validName)) { for (fileName <- expandPath(path, expandStar = expand)) { val file = AbstractFile.getDirectory(fileName) if (file ne null) etr += ctr(file) @@ -291,7 +283,7 @@ extends MergedClassPath[AbstractFile] { val name = file.name.toLowerCase if (name.endsWith(".jar") || name.endsWith(".zip") || file.isDirectory) { val archive = AbstractFile.getDirectory(new File(dir.file, name)) - if (archive ne null) etr += new DirectoryClassPath(archive, isOptimized) + if (archive ne null) etr += new DirectoryClassPath(archive, validName) } } } @@ -302,23 +294,18 @@ extends MergedClassPath[AbstractFile] { // 4. Codebase entries (URLs) { - val urlSeparator = " " - val urlStrtok = new StringTokenizer(Xcodebase, urlSeparator) - while (urlStrtok.hasMoreTokens()) try { - val url = new URL(urlStrtok.nextToken()) - val archive = AbstractFile.getURL(url) - if (archive ne null) etr += new DirectoryClassPath(archive, isOptimized) - } - catch { - case e => - Console.println("error adding classpath form URL: " + e.getMessage)//debug - throw e + for { + spec <- Xcodebase.trim split " " + url <- specToURL(spec) + archive <- Option(AbstractFile getURL url) + } { + etr += new DirectoryClassPath(archive, validName) } } // 5. Source path if (source != "") - addFilesInPath(source, false, x => new SourcePath[AbstractFile](x, isOptimized)) + addFilesInPath(source, false, x => new SourcePath[AbstractFile](x, validName)) etr.toList } diff --git a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala index 3f69e67233..b55e44c822 100644 --- a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala @@ -38,15 +38,15 @@ object MsilClassPath { /** * A assembly file (dll / exe) containing classes and namespaces */ -class AssemblyClassPath(types: Array[MSILType], namespace: String, val isOptimized: Boolean) extends ClassPath[MSILType] { +class AssemblyClassPath(types: Array[MSILType], namespace: String, val validName: String => Boolean) extends ClassPath[MSILType] { def name = { val i = namespace.lastIndexOf('.') if (i < 0) namespace else namespace drop (i + 1) } - def this(assemFile: AbstractFile, isOptimized: Boolean) { - this(MsilClassPath.collectTypes(assemFile), "", isOptimized) + def this(assemFile: AbstractFile, validName: String => Boolean) { + this(MsilClassPath.collectTypes(assemFile), "", validName) } private lazy val first: Int = { @@ -88,7 +88,7 @@ class AssemblyClassPath(types: Array[MSILType], namespace: String, val isOptimiz i += 1 } for (ns <- nsSet.toList) - yield new AssemblyClassPath(types, ns, isOptimized) + yield new AssemblyClassPath(types, ns, validName) } val sourcepaths: List[AbstractFile] = Nil @@ -100,7 +100,7 @@ class AssemblyClassPath(types: Array[MSILType], namespace: String, val isOptimiz * The classpath when compiling with target:msil. Binary files are represented as * MSILType values. */ -class MsilClassPath(ext: String, user: String, source: String, val isOptimized: Boolean) extends MergedClassPath[MSILType] { +class MsilClassPath(ext: String, user: String, source: String, val validName: String => Boolean) extends MergedClassPath[MSILType] { protected val entries: List[ClassPath[MSILType]] = assembleEntries() override protected def nameOfBinaryRepresentation(binary: MSILType) = binary.Name @@ -117,7 +117,7 @@ class MsilClassPath(ext: String, user: String, source: String, val isOptimized: val name = file.name.toLowerCase if (name.endsWith(".dll") || name.endsWith(".exe")) { names += name - etr += new AssemblyClassPath(file, isOptimized) + etr += new AssemblyClassPath(file, validName) } } } @@ -130,7 +130,7 @@ class MsilClassPath(ext: String, user: String, source: String, val isOptimized: val name = file.name.toLowerCase if (name.endsWith(".dll") || name.endsWith(".exe")) { names += name - etr += new AssemblyClassPath(file, isOptimized) + etr += new AssemblyClassPath(file, validName) } } } @@ -146,7 +146,7 @@ class MsilClassPath(ext: String, user: String, source: String, val isOptimized: // 3. Source path for (dirName <- expandPath(source, expandStar = false)) { val file = AbstractFile.getDirectory(dirName) - if (file ne null) etr += new SourcePath[MSILType](file, isOptimized) + if (file ne null) etr += new SourcePath[MSILType](file, validName) } etr.toList diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala index 3a4779c6b7..338143f671 100644 --- a/src/scalap/scala/tools/scalap/Main.scala +++ b/src/scalap/scala/tools/scalap/Main.scala @@ -265,9 +265,9 @@ object Main { val path = arguments.getArgument("-classpath") match { case None => arguments.getArgument("-cp") match { case None => EmptyClasspath - case Some(path) => new JavaClassPath("", "", path, "", "", false) + case Some(path) => new JavaClassPath("", "", path, "", "") } - case Some(path) => new JavaClassPath("", "", path, "", "", false) + case Some(path) => new JavaClassPath("", "", path, "", "") } // print the classpath if output is verbose if (verbose) { @@ -286,6 +286,6 @@ object Main { val classes: List[ClassRep] = Nil val packages: List[ClassPath[AbstractFile]] = Nil val sourcepaths: List[AbstractFile] = Nil - def isOptimized = false + val validName: String => Boolean = ClassPath.noTraitImplFilter } } |