From 55ce01a926ec6fcc0474a905a6a0026811527d72 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Thu, 12 Nov 2009 13:30:08 +0000 Subject: Merged revisions 19543,19545-19547 via svnmerge... Merged revisions 19543,19545-19547 via svnmerge from https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk ........ r19543 | rytz | 2009-11-12 12:10:13 +0100 (Thu, 12 Nov 2009) | 1 line fixed #2470. ........ r19545 | cunei | 2009-11-12 13:07:09 +0100 (Thu, 12 Nov 2009) | 2 lines removed disabled files ........ r19546 | rytz | 2009-11-12 13:31:49 +0100 (Thu, 12 Nov 2009) | 1 line fix #2488. ........ r19547 | odersky | 2009-11-12 14:08:04 +0100 (Thu, 12 Nov 2009) | 1 line Allow protected access to constructor in superclass. Closes #1836 ........ --- .../scala/tools/nsc/symtab/Constants.scala | 7 +- src/compiler/scala/tools/nsc/symtab/Symbols.scala | 23 +- .../nsc/symtab/classfile/ClassfileParser.scala | 2 +- .../scala/tools/nsc/typechecker/Contexts.scala | 2 +- .../tools/nsc/typechecker/NamesDefaults.scala | 5 +- .../collection/RollbackIterator.scala.disabled | 88 ----- .../generic/GenericSequenceFactory.scala.disabled | 17 - .../GenericTraversableFactory.scala.disabled | 188 --------- .../immutable/ImmutableIterator.scala.disabled | 117 ------ .../scala/collection/immutable/Tree.scala.disabled | 440 --------------------- test/files/jvm/t2470.check | 1 + test/files/jvm/t2470/Action.java | 6 + test/files/jvm/t2470/Read_Classfile_2.scala | 3 + test/files/jvm/t2470/Task.java | 3 + test/files/jvm/t2470/Test_1.scala | 11 + test/files/neg/names-defaults-neg.check | 49 ++- test/files/neg/names-defaults-neg.scala | 1 - test/files/run/names-defaults.check | 4 + test/files/run/names-defaults.scala | 2 + 19 files changed, 85 insertions(+), 884 deletions(-) delete mode 100644 src/library/scala/collection/RollbackIterator.scala.disabled delete mode 100644 src/library/scala/collection/generic/GenericSequenceFactory.scala.disabled delete mode 100644 src/library/scala/collection/generic/GenericTraversableFactory.scala.disabled delete mode 100644 src/library/scala/collection/immutable/ImmutableIterator.scala.disabled delete mode 100644 src/library/scala/collection/immutable/Tree.scala.disabled create mode 100644 test/files/jvm/t2470.check create mode 100644 test/files/jvm/t2470/Action.java create mode 100644 test/files/jvm/t2470/Read_Classfile_2.scala create mode 100644 test/files/jvm/t2470/Task.java create mode 100644 test/files/jvm/t2470/Test_1.scala diff --git a/src/compiler/scala/tools/nsc/symtab/Constants.scala b/src/compiler/scala/tools/nsc/symtab/Constants.scala index dfe7147270..2a4d3e1fa1 100644 --- a/src/compiler/scala/tools/nsc/symtab/Constants.scala +++ b/src/compiler/scala/tools/nsc/symtab/Constants.scala @@ -66,7 +66,12 @@ trait Constants { case StringTag => StringClass.tpe case NullTag => NullClass.tpe case ClassTag => Predef_classOfType(value.asInstanceOf[Type]) - case EnumTag => symbolValue.owner.linkedClassOfClass.tpe + case EnumTag => + // given (in java): "class A { enum E { VAL1 } }" + // - symbolValue: the symbol of the actual enumeration value (VAL1) + // - .owner: the ModuleClasSymbol of the enumeration (object E) + // - .linkedClassOfClass: the ClassSymbol of the enumeration (class E) + symbolValue.owner.linkedClassOfClass.tpe } /** We need the equals method to take account of tags as well as values. diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 3b9ffa4f58..1c22a6fdaf 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -1235,7 +1235,7 @@ trait Symbols { */ final def linkedClassOfModule: Symbol = { if (this != NoSymbol) - owner.rawInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) + flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) else NoSymbol } @@ -1244,7 +1244,7 @@ trait Symbols { */ final def linkedModuleOfClass: Symbol = if (this.isClass && !this.isAnonymousClass && !this.isRefinementClass) { - owner.rawInfo.decl(name.toTermName).suchThat( + flatOwnerInfo.decl(name.toTermName).suchThat( sym => (sym hasFlag MODULE) && (sym isCoDefinedWith this)) } else NoSymbol @@ -1253,7 +1253,7 @@ trait Symbols { */ final def linkedSym: Symbol = if (isTerm) linkedClassOfModule - else if (isClass) owner.rawInfo.decl(name.toTermName).suchThat(_ isCoDefinedWith this) + else if (isClass) flatOwnerInfo.decl(name.toTermName).suchThat(_ isCoDefinedWith this) else NoSymbol /** For a module class its linked class, for a plain class @@ -1268,6 +1268,23 @@ trait Symbols { final def linkedClassOfClass: Symbol = if (isModuleClass) linkedClassOfModule else linkedModuleOfClass.moduleClass + /** + * Returns the rawInfo of the owner. If the current phase has flat classes, it first + * applies all pending type maps to this symbol. + * + * Asssume this is the ModuleSymbol for B in the follwing definition: + * package p { class A { object B { val x = 1 } } } + * + * The owner after flatten is "package p" (see "def owner"). The flatten type map enters + * symbol B in the decls of p. So to find a linked symbol ("object B" or "class B") + * we need to apply flatten to B first. Fixes #2470. + */ + private final def flatOwnerInfo: Type = { + if (phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass) + info + owner.rawInfo + } + /** If this symbol is an implementation class, its interface, otherwise the symbol itself * The method follows two strategies to determine the interface. * - during or after erasure, it takes the last parent of the implementatation class diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 940a8e223b..86cb636fb8 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -890,7 +890,7 @@ abstract class ClassfileParser { val innerClass = getOwner(jflags).newClass(NoPosition, name.toTypeName).setInfo(completer).setFlag(sflags) val innerModule = getOwner(jflags).newModule(NoPosition, name).setInfo(completer).setFlag(sflags) - innerClass.moduleClass.setInfo(global.loaders.moduleClassLoader) + innerModule.moduleClass.setInfo(global.loaders.moduleClassLoader) getScope(jflags).enter(innerClass) getScope(jflags).enter(innerModule) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 4da47d58dd..b3e4666f35 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -426,7 +426,7 @@ trait Contexts { self: Analyzer => pre =:= sym.owner.thisType) || (sym hasFlag PROTECTED) && - (superAccess || + (superAccess || sym.isConstructor || (pre.widen.typeSymbol.isNonBottomSubClass(sym.owner) && (isSubClassOfEnclosing(pre.widen.typeSymbol) || phase.erasedTypes)))) // note: phase.erasedTypes disables last test, because after addinterfaces diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index f19f5516c0..773b2cf561 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -388,7 +388,10 @@ trait NamesDefaults { self: Analyzer => } val res = typer.silent(_.typed(arg, subst(paramtpe))) match { case _: TypeError => - positionalAllowed = false + // if the named argument is on the original parameter + // position, positional after named is allowed. + if (index != pos) + positionalAllowed = false argPos(index) = pos rhs case t: Tree => diff --git a/src/library/scala/collection/RollbackIterator.scala.disabled b/src/library/scala/collection/RollbackIterator.scala.disabled deleted file mode 100644 index 99573ab307..0000000000 --- a/src/library/scala/collection/RollbackIterator.scala.disabled +++ /dev/null @@ -1,88 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - -package scala.collection - -import scala.collection.mutable.{ArrayBuffer} - -/** Rollback iterators are buffered iterators which allow for unbounded rollbacks - * - * @author Sean McDirmid - * @since 2.5 - */ -class RollbackIterator[+A](underlying: Iterator[A]) extends BufferedIterator.Default[A] { - private[this] var rollback: ArrayBuffer[A] = null - protected def fill(sz: Int): Seq[A] = - if (underlying.hasNext) underlying.next :: Nil else Nil - - override def next: A = { - val ret = super.next - if (rollback != null) rollback += ret - ret - } - - private def initRollback = - if (rollback == null) { - rollback = new ArrayBuffer[A] - None - } - else Some(rollback.length) - - /** will rollback all elements iterated during - * f's execution if f return false - */ - def tryRead[T](f: => Option[T]): Option[T] = { - val oldLength = initRollback - var g : Option[T] = None - try { - g = f - } finally { - if (g.isEmpty) { - //putBack(rollback(0)) - val sz = oldLength.getOrElse(0) - val i = rollback.drop(sz).reverse.iterator - while (i.hasNext) putBack(i.next) - if (oldLength.isEmpty) rollback = null - else rollback.reduceToSize(sz) - } - } - if (!g.isEmpty && oldLength.isEmpty) - rollback = null - g - - } - /** remembers elements iterated over during g's execution - * and provides these elements to the result of g's execution - */ - def remember[T](g: => (Seq[A] => T)): T = { - val oldLength = initRollback - var in: Seq[A] = Nil - val f = try { - g - } finally { - in = rollback.drop(oldLength.getOrElse(0)) - if (oldLength.isEmpty) rollback = null - } - f(in) - } - - /** returns true if any elements are iterated over during f's execution - */ - def read(f: => Unit): Boolean = remember[Boolean] { - f; seq => !seq.isEmpty - } - - /** if elements of seq will be iterated over next in this iterator, - * returns true and iterates over these elements - */ - override def readIfStartsWith(seq : Seq[Any]) : Boolean = - !tryRead{if (seq.forall(a => hasNext && next == a)) Some(()) else None}.isEmpty - -} diff --git a/src/library/scala/collection/generic/GenericSequenceFactory.scala.disabled b/src/library/scala/collection/generic/GenericSequenceFactory.scala.disabled deleted file mode 100644 index 9132c96762..0000000000 --- a/src/library/scala/collection/generic/GenericSequenceFactory.scala.disabled +++ /dev/null @@ -1,17 +0,0 @@ -package scala.collection.generic - -/** A template for companion objects of Sequence and subclasses thereof. - * - * @since 2.8 - */ -abstract class GenericSequenceFactory extends GenericTraversableFactory { - - type Coll <: Sequence[_] - - /** This method is called in a pattern match { case Sequence(...) => }. - * - * @param x the selector value - * @return sequence wrapped in an option, if this is a Sequence, otherwise none - */ - def unapplySeq[A](x: Coll with Sequence[A]): Some[Coll with Sequence[A]] = Some(x) -} diff --git a/src/library/scala/collection/generic/GenericTraversableFactory.scala.disabled b/src/library/scala/collection/generic/GenericTraversableFactory.scala.disabled deleted file mode 100644 index c2ae7e114c..0000000000 --- a/src/library/scala/collection/generic/GenericTraversableFactory.scala.disabled +++ /dev/null @@ -1,188 +0,0 @@ -package scala.collection.generic - -/** A template for companion objects of Traversable and subclasses thereof. - * - * @since 2.8 - */ -abstract class GenericTraversableFactory { - - type Coll <: Traversable[_] - - /** The empty iterable of type CC */ - def empty[A, That](implicit bf: Coll => Builder[A, That, Coll]): That = apply[A, That]() - - /** Creates an iterable of type CC with specified elements */ - def apply[A, That](args: A*)(implicit bf: Coll => Builder[A, That, Coll]): That = { - val b = bf(thisCollection) - b ++= Iterable.fromOld(args) - b.result - } - - /** Concatenate all the argument lists into a single list. - * - * @param xss the lists that are to be concatenated - * @return the concatenation of all the lists - */ - def concat[A, That](xss: Traversable[A]*)(implicit bf: Coll => Builder[A, That, Coll]): That = { - val b = bf(thisCollection) - for (xs <- Iterable.fromOld(xss)) - b ++= xs - b.result - } - - /** An iterable that contains the results of some element computation a number of times. - * @param n the number of elements returned - * @param elem the element computation - */ - def fill[A, That](n: Int)(elem: => A)(implicit bf: Coll => Builder[A, That, Coll]): That = { - val b = bf(thisCollection) - var i = 0 - while (i < n) { - b += elem - i += 1 - } - b.result - } - - /** A two-dimensional iterable that contains the results of some element computation a number of times. - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param elem the element computation - */ - def fill[A, C1, That](n1: Int, n2: Int)(elem: => A)(implicit b1: Builder[A, C1, Coll], b2: Builder[C1, That, Coll]): That = - tabulate(n1)(_ => fill(n2)(elem)) -/* - /** A three-dimensional iterable that contains the results of some element computation a number of times. - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param elem the element computation - */ - def fill[A](n1: Int, n2: Int, n3: Int)(elem: => A): CC[CC[CC[A]]] = - tabulate(n1)(_ => fill(n2, n3)(elem)) - - /** A four-dimensional iterable that contains the results of some element computation a number of times. - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param elem the element computation - */ - def fill[A](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => A): CC[CC[CC[CC[A]]]] = - tabulate(n1)(_ => fill(n2, n3, n4)(elem)) - - /** A five-dimensional iterable that contains the results of some element computation a number of times. - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param n5 the number of elements in the 5th dimension - * @param elem the element computation - */ - def fill[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => A): CC[CC[CC[CC[CC[A]]]]] = - tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) -*/ - - /** An iterable containing values of a given function over a range of integer values starting from 0. - * @param n The number of elements in the iterable - * @param f The function computing element values - * @return An iterable consisting of elements `f(0), ..., f(n -1)` - */ - def tabulate[A, That](n: Int)(f: Int => A)(implicit bf: Coll => Builder[A, That, Coll]) = { - val b = bf(thisCollection) - var i = 0 - while (i < n) { - b += f(i) - i += 1 - } - b.result - } - - /** A two-dimensional iterable containing values of a given function over ranges of integer values starting from 0. - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param f The function computing element values - */ - def tabulate[A, C1, That](n1: Int, n2: Int)(f: (Int, Int) => A)(implicit b1: Builder[A, C1, Coll], b2: Builder[C1, That, Coll]): That = - tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) - - /* - /** A three-dimensional iterable containing values of a given function over ranges of integer values starting from 0. - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param f The function computing element values - */ - def tabulate[A](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): CC[CC[CC[A]]] = - tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) - - /** A four-dimensional iterable containing values of a given function over ranges of integer values starting from 0. - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param f The function computing element values - */ - def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => A): CC[CC[CC[CC[A]]]] = - tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) - - /** A five-dimensional iterable containing values of a given function over ranges of integer values starting from 0. - * @param n1 the number of elements in the 1st dimension - * @param n2 the number of elements in the 2nd dimension - * @param n3 the number of elements in the 3nd dimension - * @param n4 the number of elements in the 4th dimension - * @param n5 the number of elements in the 5th dimension - * @param f The function computing element values - */ - def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => A): CC[CC[CC[CC[CC[A]]]]] = - tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) -*/ - - /** An iterable containing a sequence of increasing integers in a range. - * - * @param from the start value of the iterable - * @param end the end value of the iterable (the first value NOT returned) - * @return the iterable with values in range `start, start + 1, ..., end - 1` - * up to, but exclusding, `end`. - */ - def range[That](start: Int, end: Int)(implicit bf: Coll => Builder[Int, That, Coll]): That = - range(start, end, 1) - - /** An iterable containing equally spaced values in some integer interval. - - * @param start the start value of the iterable - * @param end the end value of the iterable (the first value NOT returned) - * @param step the increment value of the iterable (must be positive or negative) - * @return the iterable with values in `start, start + step, ...` up to, but excluding `end` - */ - def range[That](start: Int, end: Int, step: Int)(implicit bf: Coll => Builder[Int, That, Coll]): That = { - val b = bf(thisCollection) - if (step == 0) throw new IllegalArgumentException("zero step") - var i = start - while (if (step < 0) end < i else i < end) { - b += i - i += step - } - b.result - } - - /** An iterable containing repeated applications of a function to a start value. - * - * @param start the start value of the iterable - * @param len the number of elements returned by the iterable - * @param f the function that's repeatedly applied - * @return the iterable returning `len` values in the sequence `start, f(start), f(f(start)), ...` - */ - def iterate[That](start: Int, len: Int)(f: Int => Int)(implicit bf: Coll => Builder[Int, That, Coll]): That = { - val b = bf(thisCollection) - var acc = start - var i = 0 - while (i < len) { - b += acc - acc = f(acc) - i += 1 - } - b.result - } -} - diff --git a/src/library/scala/collection/immutable/ImmutableIterator.scala.disabled b/src/library/scala/collection/immutable/ImmutableIterator.scala.disabled deleted file mode 100644 index 2326bc19f6..0000000000 --- a/src/library/scala/collection/immutable/ImmutableIterator.scala.disabled +++ /dev/null @@ -1,117 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - -// Not clear whether this is needed. How is it different from a Stream? -package scala.collection.immutable - -/** An object for creating immutable iterators. - * @since 2.4 - */ -object ImmutableIterator { - case object Empty extends ImmutableIterator[Nothing] { - def hasNext = false - def next = throw new NoSuchElementException - } - - private case class NonEmpty[+A](item: A, right: () => ImmutableIterator[A]) extends ImmutableIterator[A] { - def hasNext = true - def next = Tuple2(item, right()) - } - - /** Creates an empty immutable iterator. - */ - def empty : ImmutableIterator[Nothing] = Empty - - /** Creates an immutable iterator with one element. - */ - def apply[A](item : A) : ImmutableIterator[A] = NonEmpty(item, () => Empty) - - /** Prepends a lazy immutable iterator (right) with an element (item). - */ - def apply[A](item : A, right : () => ImmutableIterator[A]) : () => ImmutableIterator[A] = - () => NonEmpty(item, right) - - /** Appends an immutable iterator (left) with an element (item) followed - * by a lazy immutable iterator (right). - */ - def apply[A](left : ImmutableIterator[A], item : A, right : () => ImmutableIterator[A]) : ImmutableIterator[A] = left match { - case NonEmpty(first, middle) => - val rest = NonEmpty(item,right); - NonEmpty(first, apply(middle, () => rest)); - case Empty => NonEmpty(item, right); - } - - /** Concats a lazy immutable iterator (left) with another lazy immutable - * iterator (right). - */ - def apply[A](left: () => ImmutableIterator[A], right: () => ImmutableIterator[A]): () => ImmutableIterator[A] = () => (left() match { - case Empty => right() - case NonEmpty(item, middle) => NonEmpty(item, apply(middle, right)) - }); -} - -/** A stateless iterator. - * - * @author Sean McDirmid - * @version 1.0 - * @since 2.4 - */ -sealed abstract class ImmutableIterator[+A] { - - /** queries if this iterator has an element to return. - */ - def hasNext: Boolean - - /** returns the next element and immutable iterator as a pair. - */ - def next: Tuple2[A,ImmutableIterator[A]] - - /** Creates a new immutable iterator that appends item to this immutable - * iterator. - */ - def append[B >: A](item: B): ImmutableIterator[B] = append(item, () => ImmutableIterator.Empty) - - /** Creates a new immutable iterator that appends item and a lazy immutable - * iterator (right) to this immutable iterator. - * - * @param item ... - * @param right ... - * @return ... - */ - def append[B >: A](item: B, right: () => ImmutableIterator[B]): ImmutableIterator[B] = - ImmutableIterator[B](this, item, right) - - /** Creates a new immutable iterator that appends a lazy immutable - * iterator (right) to this immutable iterator. - */ - def append[B >: A](right: () => ImmutableIterator[B]) = - ImmutableIterator(() => this, right)() - - private class Elements extends Iterator[A] { - private[this] var cursor: ImmutableIterator[A] = ImmutableIterator.this - def hasNext = cursor.hasNext - def next = { - val Tuple2(ret,cursor0) = cursor.next - cursor = cursor0 - ret - } - } - - /** Converts this immutable iterator into a conventional iterator. - */ - def iterator: Iterator[A] = new Elements - - @deprecated("use `iterator' instead") def elements = iterator - -} - - - - diff --git a/src/library/scala/collection/immutable/Tree.scala.disabled b/src/library/scala/collection/immutable/Tree.scala.disabled deleted file mode 100644 index 1c1eb17acc..0000000000 --- a/src/library/scala/collection/immutable/Tree.scala.disabled +++ /dev/null @@ -1,440 +0,0 @@ -o/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - -// This is probably no longer needed; replaced by RedBlack.scala -* -/* General Balanced Trees - highly efficient functional dictionaries. -** -** This is a scala version of gb_trees.erl which is -** copyrighted (C) 1999-2001 by Sven-Olof Nystrom, and Richard Carlsson -** -** An efficient implementation of Prof. Arne Andersson's General -** Balanced Trees. These have no storage overhead compared to plain -** unbalanced binary trees, and their performance is in general better -** than AVL trees. -** -** NOTE: This code was until 2007-04-01 under a GPL license. The author has -** given permission to remove that license, so that now this code is under -** the general license for the Scala libraries. -*/ - -package scala.collection.immutable - - -/**

