From 806238432588319e91805570ffbfc2f0ce5f409b Mon Sep 17 00:00:00 2001 From: Sean McDirmid Date: Wed, 28 Mar 2007 10:44:12 +0000 Subject: Revamped scala-doc. --- src/compiler/scala/tools/nsc/Global.scala | 6 +++++ src/compiler/scala/tools/nsc/Main.scala | 2 +- src/compiler/scala/tools/nsc/ast/Trees.scala | 2 +- .../scala/tools/nsc/doc/DocGenerator.scala | 5 ++-- src/compiler/scala/tools/nsc/doc/DocUtil.scala | 28 ++++++++++++++++++- src/compiler/scala/tools/nsc/io/PlainFile.scala | 20 ++++---------- src/compiler/scala/tools/nsc/io/ZipArchive.scala | 7 ++--- .../scala/tools/nsc/symtab/SymbolTable.scala | 2 ++ src/compiler/scala/tools/nsc/symtab/Symbols.scala | 2 +- src/compiler/scala/tools/nsc/symtab/Types.scala | 20 +++++++++++--- .../scala/tools/nsc/typechecker/Namers.scala | 8 +++++- .../scala/tools/nsc/typechecker/Typers.scala | 21 +++++++++++++-- src/library/scala/Iterable.scala | 18 +++++++++++++ src/library/scala/List.scala | 25 +++++++---------- src/library/scala/PartialFunction.scala | 5 ++-- src/library/scala/Seq.scala | 31 ++++++++-------------- src/library/scala/Symbol.scala | 14 +++++----- src/library/scala/collection/Map.scala | 2 +- src/library/scala/collection/Set.scala | 9 +++++-- src/library/scala/collection/Sorted.scala | 4 +-- .../scala/collection/jcl/MutableIterable.scala | 4 +-- src/library/scala/collection/mutable/Set.scala | 25 +++++++++++++++++ 22 files changed, 174 insertions(+), 86 deletions(-) (limited to 'src') 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 { ; 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 =
@@ -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 tp1 conform to tp2? * @@ -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 xs with the elements of + * this sequence starting at position start. + * + * @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] { /**

* Add an element x at the beginning of this list. - * Example: *

- *
-   *    1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3)
* * @param x the element to append. * @return the list with x appended at the beginning. + * @ex 1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3) */ def ::[b >: a] (x: b): List[b] = new scala.::(x, this) /**

* Returns a list resulting from the concatenation of the given - * list prefix and this list. Example: + * list prefix and this list. *

- *
-   *    List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4)
* * @param prefix the list to concatenate at the beginning of this list. * @return the concatenation of the two lists. + * @ex List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4) */ 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 * <(e1: a, e2: a) => Boolean, * which should be true iff e1 is smaller than - * e2. Example: - *

- *
-   *    List("Steve", "Tom", "John", "Bob")
-   *      .sort((e1, e2) => (e1 compareTo e2) < 0) =
-   *    List("Bob", "John", "Steve", "Tom")
- *

- * Note: The current implementation is inefficent for - * already sorted lists. + * e2. *

* * @param lt the comparison function * @return a list sorted according to the comparison function * <(e1: a, e2: a) => Boolean. + * @ex
+   *    List("Steve", "Tom", "John", "Bob")
+   *      .sort((e1, e2) => (e1 compareTo e2) < 0) =
+   *    List("Bob", "John", "Steve", "Tom")
+ * @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 length - * elements. - */ - def toArray[B >: A]: Array[B] = { - val result = new Array[B](length) - copyToArray(result, 0) - result - } - - /** Fills the given array xs with the elements of - * this sequence starting at position start. - * - * @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 toString 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 length 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]] /**

* Instances of Symbol 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 true 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 true 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 that. * @@ -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 + } + } } -- cgit v1.2.3