summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSean McDirmid <sean.mcdirmid@gmail.com>2007-03-28 10:44:12 +0000
committerSean McDirmid <sean.mcdirmid@gmail.com>2007-03-28 10:44:12 +0000
commit806238432588319e91805570ffbfc2f0ce5f409b (patch)
tree2722f8826abe3bd63fd8053854e674620e78f131 /src
parenta4d94d427ae80d191060338b230c4d88948059cb (diff)
downloadscala-806238432588319e91805570ffbfc2f0ce5f409b.tar.gz
scala-806238432588319e91805570ffbfc2f0ce5f409b.tar.bz2
scala-806238432588319e91805570ffbfc2f0ce5f409b.zip
Revamped scala-doc.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala6
-rw-r--r--src/compiler/scala/tools/nsc/Main.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocGenerator.scala5
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocUtil.scala28
-rw-r--r--src/compiler/scala/tools/nsc/io/PlainFile.scala20
-rw-r--r--src/compiler/scala/tools/nsc/io/ZipArchive.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTable.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala21
-rw-r--r--src/library/scala/Iterable.scala18
-rw-r--r--src/library/scala/List.scala25
-rw-r--r--src/library/scala/PartialFunction.scala5
-rw-r--r--src/library/scala/Seq.scala31
-rw-r--r--src/library/scala/Symbol.scala14
-rw-r--r--src/library/scala/collection/Map.scala2
-rw-r--r--src/library/scala/collection/Set.scala9
-rw-r--r--src/library/scala/collection/Sorted.scala4
-rw-r--r--src/library/scala/collection/jcl/MutableIterable.scala4
-rw-r--r--src/library/scala/collection/mutable/Set.scala25
22 files changed, 174 insertions, 86 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index e9c23b27e5..8743a4d73e 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -105,6 +105,9 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val comments =
if (onlyPresentation) new HashMap[Symbol,String]
else null
+ val methodArgumentNames =
+ if (onlyPresentation) new HashMap[Symbol,List[List[Symbol]]];
+ else null;
// reporting -------------------------------------------------------
@@ -642,6 +645,9 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
def forCLDC: Boolean = settings.target.value == "cldc"
def forMSIL: Boolean = settings.target.value == "msil"
def onlyPresentation = settings.doc.value
+ // used to disable caching in lampion IDE.
+ def inIDE = false
+
// position stuff
final val positionConfiguration: PositionConfiguration = initConfig;
protected def initConfig : PositionConfiguration = posConfig;
diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala
index 82a0026c24..089a0f7d23 100644
--- a/src/compiler/scala/tools/nsc/Main.scala
+++ b/src/compiler/scala/tools/nsc/Main.scala
@@ -6,7 +6,7 @@
package scala.tools.nsc
-import scala.tools.nsc.doc.DocGenerator
+import scala.tools.nsc.doc.{DocDriver => DocGenerator}
import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
import scala.tools.nsc.util.FakePos //{Position}
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 3d9ed750e4..a2da40d399 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -441,7 +441,7 @@ trait Trees requires Global {
vparamss map (.map (vd => {
val ret = ValDef(Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.annotations,
vd.name, vd.tpt.duplicate, EmptyTree).setPos(vd.pos)
- if (false/*inIDE*/ && vd.symbol != NoSymbol)
+ if (inIDE && vd.symbol != NoSymbol)
ret.symbol = vd.symbol
ret
}));
diff --git a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
index 41e83f8383..5ca3b6a323 100644
--- a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
@@ -214,8 +214,8 @@ abstract class DocGenerator extends Models {
</div>;
abstract class ListModuleFrame extends Frame {
- val path = "modules"
- val title = "List of all packages"
+ override val path = "modules"
+ override val title = "List of all packages"
def modules: TreeMap[String, ModuleClassSymbol]
def body: NodeSeq =
<div>
@@ -303,7 +303,6 @@ abstract class DocGenerator extends Models {
}
abstract class ContentFrame0 extends Frame {
-
private def extendsFor(mmbr: HasTree): NodeSeq = mmbr match {
case mmbr: ImplMod =>
val parents = mmbr.treey.impl.parents
diff --git a/src/compiler/scala/tools/nsc/doc/DocUtil.scala b/src/compiler/scala/tools/nsc/doc/DocUtil.scala
index 95f05605eb..34844c1367 100644
--- a/src/compiler/scala/tools/nsc/doc/DocUtil.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocUtil.scala
@@ -38,7 +38,12 @@ object DocUtil {
def relative: String
def aref(href0: String, target: String, text: String): NodeSeq = {
- val href = relative + Utility.escape(href0)
+ if (href0 == null) return Text(text);
+
+ val href = {
+ if (href0.startsWith("http:") || href0.startsWith("file:")) "";
+ else relative
+ } + Utility.escape(href0)
if ((target ne null) && target.indexOf('<') != -1) throw new Error(target)
val t0 = Text(text)
@@ -90,5 +95,26 @@ object DocUtil {
}
ts
}
+ implicit def coerceIterable[T](list : Iterable[T]) = NodeWrapper(list.elements);
+ implicit def coerceIterator[T](list : Iterator[T]) = NodeWrapper(list);
+ case class NodeWrapper[T](list : Iterator[T]) {
+ def mkXML(begin : NodeSeq, separator : NodeSeq, end : NodeSeq)(f : T => NodeSeq) : NodeSeq = {
+ var seq : NodeSeq = begin;
+ val i = list;
+ while (i.hasNext) {
+ seq = seq ++ f(i.next);
+ if (i.hasNext) seq = seq ++ separator;
+ }
+ seq ++ end;
+ }
+
+ def mkXML(begin : String, separator : String, end : String)(f : T => NodeSeq) : NodeSeq = {
+ this.mkXML(Text(begin),Text(separator),Text(end))(f);
+ }
+ def surround(open : String, close : String)(f : T => NodeSeq) = {
+ if (list.hasNext) mkXML(open, ", ", close)(f);
+ else NodeSeq.Empty;
+ }
+ }
}
diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala
index c863a30e68..cff9fac410 100644
--- a/src/compiler/scala/tools/nsc/io/PlainFile.scala
+++ b/src/compiler/scala/tools/nsc/io/PlainFile.scala
@@ -10,10 +10,6 @@ package scala.tools.nsc.io
import java.io.{File, FileInputStream, IOException}
object PlainFile {
-
- /** Returns "fromFile(new File(path))". */
- //def fromPath(path: String): AbstractFile = fromFile(new File(path));
-
/**
* If the specified File exists, returns an abstract file backed
* by it. Otherwise, returns null.
@@ -26,6 +22,8 @@ object PlainFile {
/** This class implements an abstract file backed by a File.
*/
class PlainFile(val file: File) extends AbstractFile {
+ private val fpath = try { file.getCanonicalPath }
+ catch { case _: IOException => file.getAbsolutePath }
assert(file ne null)
assert(file.exists(), "non-existent file: " + file)
@@ -43,19 +41,11 @@ class PlainFile(val file: File) extends AbstractFile {
override def size = Some(file.length.toInt)
- override def hashCode(): Int =
- try { file.getCanonicalPath().hashCode() }
- catch { case _: IOException => 0 }
+ override def hashCode(): Int = fpath.hashCode
override def equals(that: Any): Boolean =
- try {
- that.isInstanceOf[PlainFile] &&
- file.getCanonicalPath().equals(that.asInstanceOf[PlainFile].file.getCanonicalPath());
- } catch {
- case _: IOException =>
- that.isInstanceOf[PlainFile] &&
- file.getAbsolutePath().equals(that.asInstanceOf[PlainFile].file.getAbsolutePath());
- }
+ that.isInstanceOf[PlainFile] &&
+ fpath.equals(that.asInstanceOf[PlainFile].fpath)
/** Is this abstract file a directory? */
def isDirectory: Boolean = file.isDirectory()
diff --git a/src/compiler/scala/tools/nsc/io/ZipArchive.scala b/src/compiler/scala/tools/nsc/io/ZipArchive.scala
index 4f2482c112..e5c144db08 100644
--- a/src/compiler/scala/tools/nsc/io/ZipArchive.scala
+++ b/src/compiler/scala/tools/nsc/io/ZipArchive.scala
@@ -181,13 +181,10 @@ final class ZipArchive(file: File, val archive: ZipFile) extends PlainFile(file)
/** A regular file archive entry */
final class FileEntry(name: String, path: String, val entry: ZipEntry)
- extends Entry(name, path)
- {
-
+ extends Entry(name, path) {
+ def archive = ZipArchive.this.archive;
override def lastModified: Long = entry.getTime()
-
override def read = archive.getInputStream(entry);
-
override def size = Some(entry.getSize().toInt)
}
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
index 60c795920e..c68d2dfee3 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
@@ -25,6 +25,8 @@ abstract class SymbolTable extends Names
/** Are we compiling for .NET*/
def forMSIL: Boolean
+ /** are we in a lampion presentation compiler? then disable caching. */
+ def inIDE : Boolean;
/** A period is an ordinal number for a phase in a run.
* Phases in later runs have higher periods than phases in earlier runs.
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 7011f7d809..31d28b79db 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -791,7 +791,7 @@ trait Symbols requires SymbolTable {
matchingSymbol(ofclazz, ofclazz.thisType)
final def allOverriddenSymbols: List[Symbol] =
- if (owner.isClass)
+ if (owner.isClass && !owner.info.baseClasses.isEmpty)
for { val bc <- owner.info.baseClasses.tail
val s = overriddenSymbol(bc)
s != NoSymbol } yield s
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 9e30b254aa..024d71b7e8 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -421,6 +421,7 @@ trait Types requires SymbolTable {
*/
//TODO: use narrow only for modules? (correct? efficiency gain?)
def findMember(name: Name, excludedFlags: int, requiredFlags: long, stableOnly: boolean): Symbol = {
+ if (inIDE) trackTypeIDE(symbol)
if (util.Statistics.enabled) findMemberCount = findMemberCount + 1
val startTime = if (util.Statistics.enabled) currentTime else 0l
@@ -628,6 +629,7 @@ trait Types requires SymbolTable {
private var singleDerefCache: Type = _
private var singleDerefPeriod = NoPeriod
override def singleDeref: Type = {
+ if (inIDE) return pre.memberType(sym).resultType
val period = singleDerefPeriod
if (period != currentPeriod) {
singleDerefPeriod = currentPeriod
@@ -783,6 +785,7 @@ trait Types requires SymbolTable {
override def closureDepth: int = { closure; closureDepthCache }
override def baseClasses: List[Symbol] = {
+ if (inIDE) trackTypeIDE(symbol)
def computeBaseClasses: List[Symbol] =
if (parents.isEmpty) List(symbol)
else {
@@ -831,11 +834,15 @@ trait Types requires SymbolTable {
}
override def baseType(sym: Symbol): Type = {
+ if (inIDE) { trackTypeIDE(sym); trackTypeIDE(symbol); }
val index = closurePos(sym)
if (index >= 0) closure(index) else NoType
}
- override def narrow: Type = symbol.thisType
+ override def narrow: Type = {
+ if (inIDE) trackTypeIDE(symbol)
+ symbol.thisType
+ }
// override def isNonNull: boolean = parents forall (.isNonNull);
@@ -1798,6 +1805,7 @@ trait Types requires SymbolTable {
def apply(tp: Type): Type = {
def subst(sym: Symbol, from: List[Symbol], to: List[T]): Type =
if (from.isEmpty) tp
+ else if (to.isEmpty && inIDE) throw new TypeError(NoPos, "type parameter list problem");
else if (matches(from.head, sym)) toType(tp, to.head)
else subst(sym, from.tail, to.tail)
tp match {
@@ -2187,6 +2195,8 @@ trait Types requires SymbolTable {
} finally {
stc = stc - 1
}
+ /** hook for IDE */
+ protected def trackTypeIDE(sym : Symbol) : Boolean = true;
/** Does type <code>tp1</code> conform to <code>tp2</code>?
*
@@ -2214,6 +2224,8 @@ trait Types requires SymbolTable {
case (TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) =>
//Console.println("isSubType " + tp1 + " " + tp2);//DEBUG
+ if (inIDE) { trackTypeIDE(sym1); trackTypeIDE(sym2); }
+
def isSubArgs(tps1: List[Type], tps2: List[Type],
tparams: List[Symbol]): boolean = (
tps1.isEmpty && tps2.isEmpty
@@ -2267,8 +2279,9 @@ trait Types requires SymbolTable {
case (_, AnnotatedType(_,atp2)) =>
tp1 <:< atp2
case (_, TypeRef(pre2, sym2, args2))
- if sym2.isAbstractType && !(tp2 =:= tp2.bounds.lo) && (tp1 <:< tp2.bounds.lo) =>
- true
+ if sym2.isAbstractType && !(tp2 =:= tp2.bounds.lo) && (tp1 <:< tp2.bounds.lo) && {
+ if (!inIDE) true else trackTypeIDE(sym2)
+ } => true
case (_, RefinedType(parents2, ref2)) =>
(parents2 forall tp1.<:<) && (ref2.toList forall tp1.specializes) &&
(!parents2.exists(.symbol.isAbstractType) || tp1.symbol != AllRefClass)
@@ -2284,6 +2297,7 @@ trait Types requires SymbolTable {
case (ConstantType(_), _) => tp1.singleDeref <:< tp2
case (TypeRef(pre1, sym1, args1), _) =>
+ if (inIDE) trackTypeIDE(sym1)
(sym1 == AllClass && tp2 <:< AnyClass.tpe
||
sym1 == AllRefClass && tp2.isInstanceOf[SingletonType] && (tp1 <:< tp2.widen))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index f4e99e0007..8ab4b50aa2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -476,12 +476,16 @@ trait Namers requires Analyzer {
var resultPt = if (tpt.isEmpty) WildcardType else typer.typedType(tpt).tpe
+ if (onlyPresentation)
+ methodArgumentNames(meth) = vparamss.map(.map(.symbol));
if (meth.owner.isClass && (tpt.isEmpty || vparamss.exists(.exists(.tpt.isEmpty)))) {
// try to complete from matching definition in base type
for (val vparams <- vparamss; val vparam <- vparams)
if (vparam.tpt.isEmpty) vparam.symbol setInfo WildcardType
val schema = thisMethodType(resultPt)
val site = meth.owner.thisType
+
+
val overridden = intersectionType(meth.owner.info.parents).member(meth.name).filter(sym =>
sym != NoSymbol && (site.memberType(sym) matches schema))
if (overridden != NoSymbol && !(overridden hasFlag OVERLOADED)) {
@@ -489,6 +493,7 @@ trait Namers requires Analyzer {
case PolyType(tparams, rt) => rt.substSym(tparams, tparamSyms)
case mt => mt
}
+
for (val vparams <- vparamss) {
var pfs = resultPt.paramTypes
for (val vparam <- vparams) {
@@ -772,10 +777,11 @@ trait Namers requires Analyzer {
* This is used for error messages, where we want to speak in terms
* of the actual declaration or definition, not in terms of the generated setters
* and getters */
- def underlying(member: Symbol) =
+ def underlying(member: Symbol) : Symbol =
if (member hasFlag ACCESSOR) {
if (member hasFlag DEFERRED) {
val getter = if (member.isSetter) member.getter(member.owner) else member
+ if (inIDE && getter == NoSymbol) return NoSymbol;
val result = getter.owner.newValue(getter.pos, getter.name)
.setInfo(getter.tpe.resultType)
.setFlag(DEFERRED)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index df3ede8eca..aff947c210 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -900,7 +900,7 @@ trait Typers requires Analyzer {
if (mods.flags & (PRIVATE | LOCAL)) != (PRIVATE | LOCAL) && !stat.symbol.isModuleVar =>
val vdef = copy.ValDef(stat, mods | PRIVATE | LOCAL, nme.getterToLocal(name), tpt, rhs)
val value = vdef.symbol
- val getter = if (mods hasFlag DEFERRED) value else value.getter(value.owner)
+ val getter = if ((mods hasFlag DEFERRED) || inIDE) value else value.getter(value.owner)
assert(getter != NoSymbol, stat)
if (getter hasFlag OVERLOADED)
error(getter.pos, getter+" is defined twice")
@@ -1179,6 +1179,8 @@ trait Typers requires Analyzer {
tp
}
+ protected def typedFunctionIDE(fun : Function, txt : Context) = {}
+
/**
* @param block ...
* @param mode ...
@@ -1282,6 +1284,8 @@ trait Typers requires Analyzer {
vparam.symbol
}
// XXX: here to for IDE hooks.
+ if (inIDE) // HACK to process arguments types in IDE.
+ typedFunctionIDE(fun, context);
val vparams = List.mapConserve(fun.vparams)(typedValDef)
for (val vparam <- vparams) {
checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()
@@ -1787,7 +1791,7 @@ trait Typers requires Analyzer {
qual.tpe.widen+" does not have a constructor"
else
decode(name)+" is not a member of "+qual.tpe.widen +
- (if ((context.unit ne null) && Position.line(context.unit.source, qual.pos) <
+ (if (!inIDE && (context.unit ne null) && Position.line(context.unit.source, qual.pos) <
Position.line(context.unit.source, tree.pos))
"\npossible cause: maybe a semicolon is missing before `"+decode(name)+"'?"
else ""))
@@ -1857,8 +1861,21 @@ trait Typers requires Analyzer {
while (defSym == NoSymbol && cx != NoContext) {
pre = cx.enclClass.prefix
defEntry = cx.scope.lookupEntry(name)
+ if (inIDE && (defEntry ne null) && defEntry.sym.exists) {
+ val sym = defEntry.sym
+ val namePos : Int = tree.pos
+ val symPos : Int = sym.pos
+ if (namePos < symPos) defEntry = null
+ }
if ((defEntry ne null) && qualifies(defEntry.sym)) {
defSym = defEntry.sym
+ } else if (inIDE) {
+ if (cx.outer == cx.enclClass) {
+ cx = cx.enclClass
+ defSym = pre.member(name) filter (
+ sym => sym.exists && context.isAccessible(sym, pre, false))
+ }
+ if (defSym == NoSymbol) cx = cx.outer
} else {
cx = cx.enclClass
defSym = pre.member(name) filter (
diff --git a/src/library/scala/Iterable.scala b/src/library/scala/Iterable.scala
index 579e249c3f..85d61c7227 100644
--- a/src/library/scala/Iterable.scala
+++ b/src/library/scala/Iterable.scala
@@ -382,4 +382,22 @@ trait Iterable[+A] {
}
buf.append(end)
}
+
+ /** Fills the given array <code>xs</code> with the elements of
+ * this sequence starting at position <code>start</code>.
+ *
+ * @param xs the array to fill.
+ * @param start starting index.
+ * @pre the array must be large enough to hold all elements.
+ */
+ def copyToArray[B >: A](xs: Array[B], start: Int): Unit =
+ elements.copyToArray(xs, start)
+
+ /** Converts this iterable to a fresh Array with elements.
+ */
+ def toArray[B >: A]: Array[B] = toList.toArray
+
+ /** Is this collection empty? */
+ def isEmpty = elements.hasNext
+
}
diff --git a/src/library/scala/List.scala b/src/library/scala/List.scala
index b6723b5517..de0b24c716 100644
--- a/src/library/scala/List.scala
+++ b/src/library/scala/List.scala
@@ -401,26 +401,23 @@ sealed abstract class List[+a] extends Seq[a] {
/** <p>
* Add an element <code>x</code> at the beginning of this list.
- * Example:
* </p>
- * <pre>
- * 1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3)</pre>
*
* @param x the element to append.
* @return the list with <code>x</code> appended at the beginning.
+ * @ex <code>1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3)</code>
*/
def ::[b >: a] (x: b): List[b] =
new scala.::(x, this)
/** <p>
* Returns a list resulting from the concatenation of the given
- * list <code>prefix</code> and this list. Example:
+ * list <code>prefix</code> and this list.
* </p>
- * <pre>
- * List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4)</pre>
*
* @param prefix the list to concatenate at the beginning of this list.
* @return the concatenation of the two lists.
+ * @ex <code>List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4)</code>
*/
def :::[b >: a](prefix: List[b]): List[b] =
if (isEmpty) prefix
@@ -767,20 +764,18 @@ sealed abstract class List[+a] extends Seq[a] {
* Sort the list according to the comparison function
* <code>&lt;(e1: a, e2: a) =&gt; Boolean</code>,
* which should be true iff <code>e1</code> is smaller than
- * <code>e2</code>. Example:
- * </p>
- * <pre>
- * List("Steve", "Tom", "John", "Bob")
- * .sort((e1, e2) => (e1 compareTo e2) &lt; 0) =
- * List("Bob", "John", "Steve", "Tom")</pre>
- * <p>
- * Note: The current implementation is inefficent for
- * already sorted lists.
+ * <code>e2</code>.
* </p>
*
* @param lt the comparison function
* @return a list sorted according to the comparison function
* <code>&lt;(e1: a, e2: a) =&gt; Boolean</code>.
+ * @ex <pre>
+ * List("Steve", "Tom", "John", "Bob")
+ * .sort((e1, e2) => (e1 compareTo e2) &lt; 0) =
+ * List("Bob", "John", "Steve", "Tom")</pre>
+ * @note The current implementation is inefficent for
+ * already sorted lists.
*/
def sort(lt : (a,a) => Boolean): List[a] = {
def sort_1(smaller: List[a], acc: List[a]): List[a] =
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index 06b9f70681..13f4602c5f 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -29,7 +29,8 @@ trait PartialFunction[-A, +B] extends AnyRef with (A => B) {
*/
def isDefinedAt(x: A): Boolean;
- def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) = new PartialFunction[A1, B1] {
+ def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] =
+ new PartialFunction[A1, B1] {
def isDefinedAt(x: A1): Boolean =
PartialFunction.this.isDefinedAt(x) || that.isDefinedAt(x)
def apply(x: A1): B1 =
@@ -37,7 +38,7 @@ trait PartialFunction[-A, +B] extends AnyRef with (A => B) {
else that.apply(x)
}
- override def andThen[C](k: B => C) = new PartialFunction[A, C] {
+ override def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] {
def isDefinedAt(x: A): Boolean = PartialFunction.this.isDefinedAt(x)
def apply(x: A): C = k(PartialFunction.this.apply(x))
}
diff --git a/src/library/scala/Seq.scala b/src/library/scala/Seq.scala
index e1d5581ea1..78dc4af435 100644
--- a/src/library/scala/Seq.scala
+++ b/src/library/scala/Seq.scala
@@ -79,7 +79,7 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Iterable[A] {
/** Returns true if length == 0
*/
- def isEmpty: Boolean = { length == 0 }
+ override def isEmpty: Boolean = { length == 0 }
/** Appends two iterable objects.
*
@@ -242,25 +242,6 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Iterable[A] {
@deprecated
def subseq(from: Int, end: Int): Seq[A] = slice(from, end - from)
-
- /** Converts this sequence to a fresh Array with <code>length</code>
- * elements.
- */
- def toArray[B >: A]: Array[B] = {
- val result = new Array[B](length)
- copyToArray(result, 0)
- result
- }
-
- /** Fills the given array <code>xs</code> with the elements of
- * this sequence starting at position <code>start</code>.
- *
- * @param xs the array to fill.
- * @param start starting index.
- * @pre the array must be large enough to hold all elements.
- */
- def copyToArray[B >: A](xs: Array[B], start: Int): Unit = elements.copyToArray(xs, start)
-
/** Customizes the <code>toString</code> method.
*
* @return a string representation of this sequence.
@@ -272,5 +253,15 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Iterable[A] {
/** Defines the prefix of the string representation.
*/
protected def stringPrefix: String = "Seq"
+
+ /** Converts this sequence to a fresh Array with <code>length</code> elements.
+ */
+ override def toArray[B >: A]: Array[B] = {
+ val result = new Array[B](length)
+ copyToArray(result, 0)
+ result
+ }
+
+
}
diff --git a/src/library/scala/Symbol.scala b/src/library/scala/Symbol.scala
index 9bc195dce6..e1edf78686 100644
--- a/src/library/scala/Symbol.scala
+++ b/src/library/scala/Symbol.scala
@@ -11,9 +11,9 @@
package scala
-import collection.jcl.WeakHashMap
+import scala.collection.jcl
-private[scala] object internedSymbols extends WeakHashMap[String, Symbol]
+private[scala] object internedSymbols extends jcl.HashMap[String, ref.WeakReference[Symbol]]
/** <p>
* Instances of <code>Symbol</code> can be created easily with
@@ -47,11 +47,9 @@ final case class Symbol(name: String) {
*
* @return the unique reference to this symbol.
*/
- def intern: Symbol = internedSymbols get name match {
- case Some(sym) =>
- sym
+ def intern: Symbol = synchronized { internedSymbols get name match {
+ case Some(sym) if sym.isValid => sym.apply
case None =>
- internedSymbols(name) = this
- this
- }
+ internedSymbols(name) = new ref.WeakReference(this); this
+ } }
}
diff --git a/src/library/scala/collection/Map.scala b/src/library/scala/collection/Map.scala
index f3aab7c16a..df2f2630d3 100644
--- a/src/library/scala/collection/Map.scala
+++ b/src/library/scala/collection/Map.scala
@@ -63,7 +63,7 @@ trait Map[A, +B] extends PartialFunction[A, B] with Iterable[(A, B)] {
*
* @return <code>true</code> iff the map is empty.
*/
- def isEmpty: Boolean = size == 0
+ override def isEmpty: Boolean = size == 0
/** Retrieve the value which is associated with the given key. This
* method throws an exception if there is no mapping from the given
diff --git a/src/library/scala/collection/Set.scala b/src/library/scala/collection/Set.scala
index fcea89893e..6f90a27cb4 100644
--- a/src/library/scala/collection/Set.scala
+++ b/src/library/scala/collection/Set.scala
@@ -61,7 +61,7 @@ trait Set[A] extends (A => Boolean) with Iterable[A] {
*
* @return <code>true</code> iff there is no element in the set.
*/
- def isEmpty: Boolean = size == 0
+ override def isEmpty: Boolean = size == 0
/** Checks if this set is a subset of set <code>that</code>.
*
@@ -89,7 +89,7 @@ trait Set[A] extends (A => Boolean) with Iterable[A] {
/** hashcode for this set */
override def hashCode() =
- (0 /: this)((hash, e) => hash * 41 + e.hashCode())
+ (0 /: this)((hash, e) => hash + e.hashCode())
/** Returns a string representation of this set.
@@ -97,4 +97,9 @@ trait Set[A] extends (A => Boolean) with Iterable[A] {
* @return a string showing all elements of this set.
*/
override def toString() = mkString("Set(", ", ", ")")
+ override def toArray[B >: A]: Array[B] = {
+ val result = new Array[B](size)
+ copyToArray(result, 0)
+ result
+ }
}
diff --git a/src/library/scala/collection/Sorted.scala b/src/library/scala/collection/Sorted.scala
index 5040246a91..eda7c21aef 100644
--- a/src/library/scala/collection/Sorted.scala
+++ b/src/library/scala/collection/Sorted.scala
@@ -33,8 +33,8 @@ trait Sorted[K,+A] extends Ranged[K,A] {
override def range(from: K, until: K) = rangeImpl(Some(from),Some(until));
/** Create a range projection of this collection with no lower-bound.
- ** @param to The upper-bound (inclusive) of the ranged projection.
- **/
+ * @param to The upper-bound (inclusive) of the ranged projection.
+ */
def to(to : K): Sorted[K,A] = {
// tough!
val i = keySet.from(to).elements;
diff --git a/src/library/scala/collection/jcl/MutableIterable.scala b/src/library/scala/collection/jcl/MutableIterable.scala
index 75f6b01717..081865169a 100644
--- a/src/library/scala/collection/jcl/MutableIterable.scala
+++ b/src/library/scala/collection/jcl/MutableIterable.scala
@@ -45,9 +45,7 @@ trait MutableIterable[A] extends Iterable[A] {
/** retain only elements that are also in that.
**/
def retainAll(that : Iterable[A]) : Boolean = elements.retain(s => that.exists(t => t == s));
- /** @return true if the element has no elements.
- **/
- def isEmpty : Boolean = !elements.hasNext;
+
/** @return the current number of elements in the collection.
**/
def size : Int = {
diff --git a/src/library/scala/collection/mutable/Set.scala b/src/library/scala/collection/mutable/Set.scala
index a516fef5f2..8e081191b6 100644
--- a/src/library/scala/collection/mutable/Set.scala
+++ b/src/library/scala/collection/mutable/Set.scala
@@ -202,4 +202,29 @@ trait Set[A] extends collection.Set[A] with Scriptable[Message[A]] {
* @return a set with the same elements.
*/
override def clone(): Set[A] = super.clone().asInstanceOf[Set[A]]
+
+ /** Return a read-only projection of this set */
+ def readOnly : scala.collection.Set[A] = new scala.collection.Set[A] {
+ /** used to trigger version checking in JCL and hopefully the mutable collections */
+ override val hashCode = Set.this.hashCode
+ private def check =
+ if (false && hashCode != Set.this.hashCode)
+ throw new java.util.ConcurrentModificationException
+
+ def contains(item : A) = {
+ check
+ Set.this.contains(item)
+ }
+ override def toString = {
+ "read-only-" + Set.this.toString
+ }
+ override def size = {
+ check
+ Set.this.size
+ }
+ override def elements = {
+ check
+ Set.this.elements
+ }
+ }
}