aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/config/JavaPlatform.scala75
-rw-r--r--src/dotty/tools/dotc/config/PathResolver.scala271
-rw-r--r--src/dotty/tools/dotc/config/Platform.scala38
-rw-r--r--src/dotty/tools/dotc/config/Properties.scala165
-rw-r--r--src/dotty/tools/dotc/config/Settings.scala26
-rw-r--r--src/dotty/tools/dotc/config/WrappedProperties.scala34
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala14
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala2
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala63
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala107
-rw-r--r--src/dotty/tools/io/ClassPath.scala72
12 files changed, 733 insertions, 136 deletions
diff --git a/src/dotty/tools/dotc/config/JavaPlatform.scala b/src/dotty/tools/dotc/config/JavaPlatform.scala
new file mode 100644
index 000000000..3c6ea3a8a
--- /dev/null
+++ b/src/dotty/tools/dotc/config/JavaPlatform.scala
@@ -0,0 +1,75 @@
+package dotty.tools
+package dotc
+package config
+
+import io.{AbstractFile,ClassPath,JavaClassPath,MergedClassPath,DeltaClassPath}
+import ClassPath.{ JavaContext, DefaultJavaContext }
+
+trait JavaPlatform /*extends Platform {
+ import global._
+ import definitions._
+
+ type BinaryRepr = AbstractFile
+
+ private var currentClassPath: Option[MergedClassPath[BinaryRepr]] = None
+
+ def classPath: ClassPath[BinaryRepr] = {
+ if (currentClassPath.isEmpty) currentClassPath = Some(new PathResolver(settings).result)
+ currentClassPath.get
+ }
+
+ /** Update classpath with a substituted subentry */
+ def updateClassPath(subst: Map[ClassPath[BinaryRepr], ClassPath[BinaryRepr]]) =
+ currentClassPath = Some(new DeltaClassPath(currentClassPath.get, subst))
+
+ def rootLoader = new loaders.PackageLoader(classPath.asInstanceOf[ClassPath[platform.BinaryRepr]])
+ // [Martin] Why do we need a cast here?
+ // The problem is that we cannot specify at this point that global.platform should be of type JavaPlatform.
+ // So we cannot infer that global.platform.BinaryRepr is AbstractFile.
+ // Ideally, we should be able to write at the top of the JavaPlatform trait:
+ // val global: Global { val platform: JavaPlatform }
+ // import global._
+ // Right now, this does nothing because the concrete definition of platform in Global
+ // replaces the tighter abstract definition here. If we had DOT typing rules, the two
+ // types would be conjoined and everything would work out. Yet another reason to push for DOT.
+
+ private def depAnalysisPhase =
+ if (settings.make.isDefault) Nil
+ else List(dependencyAnalysis)
+
+ private def classEmitPhase =
+ if (settings.target.value == "jvm-1.5-fjbg") genJVM
+ else genASM
+
+ def platformPhases = List(
+ flatten, // get rid of inner classes
+ classEmitPhase // generate .class files
+ ) ++ depAnalysisPhase
+
+ lazy val externalEquals = getDecl(BoxesRunTimeClass, nme.equals_)
+ lazy val externalEqualsNumNum = getDecl(BoxesRunTimeClass, nme.equalsNumNum)
+ lazy val externalEqualsNumChar = getDecl(BoxesRunTimeClass, nme.equalsNumChar)
+ lazy val externalEqualsNumObject = getDecl(BoxesRunTimeClass, nme.equalsNumObject)
+
+ /** We could get away with excluding BoxedBooleanClass for the
+ * purpose of equality testing since it need not compare equal
+ * to anything but other booleans, but it should be present in
+ * case this is put to other uses.
+ */
+ def isMaybeBoxed(sym: Symbol) = {
+ (sym == ObjectClass) ||
+ (sym == JavaSerializableClass) ||
+ (sym == ComparableClass) ||
+ (sym isNonBottomSubClass BoxedNumberClass) ||
+ (sym isNonBottomSubClass BoxedCharacterClass) ||
+ (sym isNonBottomSubClass BoxedBooleanClass)
+ }
+
+ def newClassLoader(bin: AbstractFile): loaders.SymbolLoader =
+ new loaders.ClassfileLoader(bin)
+
+ def doLoad(cls: ClassPath[BinaryRepr]#ClassRep): Boolean = true
+
+ def needCompile(bin: AbstractFile, src: AbstractFile) =
+ src.lastModified >= bin.lastModified
+}*/
diff --git a/src/dotty/tools/dotc/config/PathResolver.scala b/src/dotty/tools/dotc/config/PathResolver.scala
new file mode 100644
index 000000000..6771e1465
--- /dev/null
+++ b/src/dotty/tools/dotc/config/PathResolver.scala
@@ -0,0 +1,271 @@
+package dotty.tools
+package dotc
+package config
+
+import java.net.{ URL, MalformedURLException }
+import WrappedProperties.AccessControl
+import io.{ ClassPath, JavaClassPath, File, Directory, Path, AbstractFile }
+import ClassPath.{ JavaContext, DefaultJavaContext, join, split }
+import PartialFunction.condOpt
+import scala.language.postfixOps
+
+// Loosely based on the draft specification at:
+// https://wiki.scala-lang.org/display/SW/Classpath
+
+object PathResolver {
+
+ /*
+ // Imports property/environment functions which suppress
+ // security exceptions.
+ import AccessControl._
+
+ def firstNonEmpty(xs: String*) = xs find (_ != "") getOrElse ""
+
+ /** Map all classpath elements to absolute paths and reconstruct the classpath.
+ */
+ def makeAbsolute(cp: String) = ClassPath.map(cp, x => Path(x).toAbsolute.path)
+
+ /** pretty print class path */
+ def ppcp(s: String) = split(s) match {
+ case Nil => ""
+ case Seq(x) => x
+ case xs => xs map ("\n" + _) mkString
+ }
+
+ /** Values found solely by inspecting environment or property variables.
+ */
+ object Environment {
+ private def searchForBootClasspath = (
+ systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse ""
+ )
+
+ /** Environment variables which java pays attention to so it
+ * seems we do as well.
+ */
+ def classPathEnv = envOrElse("CLASSPATH", "")
+ def sourcePathEnv = envOrElse("SOURCEPATH", "")
+
+ def javaBootClassPath = propOrElse("sun.boot.class.path", searchForBootClasspath)
+ def javaExtDirs = propOrEmpty("java.ext.dirs")
+ def scalaHome = propOrEmpty("scala.home")
+ def scalaExtDirs = propOrEmpty("scala.ext.dirs")
+
+ /** The java classpath and whether to use it. */
+ def javaUserClassPath = propOrElse("java.class.path", "")
+ def useJavaClassPath = propOrFalse("scala.usejavacp")
+
+ override def toString = """
+ |object Environment {
+ | scalaHome = %s (useJavaClassPath = %s)
+ | javaBootClassPath = <%d chars>
+ | javaExtDirs = %s
+ | javaUserClassPath = %s
+ | scalaExtDirs = %s
+ |}""".trim.stripMargin.format(
+ scalaHome, useJavaClassPath,
+ javaBootClassPath.length,
+ ppcp(javaExtDirs),
+ ppcp(javaUserClassPath),
+ ppcp(scalaExtDirs)
+ )
+ }
+
+ /** Default values based on those in Environment as interpreted according
+ * to the path resolution specification.
+ */
+ object Defaults {
+ def scalaSourcePath = Environment.sourcePathEnv
+ def javaBootClassPath = Environment.javaBootClassPath
+ def javaUserClassPath = Environment.javaUserClassPath
+ def javaExtDirs = Environment.javaExtDirs
+ def useJavaClassPath = Environment.useJavaClassPath
+
+ def scalaHome = Environment.scalaHome
+ def scalaHomeDir = Directory(scalaHome)
+ def scalaHomeExists = scalaHomeDir.isDirectory
+ def scalaLibDir = Directory(scalaHomeDir / "lib")
+ def scalaClassesDir = Directory(scalaHomeDir / "classes")
+
+ def scalaLibAsJar = File(scalaLibDir / "scala-library.jar")
+ def scalaLibAsDir = Directory(scalaClassesDir / "library")
+
+ def scalaLibDirFound: Option[Directory] =
+ if (scalaLibAsJar.isFile) Some(scalaLibDir)
+ else if (scalaLibAsDir.isDirectory) Some(scalaClassesDir)
+ else None
+
+ def scalaLibFound =
+ if (scalaLibAsJar.isFile) scalaLibAsJar.path
+ else if (scalaLibAsDir.isDirectory) scalaLibAsDir.path
+ else ""
+
+ // XXX It must be time for someone to figure out what all these things
+ // are intended to do. This is disabled here because it was causing all
+ // the scala jars to end up on the classpath twice: one on the boot
+ // classpath as set up by the runner (or regular classpath under -nobootcp)
+ // and then again here.
+ def scalaBootClassPath = ""
+ // scalaLibDirFound match {
+ // case Some(dir) if scalaHomeExists =>
+ // val paths = ClassPath expandDir dir.path
+ // join(paths: _*)
+ // case _ => ""
+ // }
+
+ def scalaExtDirs = Environment.scalaExtDirs
+
+ def scalaPluginPath = (scalaHomeDir / "misc" / "scala-devel" / "plugins").path
+
+ override def toString = """
+ |object Defaults {
+ | scalaHome = %s
+ | javaBootClassPath = %s
+ | scalaLibDirFound = %s
+ | scalaLibFound = %s
+ | scalaBootClassPath = %s
+ | scalaPluginPath = %s
+ |}""".trim.stripMargin.format(
+ scalaHome,
+ ppcp(javaBootClassPath),
+ scalaLibDirFound, scalaLibFound,
+ ppcp(scalaBootClassPath), ppcp(scalaPluginPath)
+ )
+ }
+
+ def fromPathString(path: String, context: JavaContext = DefaultJavaContext): JavaClassPath = {
+ val s = new Settings() {
+ classpath = path
+ }
+ new PathResolver(s, context) result
+ }
+
+ /** With no arguments, show the interesting values in Environment and Defaults.
+ * If there are arguments, show those in Calculated as if those options had been
+ * given to a scala runner.
+ */
+ def main(args: Array[String]): Unit = {
+ if (args.isEmpty) {
+ println(Environment)
+ println(Defaults)
+ }
+ else {
+ val settings = new Settings()
+ val rest = settings.processArguments(args.toList, false)._2
+ val pr = new PathResolver(settings)
+ println(" COMMAND: 'scala %s'".format(args.mkString(" ")))
+ println("RESIDUAL: 'scala %s'\n".format(rest.mkString(" ")))
+ pr.result.show
+ }
+ }
+}
+import PathResolver.{ Defaults, Environment, firstNonEmpty, ppcp }
+
+class PathResolver(settings: Settings, context: JavaContext = DefaultJavaContext) {
+
+ private def cmdLineOrElse(name: String, alt: String) = {
+ (commandLineFor(name) match {
+ case Some("") => None
+ case x => x
+ }) getOrElse alt
+ }
+
+ private def commandLineFor(s: String): Option[String] = ???
+ /*condOpt(s) {
+ case "javabootclasspath" => settings.javabootclasspath.value
+ case "javaextdirs" => settings.javaextdirs.value
+ case "bootclasspath" => settings.bootclasspath.value
+ case "extdirs" => settings.extdirs.value
+ case "classpath" | "cp" => settings.classpath.value
+ case "sourcepath" => settings.sourcepath.value
+ }*/
+
+ /** Calculated values based on any given command line options, falling back on
+ * those in Defaults.
+ */
+ object Calculated {
+ def scalaHome = Defaults.scalaHome
+ def useJavaClassPath = settings.usejavacp.value || Defaults.useJavaClassPath
+ def javaBootClassPath = cmdLineOrElse("javabootclasspath", Defaults.javaBootClassPath)
+ def javaExtDirs = cmdLineOrElse("javaextdirs", Defaults.javaExtDirs)
+ def javaUserClassPath = if (useJavaClassPath) Defaults.javaUserClassPath else ""
+ def scalaBootClassPath = cmdLineOrElse("bootclasspath", Defaults.scalaBootClassPath)
+ def scalaExtDirs = cmdLineOrElse("extdirs", Defaults.scalaExtDirs)
+ /** Scaladoc doesn't need any bootstrapping, otherwise will create errors such as:
+ * [scaladoc] ../scala-trunk/src/reflect/scala/reflect/macros/Reifiers.scala:89: error: object api is not a member of package reflect
+ * [scaladoc] case class ReificationException(val pos: reflect.api.PositionApi, val msg: String) extends Throwable(msg)
+ * [scaladoc] ^
+ * because the bootstrapping will look at the sourcepath and create package "reflect" in "<root>"
+ * and then when typing relative names, instead of picking <root>.scala.relect, typedIdentifier will pick up the
+ * <root>.reflect package created by the bootstrapping. Thus, no bootstrapping for scaladoc!
+ * TODO: we should refactor this as a separate -bootstrap option to have a clean implementation, no? */
+ def sourcePath = if (!settings.isScaladoc) cmdLineOrElse("sourcepath", Defaults.scalaSourcePath) else ""
+
+ /** Against my better judgment, giving in to martin here and allowing
+ * CLASSPATH to be used automatically. So for the user-specified part
+ * of the classpath:
+ *
+ * - If -classpath or -cp is given, it is that
+ * - Otherwise, if CLASSPATH is set, it is that
+ * - If neither of those, then "." is used.
+ */
+ def userClassPath = (
+ if (!settings.classpath.isDefault)
+ settings.classpath.value
+ else sys.env.getOrElse("CLASSPATH", ".")
+ )
+
+ import context._
+
+ // Assemble the elements!
+ def basis = List[Traversable[ClassPath]](
+ classesInPath(javaBootClassPath), // 1. The Java bootstrap class path.
+ contentsOfDirsInPath(javaExtDirs), // 2. The Java extension class path.
+ classesInExpandedPath(javaUserClassPath), // 3. The Java application class path.
+ classesInPath(scalaBootClassPath), // 4. The Scala boot class path.
+ contentsOfDirsInPath(scalaExtDirs), // 5. The Scala extension class path.
+ classesInExpandedPath(userClassPath), // 6. The Scala application class path.
+ sourcesInPath(sourcePath) // 7. The Scala source path.
+ )
+
+ lazy val containers = basis.flatten.distinct
+
+ override def toString = """
+ |object Calculated {
+ | scalaHome = %s
+ | javaBootClassPath = %s
+ | javaExtDirs = %s
+ | javaUserClassPath = %s
+ | useJavaClassPath = %s
+ | scalaBootClassPath = %s
+ | scalaExtDirs = %s
+ | userClassPath = %s
+ | sourcePath = %s
+ |}""".trim.stripMargin.format(
+ scalaHome,
+ ppcp(javaBootClassPath), ppcp(javaExtDirs), ppcp(javaUserClassPath),
+ useJavaClassPath,
+ ppcp(scalaBootClassPath), ppcp(scalaExtDirs), ppcp(userClassPath),
+ ppcp(sourcePath)
+ )
+ }
+
+ def containers = Calculated.containers
+
+ lazy val result = {
+ val cp = new JavaClassPath(containers.toIndexedSeq, context)
+ if (settings.Ylogcp.value) {
+ Console.println("Classpath built from " + settings.toConciseString)
+ Console.println("Defaults: " + PathResolver.Defaults)
+ Console.println("Calculated: " + Calculated)
+
+ val xs = (Calculated.basis drop 2).flatten.distinct
+ println("After java boot/extdirs classpath has %d entries:" format xs.size)
+ xs foreach (x => println(" " + x))
+ }
+ cp
+ }
+
+ def asURLs = result.asURLs
+
+ */
+}
diff --git a/src/dotty/tools/dotc/config/Platform.scala b/src/dotty/tools/dotc/config/Platform.scala
new file mode 100644
index 000000000..73d32f193
--- /dev/null
+++ b/src/dotty/tools/dotc/config/Platform.scala
@@ -0,0 +1,38 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2012 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package dotty.tools
+package dotc
+package config
+
+import io.{ClassPath, AbstractFile}
+import core.Contexts._
+import core.SymDenotations.ClassCompleter
+import core.SymbolLoader
+
+/** The platform dependent pieces of Global.
+ */
+abstract class Platform(base: ContextBase) {
+
+ /** The root symbol loader. */
+ def rootLoader: ClassCompleter
+
+ /** The compiler classpath. */
+ def classPath: ClassPath
+
+ /** Update classpath with a substitution that maps entries to entries */
+ def updateClassPath(subst: Map[ClassPath, ClassPath])
+
+ /** Any platform-specific phases. */
+ //def platformPhases: List[SubComponent]
+
+ /** The various ways a boxed primitive might materialize at runtime. */
+ def isMaybeBoxed(sym: Symbol): Boolean
+
+ /** Create a new class loader to load class file `bin` */
+ def newClassLoader(bin: AbstractFile): SymbolLoader
+
+}
+
diff --git a/src/dotty/tools/dotc/config/Properties.scala b/src/dotty/tools/dotc/config/Properties.scala
new file mode 100644
index 000000000..4507568e4
--- /dev/null
+++ b/src/dotty/tools/dotc/config/Properties.scala
@@ -0,0 +1,165 @@
+package dotty.tools
+package dotc
+package config
+
+import java.io.{ IOException, PrintWriter }
+import java.util.jar.Attributes.{ Name => AttributeName }
+
+/** Loads `library.properties` from the jar. */
+object Properties extends PropertiesTrait {
+ protected def propCategory = "library"
+ protected def pickJarBasedOn = classOf[Option[_]]
+
+ /** Scala manifest attributes.
+ */
+ val ScalaCompilerVersion = new AttributeName("Scala-Compiler-Version")
+}
+
+trait PropertiesTrait {
+ protected def propCategory: String // specializes the remainder of the values
+ protected def pickJarBasedOn: Class[_] // props file comes from jar containing this
+
+ /** The name of the properties file */
+ protected val propFilename = "/" + propCategory + ".properties"
+
+ /** The loaded properties */
+ protected lazy val scalaProps: java.util.Properties = {
+ val props = new java.util.Properties
+ val stream = pickJarBasedOn getResourceAsStream propFilename
+ if (stream ne null)
+ quietlyDispose(props load stream, stream.close)
+
+ props
+ }
+
+ private def quietlyDispose(action: => Unit, disposal: => Unit) =
+ try { action }
+ finally {
+ try { disposal }
+ catch { case _: IOException => }
+ }
+
+ def propIsSet(name: String) = System.getProperty(name) != null
+ def propIsSetTo(name: String, value: String) = propOrNull(name) == value
+ def propOrElse(name: String, alt: String) = System.getProperty(name, alt)
+ def propOrEmpty(name: String) = propOrElse(name, "")
+ def propOrNull(name: String) = propOrElse(name, null)
+ def propOrNone(name: String) = Option(propOrNull(name))
+ def propOrFalse(name: String) = propOrNone(name) exists (x => List("yes", "on", "true") contains x.toLowerCase)
+ def setProp(name: String, value: String) = System.setProperty(name, value)
+ def clearProp(name: String) = System.clearProperty(name)
+
+ def envOrElse(name: String, alt: String) = Option(System getenv name) getOrElse alt
+ def envOrNone(name: String) = Option(System getenv name)
+
+ // for values based on propFilename
+ def scalaPropOrElse(name: String, alt: String): String = scalaProps.getProperty(name, alt)
+ def scalaPropOrEmpty(name: String): String = scalaPropOrElse(name, "")
+ def scalaPropOrNone(name: String): Option[String] = Option(scalaProps.getProperty(name))
+
+ /** The numeric portion of the runtime Scala version, if this is a final
+ * release. If for instance the versionString says "version 2.9.0.final",
+ * this would return Some("2.9.0").
+ *
+ * @return Some(version) if this is a final release build, None if
+ * it is an RC, Beta, etc. or was built from source, or if the version
+ * cannot be read.
+ */
+ 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
+ * unique repository identifier (currently the svn revision) in the
+ * fourth dotted segment if the running version was built from source.
+ *
+ * @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 =
+ 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.
+ */
+ def versionNumberString = scalaPropOrEmpty("version.number")
+
+ /** The version number of the jar this was loaded from plus "version " prefix,
+ * or "version (unknown)" if it cannot be determined.
+ */
+ val versionString = "version " + scalaPropOrElse("version.number", "(unknown)")
+ val copyrightString = scalaPropOrElse("copyright.string", "(c) 2002-2011 LAMP/EPFL")
+
+ /** This is the encoding to use reading in source files, overridden with -encoding
+ * Note that it uses "prop" i.e. looks in the scala jar, not the system properties.
+ */
+ def sourceEncoding = scalaPropOrElse("file.encoding", "UTF-8")
+ def sourceReader = scalaPropOrElse("source.reader", "scala.tools.nsc.io.SourceReader")
+
+ /** This is the default text encoding, overridden (unreliably) with
+ * `JAVA_OPTS="-Dfile.encoding=Foo"`
+ */
+ def encodingString = propOrElse("file.encoding", "UTF-8")
+
+ /** The default end of line character.
+ */
+ def lineSeparator = propOrElse("line.separator", "\n")
+
+ /** Various well-known properties.
+ */
+ def javaClassPath = propOrEmpty("java.class.path")
+ def javaHome = propOrEmpty("java.home")
+ def javaVendor = propOrEmpty("java.vendor")
+ def javaVersion = propOrEmpty("java.version")
+ def javaVmInfo = propOrEmpty("java.vm.info")
+ def javaVmName = propOrEmpty("java.vm.name")
+ def javaVmVendor = propOrEmpty("java.vm.vendor")
+ def javaVmVersion = propOrEmpty("java.vm.version")
+ def osName = propOrEmpty("os.name")
+ def scalaHome = propOrEmpty("scala.home")
+ def tmpDir = propOrEmpty("java.io.tmpdir")
+ def userDir = propOrEmpty("user.dir")
+ def userHome = propOrEmpty("user.home")
+ def userName = propOrEmpty("user.name")
+
+ /** Some derived values.
+ */
+ def isWin = osName startsWith "Windows"
+ def isMac = javaVendor startsWith "Apple"
+
+ // This is looking for javac, tools.jar, etc.
+ // Tries JDK_HOME first, then the more common but likely jre JAVA_HOME,
+ // and finally the system property based javaHome.
+ def jdkHome = envOrElse("JDK_HOME", envOrElse("JAVA_HOME", javaHome))
+
+ def versionMsg = "Scala %s %s -- %s".format(propCategory, versionString, copyrightString)
+ def scalaCmd = if (isWin) "scala.bat" else "scala"
+ def scalacCmd = if (isWin) "scalac.bat" else "scalac"
+
+ /** Can the java version be determined to be at least as high as the argument?
+ * Hard to properly future proof this but at the rate 1.7 is going we can leave
+ * the issue for our cyborg grandchildren to solve.
+ */
+ def isJavaAtLeast(version: String) = {
+ val okVersions = version match {
+ case "1.5" => List("1.5", "1.6", "1.7")
+ case "1.6" => List("1.6", "1.7")
+ case "1.7" => List("1.7")
+ case _ => Nil
+ }
+ okVersions exists (javaVersion startsWith _)
+ }
+
+ // provide a main method so version info can be obtained by running this
+ def main(args: Array[String]) {
+ val writer = new PrintWriter(Console.err, true)
+ writer println versionMsg
+ }
+}
diff --git a/src/dotty/tools/dotc/config/Settings.scala b/src/dotty/tools/dotc/config/Settings.scala
new file mode 100644
index 000000000..83c7a747f
--- /dev/null
+++ b/src/dotty/tools/dotc/config/Settings.scala
@@ -0,0 +1,26 @@
+package dotty.tools.dotc
+package config
+
+
+class Settings {
+
+ protected def defaultClasspath = sys.env.getOrElse("CLASSPATH", ".")
+
+ protected implicit def mkSetting[T](x: T): Setting[T] = new Setting(x)
+
+ var default: Settings = this
+
+ var classpath: Setting[String] = defaultClasspath
+ var debug: Setting[Boolean] = false
+ var verbose: Setting[Boolean] = false
+
+ var XmaxClassfileName: Setting[Int] = 255
+
+ var YtermConflict: Setting[String] = "error"
+
+ def processArguments(arguments: List[String], processAll: Boolean): (Boolean, List[String]) = ???
+
+
+}
+
+case class Setting[T](value: T) \ No newline at end of file
diff --git a/src/dotty/tools/dotc/config/WrappedProperties.scala b/src/dotty/tools/dotc/config/WrappedProperties.scala
new file mode 100644
index 000000000..07972b99b
--- /dev/null
+++ b/src/dotty/tools/dotc/config/WrappedProperties.scala
@@ -0,0 +1,34 @@
+package dotty.tools
+package dotc
+package config
+
+import java.security.AccessControlException
+
+/** For placing a wrapper function around property functions.
+ * Motivated by places like google app engine throwing exceptions
+ * on property lookups.
+ */
+trait WrappedProperties extends PropertiesTrait {
+ def wrap[T](body: => T): Option[T]
+
+ protected def propCategory = "wrapped"
+ protected def pickJarBasedOn = this.getClass
+
+ override def propIsSet(name: String) = wrap(super.propIsSet(name)) exists (x => x)
+ override def propOrElse(name: String, alt: String) = wrap(super.propOrElse(name, alt)) getOrElse alt
+ override def setProp(name: String, value: String) = wrap(super.setProp(name, value)).orNull
+ override def clearProp(name: String) = wrap(super.clearProp(name)).orNull
+ override def envOrElse(name: String, alt: String) = wrap(super.envOrElse(name, alt)) getOrElse alt
+ override def envOrNone(name: String) = wrap(super.envOrNone(name)).flatten
+
+ def systemProperties: Iterator[(String, String)] = {
+ import scala.collection.JavaConverters._
+ wrap(System.getProperties.asScala.iterator) getOrElse Iterator.empty
+ }
+}
+
+object WrappedProperties {
+ object AccessControl extends WrappedProperties {
+ def wrap[T](body: => T) = try Some(body) catch { case _: AccessControlException => None }
+ }
+}
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index e2fe9822f..d7c8609f1 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -10,6 +10,7 @@ import Symbols._
import TypeComparers._, Printers._, NameOps._, SymDenotations._
import collection.mutable
import collection.immutable.BitSet
+import config.{Settings, Platform}
object Contexts {
@@ -53,12 +54,16 @@ object Contexts {
protected def owner_=(owner: Symbol) = _owner = owner
def owner: Symbol = _owner
+ private[this] var _settings: Settings = _
+ protected def settings_=(settings: Settings) = _settings = settings
+ def settings: Settings = _settings
+
def phase: Phase = ??? // phase(period.phaseId)
def enclClass: Context = ???
def erasedTypes: Boolean = ???
def debug: Boolean = ???
-// def settings: Settings = ???
def warning(msg: String) = ???
+ def inform(msg: String) = ???
def fresh: FreshContext = {
val newctx = super.clone.asInstanceOf[FreshContext]
@@ -90,8 +95,7 @@ object Contexts {
}
class ContextBase extends Transformers.TransformerBase
- with Printers.PrinterBase
- with NameOps.NameOpsBase {
+ with Printers.PrinterBase {
val initialCtx: Context = new InitialContext(this)
@@ -99,6 +103,10 @@ object Contexts {
lazy val definitions = new Definitions()(initialCtx)
+ lazy val loaders = new SymbolLoaders
+
+ lazy val platform: Platform = ???
+
// Symbols state
/** A map from a superclass id to the class that has it */
private[core] var classOfId = new Array[ClassSymbol](InitialSuperIdsSize)
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index cafc4495d..13392a1c9 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -331,7 +331,7 @@ object Flags {
/** Flags representing access rights */
final val AccessFlags = Private | Protected | Local
- final val ModuleFlags: FlagSet = ???
+ final val RetainedModuleFlags: FlagSet = ???
final val UninstantiatableFlags = Abstract | Final
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index 2bbfa1360..5aa7e2e25 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -10,25 +10,24 @@ import Decorators.StringDecorator
object NameOps {
- trait NameOpsBase { this: ContextBase =>
-
- final object compactify extends (String => String) {
- val md5 = MessageDigest.getInstance("MD5")
-
- /** COMPACTIFY
- *
- * The hashed name has the form (prefix + marker + md5 + marker + suffix), where
- * - prefix/suffix.length = MaxNameLength / 4
- * - md5.length = 32
- *
- * We obtain the formula:
- *
- * FileNameLength = 2*(MaxNameLength / 4) + 2.marker.length + 32 + 6
- *
- * (+6 for ".class"). MaxNameLength can therefore be computed as follows:
- */
+ final object compactify {
+ lazy val md5 = MessageDigest.getInstance("MD5")
+
+ /** COMPACTIFY
+ *
+ * The hashed name has the form (prefix + marker + md5 + marker + suffix), where
+ * - prefix/suffix.length = MaxNameLength / 4
+ * - md5.length = 32
+ *
+ * We obtain the formula:
+ *
+ * FileNameLength = 2*(MaxNameLength / 4) + 2.marker.length + 32 + 6
+ *
+ * (+6 for ".class"). MaxNameLength can therefore be computed as follows:
+ */
+ def apply(s: String)(implicit ctx: Context): String = {
val marker = "$$$$"
- val limit: Int = ??? // !!! settings.maxClassfileName.value
+ val limit: Int = ctx.settings.XmaxClassfileName.value
val MaxNameLength = (limit - 6) min 2 * (limit - 6 - 2 * marker.length - 32)
def toMD5(s: String, edge: Int): String = {
@@ -42,21 +41,11 @@ object NameOps {
prefix + marker + md5chars + marker + suffix
}
- def apply(s: String): String =
- if (s.length <= MaxNameLength) s else toMD5(s, MaxNameLength / 4)
+
+ if (s.length <= MaxNameLength) s else toMD5(s, MaxNameLength / 4)
}
}
- private val Boxed = Map[TypeName, TypeName](
- tpnme.Boolean -> jtpnme.BoxedBoolean,
- tpnme.Byte -> jtpnme.BoxedByte,
- tpnme.Char -> jtpnme.BoxedCharacter,
- tpnme.Short -> jtpnme.BoxedShort,
- tpnme.Int -> jtpnme.BoxedInteger,
- tpnme.Long -> jtpnme.BoxedLong,
- tpnme.Float -> jtpnme.BoxedFloat,
- tpnme.Double -> jtpnme.BoxedDouble)
-
implicit class NameDecorator(val name: Name) extends AnyVal {
import nme._
@@ -147,9 +136,21 @@ object NameOps {
}
/** If name length exceeds allowable limit, replace part of it by hash */
- def compactified(implicit ctx: Context): TermName = termName(ctx.compactify(name.toString))
+ def compactified(implicit ctx: Context): TermName = termName(compactify(name.toString))
}
+ // needed???
+ private val Boxed = Map[TypeName, TypeName](
+ tpnme.Boolean -> jtpnme.BoxedBoolean,
+ tpnme.Byte -> jtpnme.BoxedByte,
+ tpnme.Char -> jtpnme.BoxedCharacter,
+ tpnme.Short -> jtpnme.BoxedShort,
+ tpnme.Int -> jtpnme.BoxedInteger,
+ tpnme.Long -> jtpnme.BoxedLong,
+ tpnme.Float -> jtpnme.BoxedFloat,
+ tpnme.Double -> jtpnme.BoxedDouble)
+
+ // needed???
implicit class TypeNameDecorator(val name: TypeName) extends AnyVal {
def isUnboxedName = Boxed contains name
def boxedName: TypeName = Boxed(name)
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 0b61906b1..e916d0e70 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -721,7 +721,7 @@ object SymDenotations {
def classDenot(denot: LazySymDenotation) =
denot.moduleClass.denot.asInstanceOf[LazyClassDenotation]
def copyLoadedFields(denot: LazySymDenotation, from: LazyClassDenotation) = {
- denot.setFlags(from.flags.toTermFlags & ModuleFlags)
+ denot.setFlags(from.flags.toTermFlags & RetainedModuleFlags)
denot.privateWithin = from.privateWithin
}
def copyCompletedFields(denot: LazySymDenotation, from: LazyClassDenotation) = {
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 972242fbd..41bd0fdeb 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -10,108 +10,84 @@ package core
import java.io.IOException
import scala.compat.Platform.currentTime
import dotty.tools.io.{ClassPath, AbstractFile}
-import Contexts._, Symbols._, Flags._, SymDenotations._
+import Contexts._, Symbols._, Flags._, SymDenotations._, Types._
import Decorators.StringDecorator
//import classfile.ClassfileParser
+abstract class SymbolLoader extends ClassCompleter
-abstract class SymbolLoaders(implicit ctx: Context) {
- protected def enterIfNew(owner: Symbol, member: Symbol, completer: SymbolLoader): Symbol = {
+class SymbolLoaders {
+
+ protected def enterIfNew(owner: Symbol, member: Symbol, completer: SymbolLoader)(implicit ctx: Context): Symbol = {
assert(owner.info.decls.lookup(member.name) == NoSymbol, owner.fullName + "." + member.name)
owner.info.decls enter member
member
}
- /** Enter class with given `name` into scope of `root`
- * and give them `completer` as type.
+ /** Enter class with given `name` into scope of `owner`.
*/
- def enterClass(owner: Symbol, name: String, completer: SymbolLoader): Symbol = {
+ def enterClass(owner: Symbol, name: String, completer: SymbolLoader)(implicit ctx: Context): Symbol = {
val cls = ctx.newLazyClassSymbol(owner, name.toTypeName, EmptyFlags, completer)
enterIfNew(owner, cls, completer)
}
- /** Enter module with given `name` into scope of `root`
- * and give them `completer` as type.
+ /** Enter module with given `name` into scope of `owner`.
*/
- def enterModule(owner: Symbol, name: String, completer: SymbolLoader): Symbol = {
+ def enterModule(owner: Symbol, name: String, completer: SymbolLoader)(implicit ctx: Context): Symbol = {
val module = ctx.newLazyModuleSymbol(owner, name.toTermName, EmptyFlags, completer)
enterIfNew(owner, module, completer)
}
- abstract class SymbolLoader extends ClassCompleter
-}
-/*
- /** Enter module with given `name` into scope of `root`
- * and give them `completer` as type.
- */
- def enterModule(owner: Symbol, name: String, completer: SymbolLoader): Symbol = {
- val module = owner.newModule(newTermName(name))
- module setInfo completer
- module.moduleClass setInfo moduleClassLoader
- enterIfNew(owner, module, completer)
- }
-
- /** Enter package with given `name` into scope of `root`
+ /** Enter package with given `name` into scope of `owner`
* and give them `completer` as type.
*/
- def enterPackage(root: Symbol, name: String, completer: SymbolLoader): Symbol = {
- val pname = newTermName(name)
- val preExisting = root.info.decls lookup pname
+ def enterPackage(owner: Symbol, name: String, completer: SymbolLoader)(implicit ctx: Context): Symbol = {
+ val pname = name.toTermName
+ val preExisting = owner.info.decls lookup pname
if (preExisting != NoSymbol) {
// Some jars (often, obfuscated ones) include a package and
// object with the same name. Rather than render them unusable,
// offer a setting to resolve the conflict one way or the other.
// This was motivated by the desire to use YourKit probes, which
// require yjp.jar at runtime. See SI-2089.
- if (settings.termConflict.isDefault)
+ if (ctx.settings.YtermConflict == ctx.settings.default.YtermConflict)
throw new TypeError(
- root+" contains object and package with same name: "+
- name+"\none of them needs to be removed from classpath"
- )
- else if (settings.termConflict.value == "package") {
- global.warning(
- "Resolving package/object name conflict in favor of package " +
- preExisting.fullName + ". The object will be inaccessible."
- )
- root.info.decls.unlink(preExisting)
- }
- else {
- global.warning(
- "Resolving package/object name conflict in favor of object " +
- preExisting.fullName + ". The package will be inaccessible."
- )
+ s"""$owner contains object and package with same name: $name
+ |one of them needs to be removed from classpath""".stripMargin)
+ else if (ctx.settings.YtermConflict.value == "package") {
+ ctx.warning(
+ s"Resolving package/object name conflict in favor of package ${preExisting.fullName}. The object will be inaccessible.")
+ owner.info.decls.unlink(preExisting)
+ } else {
+ ctx.warning(
+ s"Resolving package/object name conflict in favor of object ${preExisting.fullName}. The package will be inaccessible.")
return NoSymbol
}
}
- // todo: find out initialization sequence for pkg/pkg.moduleClass is different from enterModule
- val pkg = root.newPackage(pname)
- pkg.moduleClass setInfo completer
- pkg setInfo pkg.moduleClass.tpe
- root.info.decls enter pkg
- pkg
+ ctx.newLazyModuleSymbol(owner, pname, PackageCreationFlags, completer).entered
}
- /** Enter class and module with given `name` into scope of `root`
+ /** Enter class and module with given `name` into scope of `owner`
* and give them `completer` as type.
*/
- def enterClassAndModule(root: Symbol, name: String, completer: SymbolLoader) {
- val clazz = enterClass(root, name, completer)
- val module = enterModule(root, name, completer)
+ def enterClassAndModule(owner: Symbol, name: String, completer: SymbolLoader)(implicit ctx: Context) {
+ val clazz = enterClass(owner, name, completer)
+ val module = enterModule(owner, name, completer)
if (!clazz.isAnonymousClass) {
assert(clazz.companionModule == module, module)
assert(module.companionClass == clazz, clazz)
}
}
- /** In batch mode: Enter class and module with given `name` into scope of `root`
+ /** In batch mode: Enter class and module with given `name` into scope of `owner`
* and give them a source completer for given `src` as type.
- * In IDE mode: Find all toplevel definitions in `src` and enter then into scope of `root`
+ * In IDE mode: Find all toplevel definitions in `src` and enter then into scope of `owner`
* with source completer for given `src` as type.
* (overridden in interactive.Global).
*/
- def enterToplevelsFromSource(root: Symbol, name: String, src: AbstractFile) {
- enterClassAndModule(root, name, new SourcefileLoader(src))
+ def enterToplevelsFromSource(owner: Symbol, name: String, src: AbstractFile)(implicit ctx: Context) {
+ ??? // !!! enterClassAndModule(owner, name, new SourcefileLoader(src))
}
/** The package objects of scala and scala.reflect should always
@@ -121,26 +97,29 @@ abstract class SymbolLoaders(implicit ctx: Context) {
* Note: We do a name-base comparison here because the method is called before we even
* have ReflectPackage defined.
*/
- def binaryOnly(owner: Symbol, name: String): Boolean =
+ def binaryOnly(owner: Symbol, name: String)(implicit ctx: Context): Boolean =
name == "package" &&
(owner.fullName == "scala" || owner.fullName == "scala.reflect")
/** Initialize toplevel class and module symbols in `owner` from class path representation `classRep`
*/
- def initializeFromClassPath(owner: Symbol, classRep: ClassPath[platform.BinaryRepr]#ClassRep) {
+ def initializeFromClassPath(owner: Symbol, classRep: ClassPath#ClassRep)(implicit ctx: Context) {
((classRep.binary, classRep.source) : @unchecked) match {
case (Some(bin), Some(src))
- if platform.needCompile(bin, src) && !binaryOnly(owner, classRep.name) =>
- if (settings.verbose.value) inform("[symloader] picked up newer source file for " + src.path)
- global.loaders.enterToplevelsFromSource(owner, classRep.name, src)
+ if needCompile(bin, src) && !binaryOnly(owner, classRep.name) =>
+ if (ctx.settings.verbose.value) ctx.inform("[symloader] picked up newer source file for " + src.path)
+ enterToplevelsFromSource(owner, classRep.name, src)
case (None, Some(src)) =>
- if (settings.verbose.value) inform("[symloader] no class, picked up source file for " + src.path)
- global.loaders.enterToplevelsFromSource(owner, classRep.name, src)
+ if (ctx.settings.verbose.value) ctx.inform("[symloader] no class, picked up source file for " + src.path)
+ enterToplevelsFromSource(owner, classRep.name, src)
case (Some(bin), _) =>
- global.loaders.enterClassAndModule(owner, classRep.name, platform.newClassLoader(bin))
+ enterClassAndModule(owner, classRep.name, ctx.platform.newClassLoader(bin))
}
}
+ def needCompile(bin: AbstractFile, src: AbstractFile) =
+ src.lastModified >= bin.lastModified
+}/*
/**
* A lazy type that completes itself by calling parameter doComplete.
* Any linked modules/classes or module classes are also initialized.
diff --git a/src/dotty/tools/io/ClassPath.scala b/src/dotty/tools/io/ClassPath.scala
index 5a2fdad41..83a7703f4 100644
--- a/src/dotty/tools/io/ClassPath.scala
+++ b/src/dotty/tools/io/ClassPath.scala
@@ -105,7 +105,7 @@ object ClassPath {
/** A class modeling aspects of a ClassPath which should be
* propagated to any classpaths it creates.
*/
- abstract class ClassPathContext[T] {
+ abstract class ClassPathContext {
/** A filter which can be used to exclude entities from the classpath
* based on their name.
*/
@@ -113,30 +113,30 @@ object ClassPath {
/** From the representation to its identifier.
*/
- def toBinaryName(rep: T): String
+ def toBinaryName(rep: AbstractFile): String
/** Create a new classpath based on the abstract file.
*/
- def newClassPath(file: AbstractFile): ClassPath[T]
+ def newClassPath(file: AbstractFile): ClassPath
/** Creators for sub classpaths which preserve this context.
*/
- def sourcesInPath(path: String): List[ClassPath[T]] =
+ def sourcesInPath(path: String): List[ClassPath] =
for (file <- expandPath(path, false) ; dir <- Option(AbstractFile getDirectory file)) yield
- new SourcePath[T](dir, this)
+ new SourcePath(dir, this)
- def contentsOfDirsInPath(path: String): List[ClassPath[T]] =
+ def contentsOfDirsInPath(path: String): List[ClassPath] =
for (dir <- expandPath(path, false) ; name <- expandDir(dir) ; entry <- Option(AbstractFile getDirectory name)) yield
newClassPath(entry)
- def classesAtAllURLS(path: String): List[ClassPath[T]] =
+ def classesAtAllURLS(path: String): List[ClassPath] =
(path split " ").toList flatMap classesAtURL
def classesAtURL(spec: String) =
for (url <- specToURL(spec).toList ; location <- Option(AbstractFile getURL url)) yield
newClassPath(location)
- def classesInExpandedPath(path: String): IndexedSeq[ClassPath[T]] =
+ def classesInExpandedPath(path: String): IndexedSeq[ClassPath] =
classesInPathImpl(path, true).toIndexedSeq
def classesInPath(path: String) = classesInPathImpl(path, false)
@@ -147,7 +147,7 @@ object ClassPath {
newClassPath(dir)
}
- class JavaContext extends ClassPathContext[AbstractFile] {
+ class JavaContext extends ClassPathContext {
def toBinaryName(rep: AbstractFile) = {
val name = rep.name
assert(endsClass(name), name)
@@ -178,8 +178,8 @@ object ClassPath {
/**
* Represents a package which contains classes and other packages
*/
-abstract class ClassPath[T] {
- type AnyClassRep = ClassPath[T]#ClassRep
+abstract class ClassPath {
+ type AnyClassRep = ClassPath#ClassRep
/**
* The short name of the package (without prefix)
@@ -202,19 +202,19 @@ abstract class ClassPath[T] {
/** Info which should be propagated to any sub-classpaths.
*/
- def context: ClassPathContext[T]
+ def context: ClassPathContext
/** Lists of entities.
*/
def classes: IndexedSeq[AnyClassRep]
- def packages: IndexedSeq[ClassPath[T]]
+ def packages: IndexedSeq[ClassPath]
def sourcepaths: IndexedSeq[AbstractFile]
/**
* Represents classes which can be loaded with a ClassfileLoader/MsilFileLoader
* and / or a SourcefileLoader.
*/
- case class ClassRep(binary: Option[T], source: Option[AbstractFile]) {
+ case class ClassRep(binary: Option[AbstractFile], source: Option[AbstractFile]) {
def name: String = binary match {
case Some(x) => context.toBinaryName(x)
case _ =>
@@ -253,8 +253,8 @@ abstract class ClassPath[T] {
def sortString = join(split(asClasspathString).sorted: _*)
override def equals(that: Any) = that match {
- case x: ClassPath[_] => this.sortString == x.sortString
- case _ => false
+ case x: ClassPath => this.sortString == x.sortString
+ case _ => false
}
override def hashCode = sortString.hashCode()
}
@@ -262,7 +262,7 @@ abstract class ClassPath[T] {
/**
* A Classpath containing source files
*/
-class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends ClassPath[T] {
+class SourcePath(dir: AbstractFile, val context: ClassPathContext) extends ClassPath {
def name = dir.name
override def origin = dir.underlyingSource map (_.path)
def asURLs = if (dir.file == null) Nil else List(dir.toURL)
@@ -271,12 +271,12 @@ class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends
private def traverse() = {
val classBuf = immutable.Vector.newBuilder[ClassRep]
- val packageBuf = immutable.Vector.newBuilder[SourcePath[T]]
+ val packageBuf = immutable.Vector.newBuilder[SourcePath]
dir foreach { f =>
if (!f.isDirectory && validSourceFile(f.name))
classBuf += ClassRep(None, Some(f))
else if (f.isDirectory && validPackage(f.name))
- packageBuf += new SourcePath[T](f, context)
+ packageBuf += new SourcePath(f, context)
}
(packageBuf.result, classBuf.result)
}
@@ -288,7 +288,7 @@ class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends
/**
* A directory (or a .jar file) containing classfiles and packages
*/
-class DirectoryClassPath(val dir: AbstractFile, val context: ClassPathContext[AbstractFile]) extends ClassPath[AbstractFile] {
+class DirectoryClassPath(val dir: AbstractFile, val context: ClassPathContext) extends ClassPath {
def name = dir.name
override def origin = dir.underlyingSource map (_.path)
def asURLs = if (dir.file == null) Nil else List(dir.toURL)
@@ -312,8 +312,8 @@ class DirectoryClassPath(val dir: AbstractFile, val context: ClassPathContext[Ab
override def toString() = "directory classpath: "+ origin.getOrElse("?")
}
-class DeltaClassPath[T](original: MergedClassPath[T], subst: Map[ClassPath[T], ClassPath[T]])
-extends MergedClassPath[T](original.entries map (e => subst getOrElse (e, e)), original.context) {
+class DeltaClassPath(original: MergedClassPath, subst: Map[ClassPath, ClassPath])
+extends MergedClassPath(original.entries map (e => subst getOrElse (e, e)), original.context) {
// not sure we should require that here. Commented out for now.
// require(subst.keySet subsetOf original.entries.toSet)
// We might add specialized operations for computing classes packages here. Not sure it's worth it.
@@ -322,11 +322,11 @@ extends MergedClassPath[T](original.entries map (e => subst getOrElse (e, e)), o
/**
* A classpath unifying multiple class- and sourcepath entries.
*/
-class MergedClassPath[T](
- val entries: IndexedSeq[ClassPath[T]],
- val context: ClassPathContext[T])
-extends ClassPath[T] {
- def this(entries: TraversableOnce[ClassPath[T]], context: ClassPathContext[T]) =
+class MergedClassPath(
+ val entries: IndexedSeq[ClassPath],
+ val context: ClassPathContext)
+extends ClassPath {
+ def this(entries: TraversableOnce[ClassPath], context: ClassPathContext) =
this(entries.toIndexedSeq, context)
def name = entries.head.name
@@ -361,10 +361,10 @@ extends ClassPath[T] {
cls.toIndexedSeq
}
- lazy val packages: IndexedSeq[ClassPath[T]] = {
+ lazy val packages: IndexedSeq[ClassPath] = {
var count = 0
val indices = mutable.HashMap[String, Int]()
- val pkg = new mutable.ArrayBuffer[ClassPath[T]](256)
+ val pkg = new mutable.ArrayBuffer[ClassPath](256)
for (e <- entries; p <- e.packages) {
val name = p.name
@@ -381,12 +381,12 @@ extends ClassPath[T] {
pkg.toIndexedSeq
}
- private def addPackage(to: ClassPath[T], pkg: ClassPath[T]) = {
- val newEntries: IndexedSeq[ClassPath[T]] = to match {
- case cp: MergedClassPath[_] => cp.entries :+ pkg
- case _ => IndexedSeq(to, pkg)
+ private def addPackage(to: ClassPath, pkg: ClassPath) = {
+ val newEntries: IndexedSeq[ClassPath] = to match {
+ case cp: MergedClassPath => cp.entries :+ pkg
+ case _ => IndexedSeq(to, pkg)
}
- new MergedClassPath[T](newEntries, context)
+ new MergedClassPath(newEntries, context)
}
def show() {
println("ClassPath %s has %d entries and results in:\n".format(name, entries.size))
@@ -400,9 +400,9 @@ extends ClassPath[T] {
* as AbstractFile. nsc.io.ZipArchive is used to view zip/jar archives as directories.
*/
class JavaClassPath(
- containers: IndexedSeq[ClassPath[AbstractFile]],
+ containers: IndexedSeq[ClassPath],
context: JavaContext)
-extends MergedClassPath[AbstractFile](containers, context) { }
+extends MergedClassPath(containers, context) { }
object JavaClassPath {
def fromURLs(urls: Seq[URL], context: JavaContext): JavaClassPath = {