diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/util')
15 files changed, 111 insertions, 733 deletions
diff --git a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala index 5c6f525c6f..f116e4af34 100644 --- a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala @@ -8,15 +8,7 @@ package util import scala.reflect.internal.Chars._ -abstract class CharArrayReader { self => - - val buf: Array[Char] - - def decodeUni: Boolean = true - - /** An error routine to call on bad unicode escapes \\uxxxx. */ - protected def error(offset: Int, msg: String): Unit - +trait CharArrayReaderData { /** the last read character */ var ch: Char = _ @@ -29,7 +21,26 @@ abstract class CharArrayReader { self => /** The start offset of the line before the current one */ var lastLineStartOffset: Int = 0 - private var lastUnicodeOffset = -1 + protected var lastUnicodeOffset = -1 + + def copyFrom(cd: CharArrayReaderData): this.type = { + this.ch = cd.ch + this.charOffset = cd.charOffset + this.lineStartOffset = cd.lineStartOffset + this.lastLineStartOffset = cd.lastLineStartOffset + this.lastUnicodeOffset = cd.lastUnicodeOffset + this + } +} + +abstract class CharArrayReader extends CharArrayReaderData { self => + + val buf: Array[Char] + + def decodeUni: Boolean = true + + /** An error routine to call on bad unicode escapes \\uxxxx. */ + protected def error(offset: Int, msg: String): Unit /** Is last character a unicode escape \\uxxxx? */ def isUnicodeEscape = charOffset == lastUnicodeOffset diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index a62c87e713..906a575d90 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -11,9 +11,9 @@ import java.net.URL import scala.collection.{ mutable, immutable } import io.{ File, Directory, Path, Jar, AbstractFile } import scala.reflect.internal.util.StringOps.splitWhere -import scala.reflect.ClassTag import Jar.isJarOrZip import File.pathSeparator +import scala.collection.convert.WrapAsScala.enumerationAsScalaIterator import java.net.MalformedURLException import java.util.regex.PatternSyntaxException import scala.reflect.runtime.ReflectionUtils @@ -30,14 +30,10 @@ object ClassPath { private def expandS(pattern: String): List[String] = { val wildSuffix = File.separator + "*" - /** Get all subdirectories, jars, zips out of a directory. */ + /* Get all subdirectories, jars, zips out of a directory. */ def lsDir(dir: Directory, filt: String => Boolean = _ => true) = dir.list filter (x => filt(x.name) && (x.isDirectory || isJarOrZip(x))) map (_.path) toList - def basedir(s: String) = - if (s contains File.separator) s.substring(0, s.lastIndexOf(File.separator)) - else "." - if (pattern == "*") lsDir(Directory(".")) else if (pattern endsWith wildSuffix) lsDir(Directory(pattern dropRight 2)) else if (pattern contains '*') { @@ -59,22 +55,6 @@ object ClassPath { /** Split the classpath, apply a transformation function, and reassemble it. */ def map(cp: String, f: String => String): String = join(split(cp) map f: _*) - /** Split the classpath, filter according to predicate, and reassemble. */ - def filter(cp: String, p: String => Boolean): String = join(split(cp) filter p: _*) - - /** Split the classpath and map them into Paths */ - def toPaths(cp: String): List[Path] = split(cp) map (x => Path(x).toAbsolute) - - /** Make all classpath components absolute. */ - def makeAbsolute(cp: String): String = fromPaths(toPaths(cp): _*) - - /** Join the paths as a classpath */ - def fromPaths(paths: Path*): String = join(paths map (_.path): _*) - def fromURLs(urls: URL*): String = fromPaths(urls map (x => Path(x.getPath)) : _*) - - /** Split the classpath and map them into URLs */ - def toURLs(cp: String): List[URL] = toPaths(cp) map (_.toURL) - /** Expand path and possibly expanding stars */ def expandPath(path: String, expandStar: Boolean = true): List[String] = if (expandStar) split(path) flatMap expandS @@ -127,31 +107,29 @@ object ClassPath { /** Creators for sub classpaths which preserve this context. */ def sourcesInPath(path: String): List[ClassPath[T]] = - for (file <- expandPath(path, false) ; dir <- Option(AbstractFile getDirectory file)) yield + for (file <- expandPath(path, expandStar = false) ; dir <- Option(AbstractFile getDirectory file)) yield new SourcePath[T](dir, this) def contentsOfDirsInPath(path: String): List[ClassPath[T]] = - for (dir <- expandPath(path, false) ; name <- expandDir(dir) ; entry <- Option(AbstractFile getDirectory name)) yield + for (dir <- expandPath(path, expandStar = false) ; name <- expandDir(dir) ; entry <- Option(AbstractFile getDirectory name)) yield newClassPath(entry) - def classesAtAllURLS(path: String): List[ClassPath[T]] = - (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]] = - classesInPathImpl(path, true).toIndexedSeq + classesInPathImpl(path, expand = true).toIndexedSeq - def classesInPath(path: String) = classesInPathImpl(path, false) + def classesInPath(path: String) = classesInPathImpl(path, expand = false) // Internal private def classesInPathImpl(path: String, expand: Boolean) = for (file <- expandPath(path, expand) ; dir <- Option(AbstractFile getDirectory file)) yield newClassPath(dir) + + def classesInManifest(used: Boolean) = + if (used) for (url <- manifests) yield newClassPath(AbstractFile getResources url) else Nil } + def manifests = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF").filter(_.getProtocol() == "jar").toList + class JavaContext extends ClassPathContext[AbstractFile] { def toBinaryName(rep: AbstractFile) = { val name = rep.name @@ -217,8 +195,7 @@ abstract class ClassPath[T] { def sourcepaths: IndexedSeq[AbstractFile] /** - * Represents classes which can be loaded with a ClassfileLoader/MsilFileLoader - * and / or a SourcefileLoader. + * Represents classes which can be loaded with a ClassfileLoader and/or SourcefileLoader. */ case class ClassRep(binary: Option[T], source: Option[AbstractFile]) { def name: String = binary match { @@ -240,7 +217,7 @@ abstract class ClassPath[T] { * Does not support nested classes on .NET */ def findClass(name: String): Option[AnyClassRep] = - splitWhere(name, _ == '.', true) match { + splitWhere(name, _ == '.', doDropIndex = true) match { case Some((pkg, rest)) => val rep = packages find (_.name == pkg) flatMap (_ findClass rest) rep map { @@ -284,7 +261,7 @@ class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends else if (f.isDirectory && validPackage(f.name)) packageBuf += new SourcePath[T](f, context) } - (packageBuf.result, classBuf.result) + (packageBuf.result(), classBuf.result()) } lazy val (packages, classes) = traverse() @@ -297,7 +274,7 @@ class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends class DirectoryClassPath(val dir: AbstractFile, val context: ClassPathContext[AbstractFile]) extends ClassPath[AbstractFile] { def name = dir.name override def origin = dir.underlyingSource map (_.path) - def asURLs = if (dir.file == null) Nil else List(dir.toURL) + def asURLs = if (dir.file == null) List(new URL(name)) else List(dir.toURL) def asClasspathString = dir.path val sourcepaths: IndexedSeq[AbstractFile] = IndexedSeq() @@ -305,13 +282,26 @@ class DirectoryClassPath(val dir: AbstractFile, val context: ClassPathContext[Ab private def traverse() = { val classBuf = immutable.Vector.newBuilder[ClassRep] val packageBuf = immutable.Vector.newBuilder[DirectoryClassPath] - dir foreach { f => - if (!f.isDirectory && validClassFile(f.name)) - classBuf += ClassRep(Some(f), None) - else if (f.isDirectory && validPackage(f.name)) - packageBuf += new DirectoryClassPath(f, context) + dir foreach { + f => + // Optimization: We assume the file was not changed since `dir` called + // `Path.apply` and categorized existent files as `Directory` + // or `File`. + val isDirectory = f match { + case pf: io.PlainFile => pf.givenPath match { + case _: io.Directory => true + case _: io.File => false + case _ => f.isDirectory + } + case _ => + f.isDirectory + } + if (!isDirectory && validClassFile(f.name)) + classBuf += ClassRep(Some(f), None) + else if (isDirectory && validPackage(f.name)) + packageBuf += new DirectoryClassPath(f, context) } - (packageBuf.result, classBuf.result) + (packageBuf.result(), classBuf.result()) } lazy val (packages, classes) = traverse() @@ -409,15 +399,3 @@ class JavaClassPath( containers: IndexedSeq[ClassPath[AbstractFile]], context: JavaContext) extends MergedClassPath[AbstractFile](containers, context) { } - -object JavaClassPath { - def fromURLs(urls: Seq[URL], context: JavaContext): JavaClassPath = { - val containers = { - for (url <- urls ; f = AbstractFile getURL url ; if f != null) yield - new DirectoryClassPath(f, context) - } - new JavaClassPath(containers.toIndexedSeq, context) - } - def fromURLs(urls: Seq[URL]): JavaClassPath = - fromURLs(urls, ClassPath.DefaultJavaContext) -} diff --git a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala b/src/compiler/scala/tools/nsc/util/CommandLineParser.scala deleted file mode 100644 index 9cf2c535df..0000000000 --- a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala +++ /dev/null @@ -1,144 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package util - -import scala.util.parsing.combinator._ -import scala.util.parsing.input.{ Reader } -import scala.util.parsing.input.CharArrayReader.EofCh -import scala.collection.mutable.ListBuffer - -/** A simple command line parser to replace the several different - * simple ones spread around trunk. - * - * XXX Note this has been completely obsolesced by scala.tools.cmd. - * I checked it back in as part of rolling partest back a month - * rather than go down the rabbit hole of unravelling dependencies. - */ - -trait ParserUtil extends Parsers { - protected implicit class ParserPlus[+T](underlying: Parser[T]) { - def !~>[U](p: => Parser[U]): Parser[U] = (underlying ~! p) ^^ { case a~b => b } - def <~![U](p: => Parser[U]): Parser[T] = (underlying ~! p) ^^ { case a~b => a } - } -} - -case class CommandLine( - args: List[String], - unaryArguments: List[String], - binaryArguments: List[String] -) { - def this(args: List[String]) = this(args, Nil, Nil) - def this(args: Array[String]) = this(args.toList, Nil, Nil) - def this(line: String) = this(CommandLineParser tokenize line, Nil, Nil) - - def withUnaryArgs(xs: List[String]) = copy(unaryArguments = xs) - def withBinaryArgs(xs: List[String]) = copy(binaryArguments = xs) - - def originalArgs = args - def assumeBinary = true - def enforceArity = true - def onlyKnownOptions = false - - val Terminator = "--" - val ValueForUnaryOption = "true" // so if --opt is given, x(--opt) = true - - def mapForUnary(opt: String) = Map(opt -> ValueForUnaryOption) - def errorFn(msg: String) = println(msg) - - /** argMap is option -> argument (or "" if it is a unary argument) - * residualArgs are what is left after removing the options and their args. - */ - lazy val (argMap, residualArgs) = { - val residualBuffer = new ListBuffer[String] - - def stripQuotes(s: String) = { - def isQuotedBy(c: Char) = s.length > 0 && s.head == c && s.last == c - if (List('"', '\'') exists isQuotedBy) s.tail.init else s - } - - def isValidOption(s: String) = !onlyKnownOptions || (unaryArguments contains s) || (binaryArguments contains s) - def isOption(s: String) = (s startsWith "-") && (isValidOption(s) || { unknownOption(s) ; false }) - def isUnary(s: String) = isOption(s) && (unaryArguments contains s) - def isBinary(s: String) = isOption(s) && !isUnary(s) && (assumeBinary || (binaryArguments contains s)) - - def unknownOption(opt: String) = - errorFn("Option '%s' not recognized.".format(opt)) - def missingArg(opt: String, what: String) = - errorFn("Option '%s' requires argument, found %s instead.".format(opt, what)) - - def loop(args: List[String]): Map[String, String] = { - def residual(xs: List[String]) = { residualBuffer ++= xs ; Map[String, String]() } - if (args.isEmpty) return Map() - val hd :: rest = args - if (rest.isEmpty) { - if (isBinary(hd) && enforceArity) - missingArg(hd, "EOF") - - if (isOption(hd)) mapForUnary(hd) else residual(args) - } - else - if (hd == Terminator) residual(rest) - else { - val hd1 :: hd2 :: rest = args - - if (hd2 == Terminator) mapForUnary(hd1) ++ residual(rest) - else if (isUnary(hd1)) mapForUnary(hd1) ++ loop(hd2 :: rest) - else if (isBinary(hd1)) { - // Disabling this check so - // --scalacopts "-verbose" works. We can't tell if it's quoted, - // the shell does us in. - // - // if (isOption(hd2) && enforceArity) - // missingArg(hd1, hd2) - - Map(hd1 -> hd2) ++ loop(rest) - } - else { residual(List(hd1)) ++ loop(hd2 :: rest) } - } - } - - (loop(args), residualBuffer map stripQuotes toList) - } - - def isSet(arg: String) = args contains arg - def get(arg: String) = argMap get arg - def getOrElse(arg: String, orElse: => String) = if (isSet(arg)) apply(arg) else orElse - def apply(arg: String) = argMap(arg) - - override def toString() = "CommandLine(\n%s)\n" format (args map (" " + _ + "\n") mkString) -} - -object CommandLineParser extends RegexParsers with ParserUtil { - override def skipWhitespace = false - - def elemExcept(xs: Elem*): Parser[Elem] = elem("elemExcept", x => x != EofCh && !(xs contains x)) - def elemOf(xs: Elem*): Parser[Elem] = elem("elemOf", xs contains _) - def escaped(ch: Char): Parser[String] = "\\" + ch - def mkQuoted(ch: Char): Parser[String] = ( - elem(ch) !~> rep(escaped(ch) | elemExcept(ch)) <~ ch ^^ (_.mkString) - | failure("Unmatched %s in input." format ch) - ) - - /** Apparently windows can't deal with the quotes sticking around. */ - lazy val squoted: Parser[String] = mkQuoted('\'') // ^^ (x => "'%s'" format x) - lazy val dquoted: Parser[String] = mkQuoted('"') // ^^ (x => "\"" + x + "\"") - lazy val token: Parser[String] = """\S+""".r - - lazy val argument: Parser[String] = squoted | dquoted | token - lazy val commandLine: Parser[List[String]] = phrase(repsep(argument, whiteSpace)) - - class ParseException(msg: String) extends RuntimeException(msg) - - def tokenize(line: String): List[String] = tokenize(line, x => throw new ParseException(x)) - def tokenize(line: String, errorFn: String => Unit): List[String] = { - parse(commandLine, line.trim) match { - case Success(args, _) => args - case NoSuccess(msg, rest) => errorFn(msg) ; Nil - } - } - def apply(line: String) = new CommandLine(tokenize(line)) -} diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala index dde53dc640..ba44126df2 100755 --- a/src/compiler/scala/tools/nsc/util/DocStrings.scala +++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala @@ -74,7 +74,7 @@ object DocStrings { else idx :: findAll(str, idx)(p) } - /** Produces a string index, which is a list of ``sections'', i.e + /** 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 an at sign and extends to the next at sign, * or to the end of the comment string, but excluding the final two diff --git a/src/compiler/scala/tools/nsc/util/Exceptional.scala b/src/compiler/scala/tools/nsc/util/Exceptional.scala index 34344263e8..1608ffa425 100644 --- a/src/compiler/scala/tools/nsc/util/Exceptional.scala +++ b/src/compiler/scala/tools/nsc/util/Exceptional.scala @@ -3,8 +3,6 @@ package util import java.util.concurrent.ExecutionException import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException } -import scala.reflect.internal.util.StringOps._ -import scala.language.implicitConversions object Exceptional { def unwrap(x: Throwable): Throwable = x match { diff --git a/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala b/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala index 5421843438..e877c990f0 100644 --- a/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala +++ b/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala @@ -14,11 +14,6 @@ trait FreshNameCreator { */ def newName(): String def newName(prefix: String): String - - @deprecated("use newName(prefix)", "2.9.0") - def newName(pos: scala.reflect.internal.util.Position, prefix: String): String = newName(prefix) - @deprecated("use newName()", "2.9.0") - def newName(pos: scala.reflect.internal.util.Position): String = newName() } object FreshNameCreator { diff --git a/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala b/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala index b7ed7903bc..58a5442465 100644 --- a/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala @@ -3,7 +3,8 @@ * @author Martin Odersky */ -package scala.tools.nsc +package scala +package tools.nsc package util import scala.reflect.internal.Chars._ @@ -14,74 +15,32 @@ class JavaCharArrayReader(buf: IndexedSeq[Char], start: Int, /* startline: int, def this(buf: IndexedSeq[Char], decodeUni: Boolean, error: String => Unit) = this(buf, 0, /* 1, 1, */ decodeUni, error) - /** produce a duplicate of this char array reader which starts reading - * at current position, independent of what happens to original reader - */ - def dup: JavaCharArrayReader = clone().asInstanceOf[JavaCharArrayReader] - - /** layout constant - */ - val tabinc = 8 - /** the line and column position of the current character */ var ch: Char = _ var bp = start - var oldBp = -1 - var oldCh: Char = _ - - //private var cline: Int = _ - //private var ccol: Int = _ def cpos = bp var isUnicode: Boolean = _ - var lastLineStartPos: Int = 0 - var lineStartPos: Int = 0 - var lastBlankLinePos: Int = 0 - - private var onlyBlankChars = false - //private var nextline = startline - //private var nextcol = startcol - - private def markNewLine() { - lastLineStartPos = lineStartPos - if (onlyBlankChars) lastBlankLinePos = lineStartPos - lineStartPos = bp - onlyBlankChars = true - //nextline += 1 - //nextcol = 1 - } - - def hasNext: Boolean = if (bp < buf.length) true - else { - false - } - def last: Char = if (bp > start + 2) buf(bp - 2) else ' ' // XML literals + def hasNext = bp < buf.length def next(): Char = { - //cline = nextline - //ccol = nextcol val buf = this.buf.asInstanceOf[collection.mutable.WrappedArray[Char]].array if(!hasNext) { ch = SU return SU // there is an endless stream of SU's at the end } - oldBp = bp - oldCh = ch ch = buf(bp) isUnicode = false bp = bp + 1 ch match { case '\t' => - // nextcol = ((nextcol - 1) / tabinc * tabinc) + tabinc + 1; case CR => - if (bp < buf.size && buf(bp) == LF) { + if (bp < buf.length && buf(bp) == LF) { ch = LF bp += 1 } - markNewLine() case LF | FF => - markNewLine() case '\\' => def evenSlashPrefix: Boolean = { var p = bp - 2 @@ -90,34 +49,23 @@ class JavaCharArrayReader(buf: IndexedSeq[Char], start: Int, /* startline: int, } def udigit: Int = { val d = digit2int(buf(bp), 16) - if (d >= 0) { bp += 1; /* nextcol = nextcol + 1 */ } - else error("error in unicode escape"); + if (d >= 0) bp += 1 + else error("error in unicode escape") d } - // nextcol += 1 if (buf(bp) == 'u' && decodeUni && evenSlashPrefix) { do { bp += 1 //; nextcol += 1 - } while (buf(bp) == 'u'); + } while (buf(bp) == 'u') val code = udigit << 12 | udigit << 8 | udigit << 4 | udigit ch = code.asInstanceOf[Char] isUnicode = true } case _ => - if (ch > ' ') onlyBlankChars = false - // nextcol += 1 } ch } - def rewind() { - if (oldBp == -1) throw new IllegalArgumentException - bp = oldBp - ch = oldCh - oldBp = -1 - oldCh = 'x' - } - def copy: JavaCharArrayReader = new JavaCharArrayReader(buf, bp, /* nextcol, nextline, */ decodeUni, error) } diff --git a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala deleted file mode 100644 index 77a19d3ead..0000000000 --- a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala +++ /dev/null @@ -1,170 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2006-2013 LAMP/EPFL - * @author Martin Odersky - */ - -// $Id$ - -package scala.tools.nsc -package util - -import java.io.File -import java.net.URL -import java.util.StringTokenizer -import scala.util.Sorting -import scala.collection.mutable -import scala.tools.nsc.io.{ AbstractFile, MsilFile } -import ch.epfl.lamp.compiler.msil.{ Type => MSILType, Assembly } -import ClassPath.ClassPathContext -import scala.reflect.runtime.ReflectionUtils.isTraitImplementation - -/** Keeping the MSIL classpath code in its own file is important to make sure - * we don't accidentally introduce a dependency on msil.jar in the jvm. - */ - -object MsilClassPath { - def collectTypes(assemFile: AbstractFile) = { - var res: Array[MSILType] = MSILType.EmptyTypes - val assem = Assembly.LoadFrom(assemFile.path) - if (assem != null) { - // DeclaringType == null: true for non-inner classes - res = assem.GetTypes() filter (_.DeclaringType == null) - Sorting.stableSort(res, (t1: MSILType, t2: MSILType) => (t1.FullName compareTo t2.FullName) < 0) - } - res - } - - /** On the java side this logic is in PathResolver, but as I'm not really - * up to folding MSIL into that, I am encapsulating it here. - */ - def fromSettings(settings: Settings): MsilClassPath = { - val context = - if (settings.inline.value) new MsilContext - else new MsilContext { override def isValidName(name: String) = !isTraitImplementation(name) } - - import settings._ - new MsilClassPath(assemextdirs.value, assemrefs.value, sourcepath.value, context) - } - - class MsilContext extends ClassPathContext[MsilFile] { - def toBinaryName(rep: MsilFile) = rep.msilType.Name - def newClassPath(assemFile: AbstractFile) = new AssemblyClassPath(MsilClassPath collectTypes assemFile, "", this) - } - - private def assembleEntries(ext: String, user: String, source: String, context: MsilContext): List[ClassPath[MsilFile]] = { - import ClassPath._ - val etr = new mutable.ListBuffer[ClassPath[MsilFile]] - val names = new mutable.HashSet[String] - - // 1. Assemblies from -Xassem-extdirs - for (dirName <- expandPath(ext, expandStar = false)) { - val dir = AbstractFile.getDirectory(dirName) - if (dir ne null) { - for (file <- dir) { - val name = file.name.toLowerCase - if (name.endsWith(".dll") || name.endsWith(".exe")) { - names += name - etr += context.newClassPath(file) - } - } - } - } - - // 2. Assemblies from -Xassem-path - for (fileName <- expandPath(user, expandStar = false)) { - val file = AbstractFile.getFile(fileName) - if (file ne null) { - val name = file.name.toLowerCase - if (name.endsWith(".dll") || name.endsWith(".exe")) { - names += name - etr += context.newClassPath(file) - } - } - } - - def check(n: String) { - if (!names.contains(n)) - throw new AssertionError("Cannot find assembly "+ n + - ". Use -Xassem-extdirs or -Xassem-path to specify its location") - } - check("mscorlib.dll") - check("scalaruntime.dll") - - // 3. Source path - for (dirName <- expandPath(source, expandStar = false)) { - val file = AbstractFile.getDirectory(dirName) - if (file ne null) etr += new SourcePath[MsilFile](file, context) - } - - etr.toList - } -} -import MsilClassPath._ - -/** - * A assembly file (dll / exe) containing classes and namespaces - */ -class AssemblyClassPath(types: Array[MSILType], namespace: String, val context: MsilContext) extends ClassPath[MsilFile] { - def name = { - val i = namespace.lastIndexOf('.') - if (i < 0) namespace - else namespace drop (i + 1) - } - def asURLs = List(new java.net.URL(name)) - def asClasspathString = sys.error("Unknown") // I don't know what if anything makes sense here? - - private lazy val first: Int = { - var m = 0 - var n = types.length - 1 - while (m < n) { - val l = (m + n) / 2 - val res = types(l).FullName.compareTo(namespace) - if (res < 0) m = l + 1 - else n = l - } - if (types(m).FullName.startsWith(namespace)) m else types.length - } - - lazy val classes = { - val cls = new mutable.ListBuffer[ClassRep] - var i = first - while (i < types.length && types(i).Namespace.startsWith(namespace)) { - // CLRTypes used to exclude java.lang.Object and java.lang.String (no idea why..) - if (types(i).Namespace == namespace) - cls += ClassRep(Some(new MsilFile(types(i))), None) - i += 1 - } - cls.toIndexedSeq - } - - lazy val packages = { - val nsSet = new mutable.HashSet[String] - var i = first - while (i < types.length && types(i).Namespace.startsWith(namespace)) { - val subns = types(i).Namespace - if (subns.length > namespace.length) { - // example: namespace = "System", subns = "System.Reflection.Emit" - // => find second "." and "System.Reflection" to nsSet. - val end = subns.indexOf('.', namespace.length + 1) - nsSet += (if (end < 0) subns - else subns.substring(0, end)) - } - i += 1 - } - val xs = for (ns <- nsSet.toList) - yield new AssemblyClassPath(types, ns, context) - - xs.toIndexedSeq - } - - val sourcepaths: IndexedSeq[AbstractFile] = IndexedSeq() - - override def toString() = "assembly classpath "+ namespace -} - -/** - * The classpath when compiling with target:msil. Binary files are represented as - * MSILType values. - */ -class MsilClassPath(ext: String, user: String, source: String, context: MsilContext) -extends MergedClassPath[MsilFile](MsilClassPath.assembleEntries(ext, user, source, context), context) { }
\ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/util/MultiHashMap.scala b/src/compiler/scala/tools/nsc/util/MultiHashMap.scala deleted file mode 100644 index 67987c6e52..0000000000 --- a/src/compiler/scala/tools/nsc/util/MultiHashMap.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tools.nsc.util - -import scala.collection.{ mutable, immutable } - -/** A hashmap with set-valued values, and an empty set as default value - */ -class MultiHashMap[K, V] extends mutable.HashMap[K, immutable.Set[V]] { - override def default(key: K): immutable.Set[V] = Set() -} diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala deleted file mode 100644 index 1f6fa68f57..0000000000 --- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala +++ /dev/null @@ -1,168 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package util - -import java.lang.{ ClassLoader => JClassLoader } -import java.lang.reflect.{ Constructor, Modifier, Method } -import java.io.{ File => JFile } -import java.net.{ URLClassLoader => JURLClassLoader } -import java.net.URL -import scala.reflect.runtime.ReflectionUtils.unwrapHandler -import ScalaClassLoader._ -import scala.util.control.Exception.{ catching } -import scala.language.implicitConversions -import scala.reflect.{ ClassTag, classTag } - -trait HasClassPath { - def classPathURLs: Seq[URL] -} - -/** A wrapper around java.lang.ClassLoader to lower the annoyance - * of java reflection. - */ -trait ScalaClassLoader extends JClassLoader { - /** Executing an action with this classloader as context classloader */ - def asContext[T](action: => T): T = { - val saved = contextLoader - try { setContext(this) ; action } - finally setContext(saved) - } - def setAsContext() { setContext(this) } - - /** Load and link a class with this classloader */ - def tryToLoadClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, false) - /** Load, link and initialize a class with this classloader */ - def tryToInitializeClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, true) - - private def tryClass[T <: AnyRef](path: String, initialize: Boolean): Option[Class[T]] = - catching(classOf[ClassNotFoundException], classOf[SecurityException]) opt - Class.forName(path, initialize, this).asInstanceOf[Class[T]] - - /** Create an instance of a class with this classloader */ - def create(path: String): AnyRef = - tryToInitializeClass[AnyRef](path) map (_.newInstance()) orNull - - def constructorsOf[T <: AnyRef : ClassTag]: List[Constructor[T]] = - classTag[T].runtimeClass.getConstructors.toList map (_.asInstanceOf[Constructor[T]]) - - /** 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() - case stream => io.Streamable.bytes(stream) - } - - /** An InputStream representing the given class name, or null if not found. */ - def classAsStream(className: String) = - getResourceAsStream(className.replaceAll("""\.""", "/") + ".class") - - /** Run the main method of a class to be loaded by this classloader */ - def run(objectName: String, arguments: Seq[String]) { - val clsToRun = tryToInitializeClass(objectName) getOrElse ( - throw new ClassNotFoundException(objectName) - ) - val method = clsToRun.getMethod("main", classOf[Array[String]]) - if (!Modifier.isStatic(method.getModifiers)) - throw new NoSuchMethodException(objectName + ".main is not static") - - try asContext(method.invoke(null, Array(arguments.toArray: AnyRef): _*)) // !!! : AnyRef shouldn't be necessary - catch unwrapHandler({ case ex => throw ex }) - } - - /** A list comprised of this classloader followed by all its - * (non-null) parent classloaders, if any. - */ - def loaderChain: List[ScalaClassLoader] = this :: (getParent match { - case null => Nil - case p => p.loaderChain - }) -} - -/** Methods for obtaining various classloaders. - * appLoader: the application classloader. (Also called the java system classloader.) - * extLoader: the extension classloader. - * bootLoader: the boot classloader. - * contextLoader: the context classloader. - */ -object ScalaClassLoader { - /** Returns loaders which are already ScalaClassLoaders unaltered, - * and translates java.net.URLClassLoaders into scala URLClassLoaders. - * Otherwise creates a new wrapper. - */ - implicit def apply(cl: JClassLoader): ScalaClassLoader = cl match { - case cl: ScalaClassLoader => cl - case cl: JURLClassLoader => new URLClassLoader(cl.getURLs.toSeq, cl.getParent) - case _ => new JClassLoader(cl) with ScalaClassLoader - } - def contextLoader = apply(Thread.currentThread.getContextClassLoader) - def appLoader = apply(JClassLoader.getSystemClassLoader) - def extLoader = apply(appLoader.getParent) - def bootLoader = apply(null) - def contextChain = loaderChain(contextLoader) - - def pathToErasure[T: ClassTag] = pathToClass(classTag[T].runtimeClass) - def pathToClass(clazz: Class[_]) = clazz.getName.replace('.', JFile.separatorChar) + ".class" - def locate[T: ClassTag] = contextLoader getResource pathToErasure[T] - - /** Tries to guess the classpath by type matching the context classloader - * and its parents, looking for any classloaders which will reveal their - * classpath elements as urls. It it can't find any, creates a classpath - * from the supplied string. - */ - def guessClassPathString(default: String = ""): String = { - val classpathURLs = contextChain flatMap { - case x: HasClassPath => x.classPathURLs - case x: JURLClassLoader => x.getURLs.toSeq - case _ => Nil - } - if (classpathURLs.isEmpty) default - else JavaClassPath.fromURLs(classpathURLs).asClasspathString - } - - def loaderChain(head: JClassLoader) = { - def loop(cl: JClassLoader): List[JClassLoader] = - if (cl == null) Nil else cl :: loop(cl.getParent) - - loop(head) - } - def setContext(cl: JClassLoader) = - Thread.currentThread.setContextClassLoader(cl) - def savingContextLoader[T](body: => T): T = { - val saved = contextLoader - try body - finally setContext(saved) - } - - class URLClassLoader(urls: Seq[URL], parent: JClassLoader) - extends JURLClassLoader(urls.toArray, parent) - with ScalaClassLoader - with HasClassPath { - - private var classloaderURLs: Seq[URL] = urls - private def classpathString = ClassPath.fromURLs(urls: _*) - def classPathURLs: Seq[URL] = classloaderURLs - def classPath: ClassPath[_] = JavaClassPath fromURLs classPathURLs - - /** Override to widen to public */ - override def addURL(url: URL) = { - classloaderURLs :+= url - super.addURL(url) - } - def toLongString = urls.mkString("URLClassLoader(\n ", "\n ", "\n)\n") - } - - def fromURLs(urls: Seq[URL], parent: ClassLoader = null): URLClassLoader = - new URLClassLoader(urls, parent) - - /** True if supplied class exists in supplied path */ - def classExists(urls: Seq[URL], name: String): Boolean = - fromURLs(urls) tryToLoadClass name isDefined - - /** Finding what jar a clazz or instance came from */ - def origin(x: Any): Option[URL] = originOfClass(x.getClass) - def originOfClass(x: Class[_]): Option[URL] = - Option(x.getProtectionDomain.getCodeSource) flatMap (x => Option(x.getLocation)) -} diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala index 2b87280c24..b804bfb842 100644 --- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala +++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala @@ -3,17 +3,17 @@ * @author Martin Odersky */ -package scala.tools +package scala +package tools package nsc package util -import java.io.{File, FileInputStream, PrintStream} +import java.io.PrintStream import java.lang.Long.toHexString import java.lang.Float.intBitsToFloat import java.lang.Double.longBitsToDouble import scala.reflect.internal.{Flags, Names} import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } -import interpreter.ByteCode.scalaSigBytesForPath object ShowPickled extends Names { import PickleFormat._ @@ -94,7 +94,6 @@ object ShowPickled extends Names { case ANNOTATEDtpe => "ANNOTATEDtpe" case ANNOTINFO => "ANNOTINFO" case ANNOTARGARRAY => "ANNOTARGARRAY" - // case DEBRUIJNINDEXtpe => "DEBRUIJNINDEXtpe" case EXISTENTIALtpe => "EXISTENTIALtpe" case TREE => "TREE" case MODIFIERS => "MODIFIERS" @@ -109,7 +108,7 @@ object ShowPickled extends Names { var result = 0L var b = 0L do { - b = data(idx) + b = data(idx).toLong idx += 1 result = (result << 7) + (b & 0x7f) } while((b & 0x80) != 0L) @@ -165,7 +164,7 @@ object ShowPickled extends Names { out.print(" %s[%s]".format(toHexString(pflags), flagString)) } - /** Might be info or privateWithin */ + /* Might be info or privateWithin */ val x = buf.readNat() if (buf.readIndex == end) { printFlags(None) @@ -177,9 +176,9 @@ object ShowPickled extends Names { } } - /** Note: the entries which require some semantic analysis to be correctly - * interpreted are for the most part going to tell you the wrong thing. - * It's not so easy to duplicate the logic applied in the UnPickler. + /* Note: the entries which require some semantic analysis to be correctly + * interpreted are for the most part going to tell you the wrong thing. + * It's not so easy to duplicate the logic applied in the UnPickler. */ def printEntry(i: Int) { buf.readIndex = index(i) @@ -251,7 +250,7 @@ object ShowPickled extends Names { case SYMANNOT => printSymbolRef(); printTypeRef(); buf.until(end, printAnnotArgRef) case ANNOTATEDtpe => - printTypeRef(); buf.until(end, printAnnotInfoRef); + printTypeRef(); buf.until(end, printAnnotInfoRef) case ANNOTINFO => printTypeRef(); buf.until(end, printAnnotArgRef) case ANNOTARGARRAY => @@ -272,8 +271,7 @@ object ShowPickled extends Names { for (i <- 0 until index.length) printEntry(i) } - def fromFile(path: String) = fromBytes(io.File(path).toByteArray) - def fromName(name: String) = fromBytes(scalaSigBytesForPath(name) getOrElse Array()) + def fromFile(path: String) = fromBytes(io.File(path).toByteArray()) def fromBytes(data: => Array[Byte]): Option[PickleBuffer] = try Some(new PickleBuffer(data, 0, data.length)) catch { case _: Exception => None } @@ -288,7 +286,7 @@ object ShowPickled extends Names { def main(args: Array[String]) { args foreach { arg => - (fromFile(arg) orElse fromName(arg)) match { + fromFile(arg) match { case Some(pb) => show(arg + ":", pb) case _ => Console.println("Cannot read " + arg) } diff --git a/src/compiler/scala/tools/nsc/util/SimpleTracer.scala b/src/compiler/scala/tools/nsc/util/SimpleTracer.scala index 2601798b96..4e1cf02a6e 100644 --- a/src/compiler/scala/tools/nsc/util/SimpleTracer.scala +++ b/src/compiler/scala/tools/nsc/util/SimpleTracer.scala @@ -6,7 +6,7 @@ package util import java.io.PrintStream /** A simple tracer - * @param out: The print stream where trace info shoul be sent + * @param out: The print stream where trace info should be sent * @param enabled: A condition that must be true for trace info to be produced. */ class SimpleTracer(out: PrintStream, enabled: Boolean = true) { @@ -14,6 +14,5 @@ class SimpleTracer(out: PrintStream, enabled: Boolean = true) { if (enabled) out.println(msg+value) value } - def withOutput(out: PrintStream) = new SimpleTracer(out, enabled) def when(enabled: Boolean): SimpleTracer = new SimpleTracer(out, enabled) } diff --git a/src/compiler/scala/tools/nsc/util/TreeSet.scala b/src/compiler/scala/tools/nsc/util/TreeSet.scala deleted file mode 100644 index d2e9238e8f..0000000000 --- a/src/compiler/scala/tools/nsc/util/TreeSet.scala +++ /dev/null @@ -1,64 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.tools.nsc -package util - -/** Sets implemented as binary trees. - * - * @author Martin Odersky - * @version 1.0 - */ -class TreeSet[T >: Null <: AnyRef](less: (T, T) => Boolean) extends Set[T] { - - private class Tree(val elem: T) { - var l: Tree = null - var r: Tree = null - } - - private var tree: Tree = null - - def findEntry(x: T): T = { - def find(t: Tree): T = { - if (t eq null) null - else if (less(x, t.elem)) find(t.l) - else if (less(t.elem, x)) find(t.r) - else t.elem - } - find(tree) - } - - def addEntry(x: T) { - def add(t: Tree): Tree = { - if (t eq null) new Tree(x) - else if (less(x, t.elem)) { t.l = add(t.l); t } - else if (less(t.elem, x)) { t.r = add(t.r); t } - else t - } - tree = add(tree) - } - - def iterator = toList.iterator - - override def foreach[U](f: T => U) { - def loop(t: Tree) { - if (t ne null) { - loop(t.l) - f(t.elem) - loop(t.r) - } - } - loop(tree) - } - override def toList = { - val xs = scala.collection.mutable.ListBuffer[T]() - foreach(xs += _) - xs.toList - } - - override def toString(): String = { - if (tree eq null) "<empty>" else "(..." + tree.elem + "...)" - } -} diff --git a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala index b1f4696d3e..4f7a9ff878 100644 --- a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala +++ b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala @@ -7,9 +7,9 @@ class WorkScheduler { type Action = () => Unit - private var todo = new mutable.Queue[Action] - private var throwables = new mutable.Queue[Throwable] - private var interruptReqs = new mutable.Queue[InterruptReq] + private val todo = new mutable.Queue[Action] + private val throwables = new mutable.Queue[Throwable] + private val interruptReqs = new mutable.Queue[InterruptReq] /** Called from server: block until one of todo list, throwables or interruptReqs is nonempty */ def waitForMoreWork() = synchronized { diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala index d34d4ee092..ea3c9d8dde 100644 --- a/src/compiler/scala/tools/nsc/util/package.scala +++ b/src/compiler/scala/tools/nsc/util/package.scala @@ -3,9 +3,12 @@ * @author Paul Phillips */ -package scala.tools.nsc +package scala +package tools +package nsc import java.io.{ OutputStream, PrintStream, ByteArrayOutputStream, PrintWriter, StringWriter } +import scala.compat.Platform.EOL package object util { @@ -18,16 +21,9 @@ package object util { type HashSet[T >: Null <: AnyRef] = scala.reflect.internal.util.HashSet[T] val HashSet = scala.reflect.internal.util.HashSet - def onull[T](value: T, orElse: => T): T = if (value == null) orElse else value - /** Apply a function and return the passed value */ def returning[T](x: T)(f: T => Unit): T = { f(x) ; x } - /** Frequency counter */ - def freq[T](xs: Traversable[T]): Map[T, Int] = xs groupBy identity mapValues (_.size) - - def freqrank[T](xs: Traversable[(T, Int)]): List[(Int, T)] = xs.toList map (_.swap) sortBy (-_._1) - /** Execute code and then wait for all non-daemon Threads * created and begun during its execution to complete. */ @@ -54,18 +50,6 @@ package object util { (result, ts2 filterNot (ts1 contains _)) } - /** Given a function and a block of code, evaluates code block, - * calls function with milliseconds elapsed, and returns block result. - */ - def millisElapsedTo[T](f: Long => Unit)(body: => T): T = { - val start = System.currentTimeMillis - val result = body - val end = System.currentTimeMillis - - f(end - start) - result - } - /** Generate a string using a routine that wants to write on a stream. */ def stringFromWriter(writer: PrintWriter => Unit): String = { val stringWriter = new StringWriter() @@ -83,8 +67,27 @@ package object util { } def stackTraceString(ex: Throwable): String = stringFromWriter(ex printStackTrace _) + /** A one line string which contains the class of the exception, the + * message if any, and the first non-Predef location in the stack trace + * (to exclude assert, require, etc.) + */ + def stackTraceHeadString(ex: Throwable): String = { + val frame = ex.getStackTrace.dropWhile(_.getClassName contains "Predef") take 1 mkString "" + val msg = ex.getMessage match { case null | "" => "" ; case s => s"""("$s")""" } + val clazz = ex.getClass.getName.split('.').last + + s"$clazz$msg @ $frame" + } + + def stackTracePrefixString(ex: Throwable)(p: StackTraceElement => Boolean): String = { + val frames = ex.getStackTrace takeWhile p map (" at " + _) + val msg = ex.getMessage match { case null => "" ; case s => s": $s" } + val clazz = ex.getClass.getName + + s"$clazz$msg" +: frames mkString EOL + } + lazy val trace = new SimpleTracer(System.out) - lazy val errtrace = new SimpleTracer(System.err) @deprecated("Moved to scala.reflect.internal.util.StringOps", "2.10.0") val StringOps = scala.reflect.internal.util.StringOps @@ -92,12 +95,6 @@ package object util { @deprecated("Moved to scala.reflect.internal.util.StringOps", "2.10.0") type StringOps = scala.reflect.internal.util.StringOps - @deprecated("Moved to scala.reflect.internal.util.TableDef", "2.10.0") - val TableDef = scala.reflect.internal.util.TableDef - - @deprecated("Moved to scala.reflect.internal.util.TableDef", "2.10.0") - type TableDef[T] = scala.reflect.internal.util.TableDef[T] - @deprecated("scala.reflect.internal.util.WeakHashSet", "2.10.0") type WeakHashSet[T <: AnyRef] = scala.reflect.internal.util.WeakHashSet[T] @@ -139,4 +136,13 @@ package object util { @deprecated("Moved to scala.reflect.internal.util.BatchSourceFile", "2.10.0") type BatchSourceFile = scala.reflect.internal.util.BatchSourceFile + + @deprecated("Moved to scala.reflect.internal.util.AbstractFileClassLoader", "2.11.0") + type AbstractFileClassLoader = scala.reflect.internal.util.AbstractFileClassLoader + + @deprecated("Moved to scala.reflect.internal.util.ScalaClassLoader", "2.11.0") + val ScalaClassLoader = scala.reflect.internal.util.ScalaClassLoader + + @deprecated("Moved to scala.reflect.internal.util.ScalaClassLoader", "2.11.0") + type ScalaClassLoader = scala.reflect.internal.util.ScalaClassLoader } |