- * General Balanced Trees - highly efficient functional dictionaries. - *

- *

- * An efficient implementation of Prof. Arne Andersson's - * General Balanced Trees. These have no storage overhead - * compared to plain unbalanced binary trees, and their performance is in - * general better than AVL trees. - *

- *

- * This implementation does not balance the trees after deletions. - * Since deletions don't increase the height of a tree, this should - * be OK in most applications. A balance method is provided for those - * cases where rebalancing is needed. - *

- *

- * The tree consists of entries conatining a key with an order. - *

- *

- * When instanciating the tree an order for the keys has to be - * supplied. - *

- * - * @author Erik Stenman, Michel Schinz - * @version 1.1, 2005-01-20 - * @since 1 - */ - -@serializable -abstract class Tree[A <% Ordered[A], B]() extends AnyRef { - /* Data structure: - ** - size:Int - the number of elements in the tree. - ** - tree:T, which is composed of nodes of the form: - ** - GBNode(key: A, entry:B, smaller:T, bigger:T), - ** - and the "empty tree" node GBLeaf. - ** - ** Original balance condition h(T) <= ceil(c * log(|T|)) has been - ** changed to the similar (but not quite equivalent) condition - ** 2 ^ h(T) <= |T| ^ c. - ** - */ - - /** The type returned when creating a new tree. - * This type should be defined by concrete implementations - * e.g.
-   *  class C[T](...) extends Tree[A,B](...) {
-   *    type This = C[T];
-   *  
- */ - protected type This <: Tree[A,B] - protected def getThis: This - - /** - * The type of nodes that the tree is build from. - */ - protected type aNode = GBTree[A,B] - - /** The nodes in the tree. - */ - protected def tree: aNode = GBLeaf[A,B]() - - /**

- * This abstract method should be defined by a concrete implementation - * C[T] as something like: - *

- *
-   *    override def New(sz: Int, t: aNode): This {
-   *      new C[T](order) {
-   *        override def size = sz
-   *        override protected def tree: aNode = t
-   *    }
-   *  
- *

- * The concrete implementation should also override the def of This - * override type This = C[T]; - *

- */ - protected def New(sz: Int, t: aNode): This - - /** The size of the tree, returns 0 (zero) if the tree is empty. - * - * @return The number of nodes in the tree as an integer. - */ - def size: Int = 0 - - /** A new tree with the entry added is returned, - * assuming that key is not in the tree. - * - * @param key ... - * @param entry ... - * @return ... - */ - protected def add(key: A, entry: B): This = { - val newSize = size + 1 - New(newSize, tree.insert(key, entry, newSize * newSize).node) - } - - /** A new tree with the entry added is returned, - * if key is not in the tree, otherwise - * the key is updated with the new entry. - */ - protected def updateOrAdd(key: A, entry: B): This = - if (tree.isDefinedAt(key)) - New(size,tree.update(key,entry)) - else - add(key,entry) - - /** Removes the key from the tree. - * - * @param key ... - * @return ... - */ - protected def deleteAny(key: A): This = - if (tree.isDefinedAt(key)) - delete(key) - else - getThis - - /** Removes the key from the tree, assumimg that key is present. - * - * @param key ... - * @return ... - */ - private def delete(key: A): This = - New(size - 1, tree.delete(key)) - - /** Check if this map maps key to a value and return the - * value if it exists. - * - * @param key the key of the mapping of interest - * @return the value of the mapping, if it exists - */ - protected def findValue(key: A): Option[B] = - tree.get(key) - - /** Gives you an iterator over all elements in the tree. - * The iterator structure corresponds to - * the call stack of an in-order traversal. - * - * Note: The iterator itself has a state, i.e., it is not functional. - */ - protected def entries: Iterator[B] = - new Iterator[B] { - var iter = tree.mk_iter(scala.Nil) - def hasNext = !iter.isEmpty - def next = iter match { - case GBNode(_,v,_,t)::iter_tail => - iter = t.mk_iter(iter_tail) - v - case scala.Nil => - throw new NoSuchElementException("next on empty iterator") - } - } - - /** Create a new balanced tree from the tree. Might be useful to call - * after many deletions, since deletion does not rebalance the tree. - */ - def balance: This = - New(size, tree.balance(size)) -} - -protected abstract class InsertTree[A <% Ordered[A],B]() extends AnyRef { - def insertLeft(k: A, v: B, t: GBTree[A,B]): InsertTree[A,B] - def insertRight(k: A, v: B, t: GBTree[A,B]): InsertTree[A,B] - def node: GBTree[A,B] -} - -/** - * ITree is an internal class used by - * Tree. - */ -private case class ITree[A <% Ordered[A],B](t: GBTree[A,B]) - extends InsertTree[A,B] { - def insertLeft(key: A, value: B, bigger: GBTree[A,B]) = - ITree(GBNode(key, value, t, bigger)) - def insertRight(key: A, value: B, smaller: GBTree[A,B]) = - ITree(GBNode(key, value, smaller, t)) - def node = t -} - -/** - * INode is an internal class used by - * Tree. - */ -private case class INode[A <% Ordered[A],B](t1: GBTree[A,B], - height: Int, - size: Int) - extends InsertTree[A,B] { - def insertLeft(key: A, value: B, bigger: GBTree[A,B]) = - balance_p(GBNode(key, value, t1, bigger), bigger); - def insertRight(key: A, value: B, smaller: GBTree[A,B]) = - balance_p(GBNode(key, value, smaller, t1),smaller); - protected def balance_p(t:GBTree[A,B],subtree:GBTree[A,B]):InsertTree[A,B] = { - val (subHeight, subSize) = subtree.count - val totalHeight = 2 * Math.max(height, subHeight) - val totalSize = size + subSize + 1 - val BalanceHeight = totalSize * totalSize - if (totalHeight > BalanceHeight) ITree(t.balance(totalSize)) - else INode(t, totalHeight, totalSize) - } - def node = t1 -} - -/** - * GBTree is an internal class used by - * Tree. - * - * @author Erik Stenman - * @version 1.0, 2005-01-20 - */ -@serializable -protected abstract class GBTree[A <% Ordered[A],B] extends AnyRef { - type aNode = GBTree[A,B] - type anInsertTree = InsertTree[A,B] - - /** Calculates 2^h, and size, where h is the height of the tree - * and size is the number of nodes in the tree. - */ - def count: (Int,Int) - def isDefinedAt(Key: A): Boolean - def get(key: A): Option[B] - def apply(key: A): B - def update(key: A, value: B): aNode - def insert(key: A, value: B, size: Int): anInsertTree - def toList(acc: List[(A,B)]): List[(A,B)] - def mk_iter(iter_tail: List[aNode]): List[aNode] - def delete(key: A): aNode - def merge(t: aNode): aNode - def takeSmallest: (A,B,aNode) - def balance(s: Int): GBTree[A,B] -} - -private case class GBLeaf[A <% Ordered[A],B]() extends GBTree[A,B] { - def count = (1, 0) - def isDefinedAt(key: A) = false - def get(_key: A) = None - def apply(key: A) = throw new NoSuchElementException("key " + key + " not found") - def update(key: A, value: B) = throw new NoSuchElementException("key " + key + " not found") - def insert(key: A, value: B, s: Int): anInsertTree = { - if (s == 0) - INode(GBNode(key, value, this, this), 1, 1) - else - ITree(GBNode(key, value, this, this)) - } - def toList(acc: List[(A,B)]): List[(A,B)] = acc - def mk_iter(iter_tail: List[GBTree[A,B]]) = iter_tail - def merge(larger: GBTree[A,B]) = larger - def takeSmallest: (A,B, GBTree[A,B]) = - throw new NoSuchElementException("takeSmallest on empty tree") - def delete(_key: A) = throw new NoSuchElementException("Delete on empty tree.") - def balance(s: Int) = this - override def hashCode() = 0 -} - -private case class GBNode[A <% Ordered[A],B](key: A, - value: B, - smaller: GBTree[A,B], - bigger: GBTree[A,B]) - extends GBTree[A,B] { - def count: (Int,Int) = { - val (sHeight, sSize) = smaller.count - val (bHeight, bSize) = bigger.count - val mySize = sSize + bSize + 1 - if (mySize == 1) - (1, mySize) - else - (2 * Math.max(sHeight, bHeight), mySize) - } - - def isDefinedAt(sKey: A): Boolean = - if (sKey < key) smaller.isDefinedAt(sKey) - else if (sKey > key) bigger.isDefinedAt(sKey) - else true - - def get(sKey: A): Option[B] = - if (sKey < key) smaller.get(sKey) - else if (sKey > key) bigger.get(sKey) - else Some(value) - - def apply(sKey: A): B = - if (sKey < key) smaller.apply(sKey) - else if (sKey > key) bigger.apply(sKey) - else value - - def update(newKey: A, newValue: B): aNode = - if (newKey < key) - GBNode(key, value, smaller.update(newKey,newValue), bigger) - else if (newKey > key) - GBNode(key, value, smaller, bigger.update(newKey,newValue)) - else - GBNode(newKey, newValue, smaller, bigger) - - def insert(newKey: A, newValue: B, s: Int): anInsertTree = { - if (newKey < key) - smaller.insert(newKey, newValue, s / 2).insertLeft(key, value, bigger) - else if (newKey > key) - bigger.insert(newKey, newValue, s / 2).insertRight(key, value, smaller) - else - throw new NoSuchElementException("Key exists: " + newKey) - } - - def toList(acc: List[(A,B)]): List[(A,B)] = - smaller.toList((key, value) :: bigger.toList(acc)) - - def mk_iter(iter_tail:List[aNode]):List[aNode] = - smaller.mk_iter(this :: iter_tail) - - def delete(sKey:A):aNode = { - if (sKey < key) - GBNode(key, value, smaller.delete(sKey), bigger) - else if (sKey > key) - GBNode(key, value, smaller, bigger.delete(sKey)) - else - smaller.merge(bigger) - } - - def merge(larger: aNode): GBTree[A,B] = larger match { - case GBLeaf() => - this - case _ => - val (key1, value1, larger1) = larger.takeSmallest - GBNode(key1, value1, this, larger1) - } - - def takeSmallest: (A, B, aNode) = smaller match { - case GBLeaf() => - (key, value, bigger) - case _ => - val (key1, value1, smaller1) = smaller.takeSmallest - (key1, value1, GBNode(key, value, smaller1, bigger)) - } - - /** - * @param s ... - * @return ... - */ - def balance(s: Int): GBTree[A,B] = - balance_list(toList(scala.Nil), s) - - protected def balance_list(list: List[(A,B)], s: Int): GBTree[A,B] = { - val empty = GBLeaf[A,B](); - def bal(list: List[(A,B)], s: Int): (aNode, List[(A,B)]) = { - if (s > 1) { - val sm = s - 1 - val s2 = sm / 2 - val s1 = sm - s2 - val (t1, (k, v) :: l1) = bal(list, s1) - val (t2, l2) = bal(l1, s2) - val t = GBNode(k, v, t1, t2) - (t, l2) - } else if (s == 1) { - val (k,v) :: rest = list - (GBNode(k, v, empty, empty), rest) - } else - (empty, list) - } - bal(list, s)._1 - } - - override def hashCode() = - value.hashCode() + smaller.hashCode() + bigger.hashCode() -} - -/* Here is the e-mail where the Author agreed to the change in license. - -from Erik Stenman -to martin odersky , -date Tue, Apr 29, 2008 at 3:31 PM -subject Re: test -mailed-by chara.epfl.ch -signed-by gmail.com - -Hi Martin, - -I am fine with that change, and since I don't have a scala distribution handy, -I am also fine with you doing the change yourself. Is that OK? - -Sorry for my dead home address, I'll add an English response to it at some time. - -I am doing fine, and my family is also doing fine. -Hope all is well with you too. - -Cheers, -Erik -- Hide quoted text - - -On Tue, Apr 29, 2008 at 3:13 PM, martin odersky wrote: - - Hi Erik, - - I tried to send mail to happi@home.se, but got a response n swedish. I - was sort of guessing from the response that it contained an - alternative e-mail address and tried to send it there. - - Anyway, I hope things are going well with you! - - There was some discussion recently about the license of Tree.scala in - package collection.immutable. It's GPL, whereas the rest of the Scala - library is BSD. It seems this poses problems with Scala being packaged - with Fedora. Would it be OK with you to change the license to the - general one of Scala libraries? You could simply remove the references - to the GPL - license in the code and send it back to me if that's OK with you. On - the other hand, if there's a problem we'll try something else instead. - - All the best - - -- Martin -*/ diff --git a/test/files/jvm/t2470.check b/test/files/jvm/t2470.check new file mode 100644 index 0000000000..11539b2a9f --- /dev/null +++ b/test/files/jvm/t2470.check @@ -0,0 +1 @@ +List(@Action(block=ACTION)) diff --git a/test/files/jvm/t2470/Action.java b/test/files/jvm/t2470/Action.java new file mode 100644 index 0000000000..62c71c43f1 --- /dev/null +++ b/test/files/jvm/t2470/Action.java @@ -0,0 +1,6 @@ +import java.lang.annotation.*; + +@Retention(value=RetentionPolicy.RUNTIME) +public @interface Action { + Task.Scope block() default Task.Scope.ACTION; +} diff --git a/test/files/jvm/t2470/Read_Classfile_2.scala b/test/files/jvm/t2470/Read_Classfile_2.scala new file mode 100644 index 0000000000..07961776dd --- /dev/null +++ b/test/files/jvm/t2470/Read_Classfile_2.scala @@ -0,0 +1,3 @@ +class Read { + val t = Test +} diff --git a/test/files/jvm/t2470/Task.java b/test/files/jvm/t2470/Task.java new file mode 100644 index 0000000000..64004b5867 --- /dev/null +++ b/test/files/jvm/t2470/Task.java @@ -0,0 +1,3 @@ +class Task { + public enum Scope { ACTION, HIKA } +} diff --git a/test/files/jvm/t2470/Test_1.scala b/test/files/jvm/t2470/Test_1.scala new file mode 100644 index 0000000000..00cf287482 --- /dev/null +++ b/test/files/jvm/t2470/Test_1.scala @@ -0,0 +1,11 @@ +object Test { + class Foo { + @Action(block = Task.Scope.ACTION) + def foo = 0 + } + + def main(args: Array[String]) { + val m = classOf[Foo].getDeclaredMethods().find(_.toString.contains("foo")).get + println(m.getAnnotations().toList) + } +} diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check index e47cf8c420..39347cd5db 100644 --- a/test/files/neg/names-defaults-neg.check +++ b/test/files/neg/names-defaults-neg.check @@ -1,4 +1,4 @@ -names-defaults-neg.scala:66: error: not enough arguments for method apply: (a: Int,b: String)(c: Int*)Fact in object Fact. +names-defaults-neg.scala:65: error: not enough arguments for method apply: (a: Int,b: String)(c: Int*)Fact in object Fact. Unspecified value parameter b. val fac = Fact(1)(2, 3) ^ @@ -8,87 +8,84 @@ names-defaults-neg.scala:5: error: type mismatch; test1(b = 2, a = "#") ^ names-defaults-neg.scala:8: error: positional after named argument. - test1(a = 1, "*") - ^ -names-defaults-neg.scala:9: error: positional after named argument. test1(b = "(*", 23) ^ -names-defaults-neg.scala:14: error: reference to x is ambiguous; it is both, a parameter +names-defaults-neg.scala:13: error: reference to x is ambiguous; it is both, a parameter name of the method and the name of a variable currently in scope. test2(x = 1) ^ -names-defaults-neg.scala:16: error: not found: value c +names-defaults-neg.scala:15: error: not found: value c test1(c = 0, b = "joke") ^ -names-defaults-neg.scala:17: error: not found: value m +names-defaults-neg.scala:16: error: not found: value m test7((m = 1)) // named arguments must be top-level assignments ^ -names-defaults-neg.scala:18: error: not found: value m +names-defaults-neg.scala:17: error: not found: value m test7({m = 1}) ^ -names-defaults-neg.scala:19: error: not found: value m +names-defaults-neg.scala:18: error: not found: value m test7 { m = 1 } // no named arguments in argument block ^ -names-defaults-neg.scala:20: error: reference to x is ambiguous; it is both, a parameter +names-defaults-neg.scala:19: error: reference to x is ambiguous; it is both, a parameter name of the method and the name of a variable currently in scope. test8(x = 1) ^ -names-defaults-neg.scala:23: error: parameter specified twice: a +names-defaults-neg.scala:22: error: parameter specified twice: a test1(1, a = 2) ^ -names-defaults-neg.scala:24: error: parameter specified twice: b +names-defaults-neg.scala:23: error: parameter specified twice: b test1(b = 1, b = "2") ^ -names-defaults-neg.scala:27: error: { +names-defaults-neg.scala:26: error: { val x$1: Int(3) = 3; val x$2: Int(1) = 1; Test.this.test3(1, 3) } of type Int does not take parameters test3(b = 3, a = 1)(3) ^ -names-defaults-neg.scala:36: error: ambiguous reference to overloaded definition, +names-defaults-neg.scala:35: error: ambiguous reference to overloaded definition, both method f in object t1 of type (b: String,a: Int)java.lang.String and method f in object t1 of type (a: Int,b: String)java.lang.String match argument types (b: java.lang.String,a: Int) t1.f(b = "dkljf", a = 1) ^ -names-defaults-neg.scala:43: error: ambiguous reference to overloaded definition, +names-defaults-neg.scala:42: error: ambiguous reference to overloaded definition, both method f in object t3 of type (a2: Int)(b: Int)java.lang.String and method f in object t3 of type (a1: Int)java.lang.String match argument types (Int) t3.f(1) ^ -names-defaults-neg.scala:44: error: ambiguous reference to overloaded definition, +names-defaults-neg.scala:43: error: ambiguous reference to overloaded definition, both method f in object t3 of type (a2: Int)(b: Int)java.lang.String and method f in object t3 of type (a1: Int)java.lang.String match argument types (Int) t3.f(1)(2) ^ -names-defaults-neg.scala:50: error: ambiguous reference to overloaded definition, +names-defaults-neg.scala:49: error: ambiguous reference to overloaded definition, both method g in object t7 of type (a: B)java.lang.String and method g in object t7 of type (a: C,b: Int*)java.lang.String match argument types (C) t7.g(new C()) // ambigous reference ^ -names-defaults-neg.scala:54: error: parameter specified twice: b +names-defaults-neg.scala:53: error: parameter specified twice: b test5(a = 1, b = "dkjl", b = "dkj") ^ -names-defaults-neg.scala:55: error: parameter specified twice: b +names-defaults-neg.scala:54: error: parameter specified twice: b test5(1, "2", b = 3) ^ -names-defaults-neg.scala:56: error: when using named arguments, the vararg parameter has to be specified exactly once +names-defaults-neg.scala:55: error: when using named arguments, the vararg parameter has to be specified exactly once test5(b = "dlkj") ^ -names-defaults-neg.scala:62: error: ambiguous reference to overloaded definition, +names-defaults-neg.scala:61: error: ambiguous reference to overloaded definition, both method f in object t8 of type (b: String,a: Int)java.lang.String and method f in object t8 of type (a: Int,b: java.lang.Object)java.lang.String match argument types (a: Int,b: java.lang.String) and expected result type Any println(t8.f(a = 0, b = "1")) // ambigous reference ^ -names-defaults-neg.scala:70: error: wrong number of arguments for : (x: Int,y: String)A1 +names-defaults-neg.scala:69: error: wrong number of arguments for : (x: Int,y: String)A1 A1() match { case A1(_) => () } ^ -names-defaults-neg.scala:77: error: no type parameters for method test4: (x: T[T[List[T[X forSome { type X }]]]])T[T[List[T[X forSome { type X }]]]] exist so that it can be applied to arguments (List[Int]) +names-defaults-neg.scala:76: error: no type parameters for method test4: (x: T[T[List[T[X forSome { type X }]]]])T[T[List[T[X forSome { type X }]]]] exist so that it can be applied to arguments (List[Int]) --- because --- argument expression's type is not compatible with formal parameter type; found : List[Int] @@ -96,15 +93,15 @@ argument expression's type is not compatible with formal parameter type; Error occured in an application involving default arguments. test4() ^ -names-defaults-neg.scala:80: error: type mismatch; +names-defaults-neg.scala:79: error: type mismatch; found : List[Int] required: scala.List[scala.List[?]] def test6[T](x: List[List[T]] = List(1,2)) = x ^ -names-defaults-neg.scala:83: error: type mismatch; +names-defaults-neg.scala:82: error: type mismatch; found : Int required: String Error occured in an application involving default arguments. new A2[String]() ^ -25 errors found +24 errors found diff --git a/test/files/neg/names-defaults-neg.scala b/test/files/neg/names-defaults-neg.scala index 5829da361c..3babd56c6f 100644 --- a/test/files/neg/names-defaults-neg.scala +++ b/test/files/neg/names-defaults-neg.scala @@ -5,7 +5,6 @@ object Test extends Application { test1(b = 2, a = "#") // mixing named and positional - test1(a = 1, "*") test1(b = "(*", 23) // assignment / names diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check index 937f95962b..47d09a5083 100644 --- a/test/files/run/names-defaults.check +++ b/test/files/run/names-defaults.check @@ -18,12 +18,16 @@ get: [ get: 4 get: @ 4: @ +get: 10 +get: flu +10: flu get: 8 get: 9 get: % get: 5 5: %, 17 12: ', 13, 16 +1: bird, swine, 10 6: ~ get: 7 get: + diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index 008939cc9d..d5524b95ab 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -13,8 +13,10 @@ object Test extends Application { // mixing named and positional test1(get(4), b = get("@")) + test1(a = get(10), get("flu")) test2(get(8), v = get(9))(get("%"), l = get(5)) test3(12, 13)("'", d = 16) + test3(a = 1, "swine")(c = "bird", d = 10L) // anonymous functions -- cgit v1.2.3