diff options
Diffstat (limited to 'src/reflect/scala/reflect/internal/util')
11 files changed, 93 insertions, 59 deletions
diff --git a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala index 5cbdb92664..49ab0cb30e 100644 --- a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala +++ b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala @@ -5,13 +5,27 @@ package scala package reflect.internal.util -import scala.collection.{ mutable, immutable } -import scala.reflect.io.{ AbstractFile, Streamable } +import scala.collection.mutable +import scala.reflect.io.AbstractFile import java.net.{ URL, URLConnection, URLStreamHandler } import java.security.cert.Certificate import java.security.{ ProtectionDomain, CodeSource } import java.util.{ Collections => JCollections, Enumeration => JEnumeration } +object AbstractFileClassLoader { + // should be a method on AbstractFile, but adding in `internal.util._` for now as we're in a minor release + private[scala] final def lookupPath(base: AbstractFile)(pathParts: Seq[String], directory: Boolean): AbstractFile = { + var file: AbstractFile = base + for (dirPart <- pathParts.init) { + file = file.lookupName(dirPart, directory = true) + if (file == null) + return null + } + + file.lookupName(pathParts.last, directory = directory) + } +} + /** A class loader that loads files from a [[scala.reflect.io.AbstractFile]]. * * @author Lex Spoon @@ -25,19 +39,7 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader) else s"${name.replace('.', '/')}.class" protected def findAbstractFile(name: String): AbstractFile = { - var file: AbstractFile = root - val pathParts = name split '/' - - for (dirPart <- pathParts.init) { - file = file.lookupName(dirPart, directory = true) - if (file == null) - return null - } - - file.lookupName(pathParts.last, directory = false) match { - case null => null - case file => file - } + AbstractFileClassLoader.lookupPath(root)(name split '/', directory = false) } protected def dirNameToPath(name: String): String = @@ -90,7 +92,7 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader) } } - private val packages = mutable.Map[String, Package]() + private[this] val packages = mutable.Map[String, Package]() override def definePackage(name: String, specTitle: String, specVersion: String, specVendor: String, implTitle: String, implVersion: String, implVendor: String, sealBase: URL): Package = { throw new UnsupportedOperationException() diff --git a/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala b/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala index 8442c1015f..c69dd23c40 100644 --- a/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala +++ b/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala @@ -8,7 +8,6 @@ package util import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicLong -import scala.collection.mutable import scala.reflect.NameTransformer class FreshNameCreator(creatorPrefix: String = "") { diff --git a/src/reflect/scala/reflect/internal/util/Origins.scala b/src/reflect/scala/reflect/internal/util/Origins.scala index 2eb4fa29d5..4c425457a7 100644 --- a/src/reflect/scala/reflect/internal/util/Origins.scala +++ b/src/reflect/scala/reflect/internal/util/Origins.scala @@ -7,7 +7,7 @@ package scala package reflect package internal.util -import scala.collection.{ mutable, immutable } +import scala.collection.mutable /** A debugging class for logging from whence a method is being called. * Say you wanted to discover who was calling phase_= in SymbolTable. diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala index 0192d31806..0db91144c9 100644 --- a/src/reflect/scala/reflect/internal/util/Position.scala +++ b/src/reflect/scala/reflect/internal/util/Position.scala @@ -222,7 +222,7 @@ private[util] trait InternalPositionImpl { private[util] trait DeprecatedPosition { self: Position => - @deprecated("use `point`", "2.9.0") // Used in SBT 0.12.4 + @deprecated("use `point`", "2.9.0") // Used in sbt 0.12.4 def offset: Option[Int] = if (isDefined) Some(point) else None @deprecated("use `focus`", "2.11.0") @@ -240,12 +240,12 @@ private[util] trait DeprecatedPosition { @deprecated("use `lineCaret`", since="2.11.0") def lineWithCarat(maxWidth: Int): (String, String) = ("", "") - @deprecated("Use `withSource(source)` and `withShift`", "2.11.0") + @deprecated("use `withSource(source)` and `withShift`", "2.11.0") def withSource(source: SourceFile, shift: Int): Position = this withSource source withShift shift - @deprecated("Use `start` instead", "2.11.0") + @deprecated("use `start` instead", "2.11.0") def startOrPoint: Int = if (isRange) start else point - @deprecated("Use `end` instead", "2.11.0") + @deprecated("use `end` instead", "2.11.0") def endOrPoint: Int = if (isRange) end else point } diff --git a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala index 41011f6c6b..f3db2017be 100644 --- a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala +++ b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala @@ -6,15 +6,16 @@ package scala package reflect.internal.util +import scala.language.implicitConversions + import java.lang.{ ClassLoader => JClassLoader } -import java.lang.reflect.{ Constructor, Modifier, Method } -import java.io.{ File => JFile } +import java.lang.reflect.Modifier import java.net.{ URLClassLoader => JURLClassLoader } import java.net.URL -import scala.reflect.runtime.ReflectionUtils.unwrapHandler + +import scala.reflect.runtime.ReflectionUtils.{ show, unwrapHandler } import ScalaClassLoader._ import scala.util.control.Exception.{ catching } -import scala.language.implicitConversions import scala.reflect.{ ClassTag, classTag } trait HasClassPath { @@ -46,6 +47,33 @@ trait ScalaClassLoader extends JClassLoader { def create(path: String): AnyRef = tryToInitializeClass[AnyRef](path).map(_.newInstance()).orNull + /** Create an instance with ctor args, or invoke errorFn before throwing. */ + def create[T <: AnyRef : ClassTag](path: String, errorFn: String => Unit)(args: AnyRef*): T = { + def fail(msg: String) = error(msg, new IllegalArgumentException(msg)) + def error(msg: String, e: Throwable) = { errorFn(msg) ; throw e } + try { + val clazz = Class.forName(path, /*initialize =*/ true, /*loader =*/ this) + if (classTag[T].runtimeClass isAssignableFrom clazz) { + val ctor = { + val maybes = clazz.getConstructors filter (c => c.getParameterCount == args.size && + (c.getParameterTypes zip args).forall { case (k, a) => k isAssignableFrom a.getClass }) + if (maybes.size == 1) maybes.head + else fail(s"Constructor must accept arg list (${args map (_.getClass.getName) mkString ", "}): ${path}") + } + (ctor.newInstance(args: _*)).asInstanceOf[T] + } else { + errorFn(s"""Loader for ${classTag[T]}: [${show(classTag[T].runtimeClass.getClassLoader)}] + |Loader for ${clazz.getName}: [${show(clazz.getClassLoader)}]""".stripMargin) + fail(s"Not a ${classTag[T]}: ${path}") + } + } catch { + case e: ClassNotFoundException => + error(s"Class not found: ${path}", e) + case e @ (_: LinkageError | _: ReflectiveOperationException) => + error(s"Unable to create instance: ${path}: ${e.toString}", e) + } + } + /** The actual bytes for a class file, or an empty array if it can't be found. */ def classBytes(className: String): Array[Byte] = classAsStream(className) match { case null => Array() @@ -111,6 +139,10 @@ object ScalaClassLoader { classloaderURLs :+= url super.addURL(url) } + override def close(): Unit = { + super.close() + classloaderURLs = null + } } def fromURLs(urls: Seq[URL], parent: ClassLoader = null): URLClassLoader = diff --git a/src/reflect/scala/reflect/internal/util/SourceFile.scala b/src/reflect/scala/reflect/internal/util/SourceFile.scala index a2642628a4..64b6972298 100644 --- a/src/reflect/scala/reflect/internal/util/SourceFile.scala +++ b/src/reflect/scala/reflect/internal/util/SourceFile.scala @@ -154,18 +154,23 @@ class BatchSourceFile(val file : AbstractFile, content0: Array[Char]) extends So case _ => false } - def calculateLineIndices(cs: Array[Char]) = { - val buf = new ArrayBuffer[Int] - buf += 0 - for (i <- 0 until cs.length) if (isAtEndOfLine(i)) buf += i + 1 - buf += cs.length // sentinel, so that findLine below works smoother - buf.toArray + private lazy val lineIndices: Array[Int] = { + def calculateLineIndices(cs: Array[Char]) = { + val buf = new ArrayBuffer[Int] + buf += 0 + for (i <- 0 until cs.length) if (isAtEndOfLine(i)) buf += i + 1 + buf += cs.length // sentinel, so that findLine below works smoother + buf.toArray + } + calculateLineIndices(content) } - private lazy val lineIndices: Array[Int] = calculateLineIndices(content) - def lineToOffset(index : Int): Int = lineIndices(index) + def lineToOffset(index: Int): Int = { + val offset = lineIndices(index) + if (offset < length) offset else throw new IndexOutOfBoundsException(index.toString) + } - private var lastLine = 0 + private[this] var lastLine = 0 /** Convert offset to line in this source file. * Lines are numbered from 0. diff --git a/src/reflect/scala/reflect/internal/util/Statistics.scala b/src/reflect/scala/reflect/internal/util/Statistics.scala index 905f1bf26e..2d623f3367 100644 --- a/src/reflect/scala/reflect/internal/util/Statistics.scala +++ b/src/reflect/scala/reflect/internal/util/Statistics.scala @@ -78,7 +78,7 @@ object Statistics { /** Create a new stackable that shows as `prefix` and is active * in the same phases as its base timer. Stackable timers are subtimers - * that can be stacked ina timerstack, and that print aggregate, as well as specific + * that can be stacked in a timerstack, and that print aggregate, as well as specific * durations. */ def newStackableTimer(prefix: String, timer: Timer): StackableTimer = new StackableTimer(prefix, timer) diff --git a/src/reflect/scala/reflect/internal/util/StringOps.scala b/src/reflect/scala/reflect/internal/util/StringOps.scala index efb8126ff0..2fee6b0f82 100644 --- a/src/reflect/scala/reflect/internal/util/StringOps.scala +++ b/src/reflect/scala/reflect/internal/util/StringOps.scala @@ -11,7 +11,7 @@ package reflect package internal package util -import scala.compat.Platform.EOL +import java.lang.System.{lineSeparator => EOL} /** This object provides utility methods to extract elements * from Strings. @@ -45,7 +45,7 @@ trait StringOps { else s.substring(0, end) } /** Breaks the string into lines and strips each line before reassembling. */ - def trimAllTrailingSpace(s: String): String = s.lines map trimTrailingSpace mkString EOL + def trimAllTrailingSpace(s: String): String = s.lines.map(trimTrailingSpace).mkString(EOL) def decompose(str: String, sep: Char): List[String] = { def ws(start: Int): List[String] = @@ -69,18 +69,17 @@ trait StringOps { else Some((str take idx, str drop (if (doDropIndex) idx + 1 else idx))) /** Returns a string meaning "n elements". + * Don't try an element such as "index" with irregular plural. */ - def countElementsAsString(n: Int, elements: String): String = + def countElementsAsString(n: Int, element: String): String = n match { - case 0 => "no " + elements + "s" - case 1 => "one " + elements - case 2 => "two " + elements + "s" - case 3 => "three " + elements + "s" - case 4 => "four " + elements + "s" - case _ => "" + n + " " + elements + "s" + case 0 => s"no ${element}s" + case 1 => s"one ${element}" + case _ => s"${countAsString(n)} ${element}s" } /** Turns a count into a friendly English description if n<=4. + * Otherwise, a scary math representation. */ def countAsString(n: Int): String = n match { @@ -89,8 +88,8 @@ trait StringOps { case 2 => "two" case 3 => "three" case 4 => "four" - case _ => "" + n + case _ => n.toString } } -object StringOps extends StringOps { } +object StringOps extends StringOps diff --git a/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala b/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala index e4a6503184..e48c35908f 100644 --- a/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala +++ b/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala @@ -2,8 +2,7 @@ package scala package reflect.internal package util -import scala.collection.{ mutable, immutable } -import scala.language.postfixOps +import scala.collection.mutable trait TraceSymbolActivity { val global: SymbolTable diff --git a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala index 83d2a3453b..412b14d329 100644 --- a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala +++ b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala @@ -3,7 +3,6 @@ package reflect.internal.util import java.lang.ref.{WeakReference, ReferenceQueue} import scala.annotation.tailrec -import scala.collection.generic.Clearable import scala.collection.mutable.{Set => MSet} /** @@ -57,9 +56,9 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D /** * the limit at which we'll increase the size of the hash table */ - var threshhold = computeThreshHold + private[this] var threshold = computeThreshold - private[this] def computeThreshHold: Int = (table.size * loadFactor).ceil.toInt + private[this] def computeThreshold: Int = (table.size * loadFactor).ceil.toInt /** * find the bucket associated with an element's hash code @@ -122,7 +121,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D private[this] def resize() { val oldTable = table table = new Array[Entry[A]](oldTable.size * 2) - threshhold = computeThreshHold + threshold = computeThreshold @tailrec def tableLoop(oldBucket: Int): Unit = if (oldBucket < oldTable.size) { @@ -177,7 +176,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D def add() = { table(bucket) = new Entry(elem, hash, oldHead, queue) count += 1 - if (count > threshhold) resize() + if (count > threshold) resize() elem } @@ -207,7 +206,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D def add() { table(bucket) = new Entry(elem, hash, oldHead, queue) count += 1 - if (count > threshhold) resize() + if (count > threshold) resize() } @tailrec @@ -224,7 +223,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D def +=(elem: A) = this + elem - // from scala.reflect.interanl.Set + // from scala.reflect.internal.Set override def addEntry(x: A) { this += x } // remove an element from this set and return this set @@ -253,7 +252,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D // empty this set override def clear(): Unit = { table = new Array[Entry[A]](table.size) - threshhold = computeThreshHold + threshold = computeThreshold count = 0 // drain the queue - doesn't do anything because we're throwing away all the values anyway @@ -403,4 +402,4 @@ object WeakHashSet { val defaultLoadFactor = .75 def apply[A <: AnyRef](initialCapacity: Int = WeakHashSet.defaultInitialCapacity, loadFactor: Double = WeakHashSet.defaultLoadFactor) = new WeakHashSet[A](initialCapacity, defaultLoadFactor) -}
\ No newline at end of file +} diff --git a/src/reflect/scala/reflect/internal/util/package.scala b/src/reflect/scala/reflect/internal/util/package.scala index 3618c150ca..ec5938b902 100644 --- a/src/reflect/scala/reflect/internal/util/package.scala +++ b/src/reflect/scala/reflect/internal/util/package.scala @@ -5,7 +5,6 @@ package internal import scala.language.existentials // SI-6541 package object util { - import StringOps.longestCommonPrefix // An allocation-avoiding reusable instance of the so-common List(Nil). val ListOfNil: List[List[Nothing]] = Nil :: Nil |