diff options
author | Paul Phillips <paulp@improving.org> | 2011-12-04 17:43:10 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-12-04 17:43:10 -0800 |
commit | 1ed57a4c19f89bc6736271fd63d465fed405c4d3 (patch) | |
tree | 3a5d7d3d91e326682486bac2acc19c4917381b25 | |
parent | 261c63995ccf6a238786fd3c31796be7a965fec4 (diff) | |
parent | a289465c70630719cbd3a74edf5502a156ef83c4 (diff) | |
download | scala-1ed57a4c19f89bc6736271fd63d465fed405c4d3.tar.gz scala-1ed57a4c19f89bc6736271fd63d465fed405c4d3.tar.bz2 scala-1ed57a4c19f89bc6736271fd63d465fed405c4d3.zip |
Merge branch 'master' into xsbt
70 files changed, 987 insertions, 120 deletions
@@ -201,7 +201,17 @@ PROPERTIES INITIALISATION ============================================================================ --> - <target name="init"> + <condition property="starr.absent"> + <not><available file="${lib.dir}/scala-library.jar"/></not> + </condition> + + <target name="init.starr" if="starr.absent"> + <echo level="warn" message="Downloading bootstrap libs. (To do this by hand, run ./pull-binary-libs.sh)"/> + <exec osfamily="unix" vmlauncher="false" executable="./pull-binary-libs.sh" failifexecutionfails="true" /> + <exec osfamily="windows" vmlauncher="false" executable="pull-binary-libs.sh" failifexecutionfails="true" /> + </target> + + <target name="init" depends="init.starr"> <!-- scalac.args.optimise is selectively overridden in certain antcall tasks. --> <property name="scalac.args.optimise" value=""/> <!-- scalac.args.quickonly are added to quick.* targets but not others (particularly, locker.) @@ -222,10 +232,10 @@ INITIALISATION <os family="windows"/> </condition> - <exec osfamily="unix" executable="tools/get-scala-revision" outputproperty="svn.number" failifexecutionfails="false" /> - <exec osfamily="windows" executable="tools/get-scala-revision.bat" outputproperty="svn.number" failifexecutionfails="false" /> + <exec osfamily="unix" executable="tools/get-scala-revision" outputproperty="git.describe" failifexecutionfails="false" /> + <exec osfamily="windows" executable="tools/get-scala-revision.bat" outputproperty="git.describe" failifexecutionfails="false" /> <!-- some default in case something went wrong getting the revision --> - <property name="svn.number" value="0"/> + <property name="git.describe" value="-unknown-"/> <property name="init.avail" value="yes"/> @@ -233,10 +243,11 @@ INITIALISATION <property file="${basedir}/build.number"/> <property name="version.number" - value="${version.major}.${version.minor}.${version.patch}.r${svn.number}-b${time.short}"/> + value="${version.major}.${version.minor}.${version.patch}.${git.describe}"/> + <!-- And print-out what we are building --> <echo level="info" message="Build number is '${version.number}'"/> - <echo level="info" message="Built ${time.human} from revision ${svn.number} with ${java.vm.name} ${java.version}"/> + <echo level="info" message="Built ${time.human} from revision ${git.describe} with ${java.vm.name} ${java.version}"/> <!-- Local libs (developer use.) --> <mkdir dir="${lib-extra.dir}"/> @@ -639,7 +650,7 @@ QUICK BUILD (QUICK) <scalacfork destdir="${build-quick.dir}/classes/library" compilerpathref="quick.classpath" - params="${scalac.args.quick} -Xplugin-require:continuations -P:continuations:enable" + params="${scalac.args.quick} -Xplugin-require:continuations" srcdir="${src.dir}/continuations/library" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -1154,7 +1165,7 @@ BOOTSTRAPPING BUILD (STRAP) <scalacfork destdir="${build-strap.dir}/classes/library" compilerpathref="pack.classpath" - params="${scalac.args.all} -Xplugin-require:continuations -P:continuations:enable" + params="${scalac.args.all} -Xplugin-require:continuations" srcdir="${src.dir}/continuations/library" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -1614,7 +1625,7 @@ BOOTRAPING TEST AND TEST SUITE <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" timeout="2400000" srcdir="${partest.srcdir}" - scalacopts="${scalac.args.optimise} -Xplugin-require:continuations -P:continuations:enable"> + scalacopts="${scalac.args.optimise} -Xplugin-require:continuations"> <compilerarg value="-Xpluginsdir"/> <compilerarg file="${build-quick.dir}/misc/scala-devel/plugins"/> <compilationpath> diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 6d672d9263..60b353a7c4 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -231,6 +231,8 @@ trait Importers { self: SymbolTable => new PackageDef(importRefTree(pid), stats map importTree) case from.ModuleDef(mods, name, impl) => new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl)) + case from.emptyValDef => + emptyValDef case from.ValDef(mods, name, tpt, rhs) => new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs)) case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) => diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 320fb949ff..265261f594 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -4174,8 +4174,16 @@ A type's typeSymbol should never be inspected directly. private def adaptToNewRun(pre: Type, sym: Symbol): Symbol = { if (phase.flatClasses) { sym + } else if (sym == definitions.RootClass) { + definitions.RootClass + } else if (sym == definitions.RootPackage) { + definitions.RootPackage } else if (sym.isModuleClass) { - adaptToNewRun(pre, sym.sourceModule).moduleClass + val sourceModule1 = adaptToNewRun(pre, sym.sourceModule) + val result = sourceModule1.moduleClass + val msg = "sym = %s, sourceModule = %s, sourceModule.moduleClass = %s => sourceModule1 = %s, sourceModule1.moduleClass = %s" + assert(result != NoSymbol, msg.format(sym, sym.sourceModule, sym.sourceModule.moduleClass, sourceModule1, sourceModule1.moduleClass)) + result } else if ((pre eq NoPrefix) || (pre eq NoType) || sym.isPackageClass) { sym } else { diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 9668debbbb..85849cfad4 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -257,6 +257,10 @@ trait Trees extends reflect.internal.Trees { self: Global => case _: DefTree | Function(_, _) | Template(_, _, _) => resetDef(tree) tree.tpe = null + tree match { + case tree: DefDef => tree.tpt.tpe = null + case _ => () + } case tpt: TypeTree => if (tpt.wasEmpty) tree.tpe = null case This(_) if tree.symbol != null && tree.symbol.isPackageClass => diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index 5e5320ca9a..813958af85 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -563,7 +563,8 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { if (!nameLink.isEmpty) <a href={nameLink}>{nameHtml}</a> else nameHtml - }{ + } + { def tparamsToHtml(mbr: Entity): NodeSeq = mbr match { case hk: HigherKinded => val tpss = hk.typeParams @@ -579,8 +580,8 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { case _ => NodeSeq.Empty } tparamsToHtml(mbr) - }{ - if (isReduced) NodeSeq.Empty else { + } + { if (isReduced) NodeSeq.Empty else { def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = { def param0(vl: ValueParam): NodeSeq = // notice the }{ in the next lines, they are necessary to avoid a undesired withspace in output diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index 7a64fc9b5e..68a53e57a1 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -475,7 +475,7 @@ abstract class LiftCode extends Transform with TypingTransformers { case tt: TypeTree if (tt.tpe != null) => if (!(boundSyms exists (tt.tpe contains _))) mirrorCall("TypeTree", reifyType(tt.tpe)) else if (tt.original != null) reify(tt.original) - else TypeTree() + else mirrorCall("TypeTree") case global.emptyValDef => mirrorSelect("emptyValDef") case _ => diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index d252281002..1d9eb9c292 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -17,13 +17,16 @@ import annotation.tailrec trait Contexts { self: Analyzer => import global._ - val NoContext = new Context { - override def implicitss: List[List[ImplicitInfo]] = List() - outer = this + object NoContext extends Context { + outer = this + enclClass = this + enclMethod = this + + override def nextEnclosing(p: Context => Boolean): Context = this + override def enclosingContextChain: List[Context] = Nil + override def implicitss: List[List[ImplicitInfo]] = Nil override def toString = "NoContext" } - NoContext.enclClass = NoContext - NoContext.enclMethod = NoContext private val startContext = { NoContext.make( @@ -337,7 +340,9 @@ trait Contexts { self: Analyzer => } def nextEnclosing(p: Context => Boolean): Context = - if (this == NoContext || p(this)) this else outer.nextEnclosing(p) + if (p(this)) this else outer.nextEnclosing(p) + + def enclosingContextChain: List[Context] = this :: outer.enclosingContextChain override def toString = "Context(%s@%s unit=%s scope=%s)".format( owner.fullName, tree.shortClass, unit, scope.## diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index b969e9629f..7671ccbed7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -19,6 +19,7 @@ import symtab.Flags._ import util.Statistics import util.Statistics._ import scala.tools.util.StringOps.{ countAsString, countElementsAsString } +import scala.tools.util.EditDistance.similarString // Suggestion check whether we can do without priming scopes with symbols of outer scopes, // like the IDE does. @@ -3457,12 +3458,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (treeInfo.isVariableOrGetter(qual1)) { stopTimer(failedOpEqNanos, opeqStart) convertToAssignment(fun, qual1, name, args, ex) - } else { + } + else { stopTimer(failedApplyNanos, appStart) - if ((qual1.symbol ne null) && qual1.symbol.isValue) - error(tree.pos, "reassignment to val") - else - reportTypeError(fun.pos, ex) + reportTypeError(fun.pos, ex) setError(tree) } case _ => @@ -3754,7 +3753,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { defSym = EmptyPackageClass.tpe.nonPrivateMember(name) defSym != NoSymbol } - + def startingIdentContext = ( + // ignore current variable scope in patterns to enforce linearity + if ((mode & (PATTERNmode | TYPEPATmode)) == 0) context + else context.outer + ) // A symbol qualifies if it exists and is not stale. Stale symbols // are made to disappear here. In addition, // if we are in a constructor of a pattern, we ignore all definitions @@ -3770,13 +3773,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (defSym == NoSymbol) { var defEntry: ScopeEntry = null // the scope entry of defSym, if defined in a local scope - var cx = context - if ((mode & (PATTERNmode | TYPEPATmode)) != 0) { - // println("ignoring scope: "+name+" "+cx.scope+" "+cx.outer.scope) - // ignore current variable scope in patterns to enforce linearity - cx = cx.outer - } - + var cx = startingIdentContext while (defSym == NoSymbol && cx != NoContext) { currentRun.compileSourceFor(context.asInstanceOf[analyzer.Context], name) pre = cx.enclClass.prefix @@ -3874,7 +3871,26 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (inaccessibleSym eq NoSymbol) { // Avoiding some spurious error messages: see SI-2388. if (reporter.hasErrors && (name startsWith tpnme.ANON_CLASS_NAME)) () - else error(tree.pos, "not found: "+decodeWithKind(name, context.owner)) + else { + val similar = ( + // name length check to limit unhelpful suggestions for e.g. "x" and "b1" + if (name.length > 2) { + val allowed = ( + startingIdentContext.enclosingContextChain + flatMap (ctx => ctx.scope.toList ++ ctx.imports.flatMap(_.allImportedSymbols)) + filter (sym => sym.isTerm == name.isTermName) + filterNot (sym => sym.isPackage || sym.isSynthetic || sym.hasMeaninglessName) + ) + val allowedStrings = ( + allowed.map("" + _.name).distinct.sorted + filterNot (s => (s contains '$') || (s contains ' ')) + ) + similarString("" + name, allowedStrings) + } + else "" + ) + error(tree.pos, "not found: "+decodeWithKind(name, context.owner) + similar) + } } else new AccessError( tree, inaccessibleSym, context.enclClass.owner.thisType, diff --git a/src/compiler/scala/tools/util/EditDistance.scala b/src/compiler/scala/tools/util/EditDistance.scala new file mode 100644 index 0000000000..a8d7408532 --- /dev/null +++ b/src/compiler/scala/tools/util/EditDistance.scala @@ -0,0 +1,54 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package util + +object EditDistance { + def similarString(name: String, allowed: TraversableOnce[String]): String = { + val suggested = suggestions(name, allowed.toSeq, maxDistance = 1, maxSuggestions = 2) + if (suggested.isEmpty) "" + else suggested.mkString(" (similar: ", ", ", ")") + } + + def suggestions(a: String, bs: Seq[String], maxDistance: Int, maxSuggestions: Int): Seq[String] = ( + bs map (b => (b, distance(a, b))) + filter (_._2 <= maxDistance) + sortBy (_._2) + take (maxSuggestions) + map (_._1) + ) + + def distance(a: String, b: String): Int = levenshtein(a, b, transpositions = true) + + def levenshtein(s: String, t: String, transpositions: Boolean): Int = { + val n = s.length + val m = t.length + if (n == 0) return m + if (m == 0) return n + + val d = Array.ofDim[Int](n + 1, m + 1) + 0 to n foreach (x => d(x)(0) = x) + 0 to m foreach (x => d(0)(x) = x) + + for (i <- 1 to n ; val s_i = s(i - 1) ; j <- 1 to m) { + val t_j = t(j - 1) + val cost = if (s_i == t_j) 0 else 1 + + val c1 = d(i - 1)(j) + 1 + val c2 = d(i)(j - 1) + 1 + val c3 = d(i - 1)(j - 1) + cost + + d(i)(j) = c1 min c2 min c3 + + if (transpositions) { + if (i > 1 && j > 1 && s(i - 1) == t(j - 2) && s(i - 2) == t(j - 1)) + d(i)(j) = d(i)(j) min (d(i - 2)(j - 2) + cost) + } + } + + d(n)(m) + } +} diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala index 5cb06d42db..f4481b800e 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala @@ -9,7 +9,7 @@ trait CPSUtils { import global._ import definitions._ - var cpsEnabled = false + var cpsEnabled = true val verbose: Boolean = System.getProperty("cpsVerbose", "false") == "true" def vprintln(x: =>Any): Unit = if (verbose) println(x) diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala index 8a500d6c4d..eb18f03748 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala @@ -26,7 +26,6 @@ class SelectiveCPSPlugin(val global: Global) extends Plugin { override val runsBefore = List("uncurry") } - val components = List[PluginComponent](anfPhase, cpsPhase) val checker = new CPSAnnotationChecker { @@ -43,19 +42,17 @@ class SelectiveCPSPlugin(val global: Global) extends Plugin { } // TODO: require -enabled command-line flag - override def processOptions(options: List[String], error: String => Unit) = { - var enabled = false - for (option <- options) { - if (option == "enable") { - enabled = true - } else { - error("Option not understood: "+option) - } + var enabled = true + options foreach { + case "enable" => enabled = true + case "disable" => enabled = false + case option => error("Option not understood: "+option) } setEnabled(enabled) } - override val optionsHelp: Option[String] = - Some(" -P:continuations:enable Enable continuations") + override val optionsHelp: Option[String] = { + Some(" -P:continuations:disable Disable continuations plugin") + } } diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index 07e758013c..c967a48abc 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -8,7 +8,7 @@ package scala -import scala.collection.{ mutable, immutable, generic, SetLike, AbstractSet } +import scala.collection.{ mutable, immutable, generic, SortedSetLike, AbstractSet } import java.lang.reflect.{ Modifier, Method => JMethod, Field => JField } import scala.reflect.NameTransformer._ import java.util.regex.Pattern @@ -53,10 +53,14 @@ import java.util.regex.Pattern * @author Matthias Zenger */ @SerialVersionUID(8476000850333817230L) -abstract class Enumeration(initial: Int, names: String*) extends Serializable { +abstract class Enumeration(initial: Int, + @deprecated("Names should be specified individually or discovered via reflection", "2.10") + names: String*) extends Serializable { thisenum => def this() = this(0) + + @deprecated("Names should be specified individually or discovered via reflection", "2.10") def this(names: String*) = this(0, names: _*) /* Note that `readResolve` cannot be private, since otherwise @@ -86,7 +90,7 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { */ def values: ValueSet = { if (!vsetDefined) { - vset = new ValueSet(immutable.SortedSet.empty[Int] ++ (vmap.values map (_.id))) + vset = (ValueSet.newBuilder ++= vmap.values).result() vsetDefined = true } vset @@ -104,6 +108,10 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { * enumeration. */ private var topId = initial + /** The lowest integer amongst those used to identify values in this + * enumeration, but no higher than 0. */ + private var bottomId = if(initial < 0) initial else 0 + /** The highest integer amongst those used to identify values in this * enumeration. */ final def maxId = topId @@ -200,6 +208,9 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { case _ => false } override def hashCode: Int = id.## + + /** Create a ValueSet which contains this value and another one */ + def + (v: Value) = ValueSet(this, v) } /** A class implementing the [[scala.Enumeration.Value]] type. This class @@ -217,6 +228,7 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { vsetDefined = false nextId = i + 1 if (nextId > topId) topId = nextId + if (i < bottomId) bottomId = i def id = i override def toString() = if (name != null) name @@ -230,34 +242,56 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { } } + /** An ordering by id for values of this set */ + object ValueOrdering extends Ordering[Value] { + def compare(x: Value, y: Value): Int = x.id - y.id + } + /** A class for sets of values. * Iterating through this set will yield values in increasing order of their ids. * - * @param ids The set of ids of values, organized as a `SortedSet`. + * @param nnIds The set of ids of values (adjusted so that the lowest value does + * not fall below zero), organized as a `BitSet`. */ - class ValueSet private[Enumeration] (val ids: immutable.SortedSet[Int]) + class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet) extends AbstractSet[Value] - with Set[Value] - with SetLike[Value, ValueSet] { + with immutable.SortedSet[Value] + with SortedSetLike[Value, ValueSet] + with Serializable { + + implicit def ordering: Ordering[Value] = ValueOrdering + def rangeImpl(from: Option[Value], until: Option[Value]): ValueSet = + new ValueSet(nnIds.rangeImpl(from.map(_.id - bottomId), until.map(_.id - bottomId))) override def empty = ValueSet.empty - def contains(v: Value) = ids contains (v.id) - def + (value: Value) = new ValueSet(ids + value.id) - def - (value: Value) = new ValueSet(ids - value.id) - def iterator = ids.iterator map thisenum.apply + def contains(v: Value) = nnIds contains (v.id - bottomId) + def + (value: Value) = new ValueSet(nnIds + (value.id - bottomId)) + def - (value: Value) = new ValueSet(nnIds - (value.id - bottomId)) + def iterator = nnIds.iterator map (id => thisenum.apply(id + bottomId)) override def stringPrefix = thisenum + ".ValueSet" + /** Creates a bit mask for the zero-adjusted ids in this set as a + * new array of longs */ + def toBitMask: Array[Long] = nnIds.toBitMask } - + /** A factory object for value sets */ object ValueSet { import generic.CanBuildFrom /** The empty value set */ - val empty = new ValueSet(immutable.SortedSet.empty) + val empty = new ValueSet(immutable.BitSet.empty) /** A value set consisting of given elements */ - def apply(elems: Value*): ValueSet = empty ++ elems + def apply(elems: Value*): ValueSet = (newBuilder ++= elems).result() + /** A value set containing all the values for the zero-adjusted ids + * corresponding to the bits in an array */ + def fromBitMask(elems: Array[Long]): ValueSet = new ValueSet(immutable.BitSet.fromBitMask(elems)) /** A builder object for value sets */ - def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.SetBuilder(empty) + def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.Builder[Value, ValueSet] { + private[this] val b = new mutable.BitSet + def += (x: Value) = { b += (x.id - bottomId); this } + def clear() = b.clear + def result() = new ValueSet(b.toImmutable) + } /** The implicit builder for value sets */ implicit def canBuildFrom: CanBuildFrom[ValueSet, Value, ValueSet] = new CanBuildFrom[ValueSet, Value, ValueSet] { diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index b3dd4764a9..63e9543711 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -276,6 +276,8 @@ trait GenSeqLike[+A, +Repr] extends GenIterableLike[A, Repr] with Equals with Pa /** A copy of the $coll with an element prepended. * * Note that :-ending operators are right associative (see example). + * A mnemonic for `+:` vs. `:+` is: the COLon goes on the COLlection side. + * * Also, the original $coll is not modified, so you will want to capture the result. * * Example: @@ -304,6 +306,8 @@ trait GenSeqLike[+A, +Repr] extends GenIterableLike[A, Repr] with Equals with Pa /** A copy of this $coll with an element appended. * + * A mnemonic for `+:` vs. `:+` is: the COLon goes on the COLlection side. + * * $willNotTerminateInf * @param elem the appended element * @tparam B the element type of the returned $coll. diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index 6fa05bd85b..4f0fec1de3 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -159,8 +159,10 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr] /** As with `++`, returns a new collection containing the elements from the left operand followed by the * elements from the right operand. + * * It differs from `++` in that the right operand determines the type of * the resulting collection rather than the left one. + * Mnemonic: the COLon is on the side of the new COLlection type. * * Example: * {{{ @@ -195,8 +197,10 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr] /** As with `++`, returns a new collection containing the elements from the * left operand followed by the elements from the right operand. + * * It differs from `++` in that the right operand determines the type of * the resulting collection rather than the left one. + * Mnemonic: the COLon is on the side of the new COLlection type. * * Example: * {{{ diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 47ce2f0341..3736096f36 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -211,6 +211,13 @@ extends collection.AbstractSeq[Int] final def contains(x: Int) = isWithinBoundaries(x) && ((x - start) % step == 0) + final override def sum[B >: Int](implicit num: Numeric[B]): Int = { + val len = length + if (len == 0) 0 + else if (len == 1) head + else (len.toLong * (head + last) / 2).toInt + } + override def toIterable = this override def toSeq = this diff --git a/src/library/scala/math/package.scala b/src/library/scala/math/package.scala index 8948722340..0417461f85 100644 --- a/src/library/scala/math/package.scala +++ b/src/library/scala/math/package.scala @@ -127,15 +127,9 @@ package object math { else if (x > 0) 1.0f else x // NaN - def signum(x: Long): Long = - if (x == 0l) 0l - else if (x < 0) -1l - else 1l - - def signum(x: Int): Int = - if (x == 0) 0 - else if (x < 0) -1 - else 1 + def signum(x: Long): Long = java.lang.Long.signum(x) + + def signum(x: Int): Int = java.lang.Integer.signum(x) // ----------------------------------------------------------------------- // root functions diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala index e7ea9f598b..751539243b 100644 --- a/src/library/scala/util/parsing/combinator/Parsers.scala +++ b/src/library/scala/util/parsing/combinator/Parsers.scala @@ -108,6 +108,8 @@ trait Parsers { def flatMapWithNext[U](f: T => Input => ParseResult[U]): ParseResult[U] + def filterWithError(p: T => Boolean, error: T => String, position: Input): ParseResult[T] + def append[U >: T](a: => ParseResult[U]): ParseResult[U] def isEmpty = !successful @@ -137,6 +139,10 @@ trait Parsers { def flatMapWithNext[U](f: T => Input => ParseResult[U]): ParseResult[U] = f(result)(next) + def filterWithError(p: T => Boolean, error: T => String, position: Input): ParseResult[T] = + if (p(result)) this + else Failure(error(result), position) + def append[U >: T](a: => ParseResult[U]): ParseResult[U] = this def get: T = result @@ -161,6 +167,8 @@ trait Parsers { def flatMapWithNext[U](f: Nothing => Input => ParseResult[U]): ParseResult[U] = this + def filterWithError(p: Nothing => Boolean, error: Nothing => String, position: Input): ParseResult[Nothing] = this + def get: Nothing = sys.error("No result when parsing failed") } /** An extractor so `NoSuccess(msg, next)` can be used in matches. */ @@ -224,6 +232,12 @@ trait Parsers { def map[U](f: T => U): Parser[U] //= flatMap{x => success(f(x))} = Parser{ in => this(in) map(f)} + def filter(p: T => Boolean): Parser[T] + = withFilter(p) + + def withFilter(p: T => Boolean): Parser[T] + = Parser{ in => this(in) filterWithError(p, "Input doesn't match filter: "+_, in)} + // no filter yet, dealing with zero is tricky! @migration(2, 9, "As of 2.9, the call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.") @@ -443,6 +457,62 @@ trait Parsers { * @return opt(this) */ def ? = opt(this) + + /** Changes the failure message produced by a parser. + * + * This doesn't change the behavior of a parser on neither + * success nor error, just on failure. The semantics are + * slightly different than those obtained by doing `| failure(msg)`, + * in that the message produced by this method will always + * replace the message produced, which is not guaranteed + * by that idiom. + * + * For example, parser `p` below will always produce the + * designated failure message, while `q` will not produce + * it if `sign` is parsed but `number` is not. + * + * {{{ + * def p = sign.? ~ number withFailureMessage "Number expected!" + * def q = sign.? ~ number | failure("Number expected!") + * }}} + * + * @param msg The message that will replace the default failure message. + * @return A parser with the same properties and different failure message. + */ + def withFailureMessage(msg: String) = Parser{ in => + this(in) match { + case Failure(_, next) => Failure(msg, next) + case other => other + } + } + + /** Changes the error message produced by a parser. + * + * This doesn't change the behavior of a parser on neither + * success nor failure, just on error. The semantics are + * slightly different than those obtained by doing `| error(msg)`, + * in that the message produced by this method will always + * replace the message produced, which is not guaranteed + * by that idiom. + * + * For example, parser `p` below will always produce the + * designated error message, while `q` will not produce + * it if `sign` is parsed but `number` is not. + * + * {{{ + * def p = sign.? ~ number withErrorMessage "Number expected!" + * def q = sign.? ~ number | error("Number expected!") + * }}} + * + * @param msg The message that will replace the default error message. + * @return A parser with the same properties and different error message. + */ + def withErrorMessage(msg: String) = Parser{ in => + this(in) match { + case Error(_, next) => Error(msg, next) + case other => other + } + } } /** Wrap a parser so that its failures become errors (the `|` combinator diff --git a/test/files/jvm/signum.scala b/test/files/jvm/signum.scala new file mode 100644 index 0000000000..feb28d3e43 --- /dev/null +++ b/test/files/jvm/signum.scala @@ -0,0 +1,15 @@ +object Test { + def main(args: Array[String]) { + assert(math.signum(Long.MaxValue) == 1L) + assert(math.signum(1L) == 1L) + assert(math.signum(0L) == 0L) + assert(math.signum(-1L) == -1L) + assert(math.signum(Long.MinValue) == -1L) + + assert(math.signum(Int.MaxValue) == 1) + assert(math.signum(1) == 1) + assert(math.signum(0) == 0) + assert(math.signum(-1) == -1) + assert(math.signum(Int.MinValue) == -1) + } +} diff --git a/test/files/neg/nopredefs.check b/test/files/neg/nopredefs.check index 0a0ab34482..e6c1af78a0 100644 --- a/test/files/neg/nopredefs.check +++ b/test/files/neg/nopredefs.check @@ -1,4 +1,4 @@ -nopredefs.scala:5: error: not found: value Set +nopredefs.scala:5: error: not found: value Set (similar: Seq) val y = Set(3) ^ one error found diff --git a/test/files/neg/reassignment.check b/test/files/neg/reassignment.check new file mode 100644 index 0000000000..f0effd1459 --- /dev/null +++ b/test/files/neg/reassignment.check @@ -0,0 +1,13 @@ +reassignment.scala:2: error: not found: value x + x = 5 + ^ +reassignment.scala:3: error: not found: value y + y := 45 + ^ +reassignment.scala:4: error: not found: value y + y += 45 + ^ +reassignment.scala:6: error: reassignment to val + z = 51 + ^ +four errors found diff --git a/test/files/neg/reassignment.scala b/test/files/neg/reassignment.scala new file mode 100644 index 0000000000..e31eefbf3f --- /dev/null +++ b/test/files/neg/reassignment.scala @@ -0,0 +1,7 @@ +class A { + x = 5 + y := 45 + y += 45 + val z = 50 + z = 51 +}
\ No newline at end of file diff --git a/test/files/neg/suggest-similar.check b/test/files/neg/suggest-similar.check new file mode 100644 index 0000000000..0a858aaf2e --- /dev/null +++ b/test/files/neg/suggest-similar.check @@ -0,0 +1,10 @@ +suggest-similar.scala:8: error: not found: value flippitx (similar: flippity) + flippitx = 123 + ^ +suggest-similar.scala:9: error: not found: value identiyt (similar: identity) + Nil map identiyt + ^ +suggest-similar.scala:10: error: not found: type Bingus (similar: Dingus) + new Bingus + ^ +three errors found diff --git a/test/files/neg/suggest-similar.scala b/test/files/neg/suggest-similar.scala new file mode 100644 index 0000000000..ff327478fe --- /dev/null +++ b/test/files/neg/suggest-similar.scala @@ -0,0 +1,11 @@ +class Dingus +object Dingus { + var flippity = 1 +} +import Dingus._ + +class A { + flippitx = 123 + Nil map identiyt + new Bingus +} diff --git a/test/files/neg/t0903.check b/test/files/neg/t0903.check index db4cd94d2c..2dd05cd3ee 100644 --- a/test/files/neg/t0903.check +++ b/test/files/neg/t0903.check @@ -1,4 +1,4 @@ -t0903.scala:3: error: reassignment to val +t0903.scala:3: error: value += is not a member of Int x += 1 ^ t0903.scala:4: error: reassignment to val diff --git a/test/files/neg/t2870.check b/test/files/neg/t2870.check index 6577577d3f..72bc0d98a1 100644 --- a/test/files/neg/t2870.check +++ b/test/files/neg/t2870.check @@ -1,4 +1,4 @@ -t2870.scala:1: error: not found: type Jar +t2870.scala:1: error: not found: type Jar (similar: Jars) class Jars(jar: Jar) ^ t2870.scala:6: error: illegal cyclic reference involving value <import> diff --git a/test/files/pos/t4758.scala b/test/files/pos/t4758.scala new file mode 100644 index 0000000000..627dfd7a23 --- /dev/null +++ b/test/files/pos/t4758.scala @@ -0,0 +1,17 @@ +// /scala/trac/4758/a.scala +// Fri Dec 2 13:41:54 PST 2011 + +package bar { + // works + trait M[F[_]] + class S[X[_] <: M[X], A](val x:X[A]) + object S { + def apply[X[_] <: M[X], A](x: X[A]): S[X, A] = new S[X, A](x) + def unapply[X[_] <: M[X], A](p: S[X, A]) = Some(p.x) + } +} +package foo { + // seemingly equivalent, doesn't work + trait M[F[_]] + case class S[X[_] <: M[X], A](x: X[A]) +} diff --git a/test/files/pos/t5084.scala b/test/files/pos/t5084.scala new file mode 100644 index 0000000000..17d0a68adf --- /dev/null +++ b/test/files/pos/t5084.scala @@ -0,0 +1,5 @@ +case class Search(tpe: Search.Value) + +object Search { + type Value = String +} diff --git a/test/files/run/enums.check b/test/files/run/enums.check index f53aba8794..93eadae6e3 100644 --- a/test/files/run/enums.check +++ b/test/files/run/enums.check @@ -3,3 +3,13 @@ test Test2 was successful test Test3 was successful test Test4 was successful +D1.ValueSet(North, East) +D2.ValueSet(North, East) +D1.ValueSet(North, East, West) +D2.ValueSet(North, East, West) +List(101) +List(101) +D1.ValueSet(North, East) +D2.ValueSet(North, East) +WeekDays.ValueSet(Tue, Wed, Thu, Fri) + diff --git a/test/files/run/enums.scala b/test/files/run/enums.scala index 6dda8cbc6e..9cdeed2691 100644 --- a/test/files/run/enums.scala +++ b/test/files/run/enums.scala @@ -65,6 +65,58 @@ object Test4 { } } +object Test5 { + + object D1 extends Enumeration(0) { + val North, South, East, West = Value; + } + + object D2 extends Enumeration(-2) { + val North, South, East, West = Value; + } + + object WeekDays extends Enumeration { + val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value + } + + def run { + val s1 = D1.ValueSet(D1.North, D1.East) + val s2 = D2.North + D2.East + println(s1) + println(s2) + println(s1 + D1.West) + println(s2 + D2.West) + println(s1.toBitMask.map(_.toBinaryString).toList) + println(s2.toBitMask.map(_.toBinaryString).toList) + println(D1.ValueSet.fromBitMask(s1.toBitMask)) + println(D2.ValueSet.fromBitMask(s2.toBitMask)) + println(WeekDays.values.range(WeekDays.Tue, WeekDays.Sat)) + } +} + +object SerializationTest { + object Types extends Enumeration { val X, Y = Value } + class A extends java.io.Serializable { val types = Types.values } + class B extends java.io.Serializable { val types = Set(Types.X, Types.Y) } + + def serialize(obj: AnyRef) = { + val baos = new java.io.ByteArrayOutputStream() + val oos = new java.io.ObjectOutputStream(baos) + oos.writeObject(obj) + oos.close() + val bais = new java.io.ByteArrayInputStream(baos.toByteArray) + val ois = new java.io.ObjectInputStream(bais) + val prime = ois.readObject() + ois.close() + prime + } + + def run { + serialize(new B()) + serialize(new A()) + } +} + //############################################################################ // Test code @@ -94,6 +146,9 @@ object Test { check_success("Test3", Test3.run, 1); check_success("Test4", Test4.run, 0); Console.println; + Test5.run; + Console.println; + SerializationTest.run; } } diff --git a/test/files/run/parserFilter.check b/test/files/run/parserFilter.check new file mode 100644 index 0000000000..be04454426 --- /dev/null +++ b/test/files/run/parserFilter.check @@ -0,0 +1,9 @@ +[1.3] failure: Input doesn't match filter: false + +if false + ^ +[1.1] failure: Input doesn't match filter: not + +not true +^ +[1.8] parsed: (if~true) diff --git a/test/files/run/parserFilter.scala b/test/files/run/parserFilter.scala new file mode 100644 index 0000000000..d007d441f4 --- /dev/null +++ b/test/files/run/parserFilter.scala @@ -0,0 +1,15 @@ +object Test extends scala.util.parsing.combinator.RegexParsers { + val keywords = Set("if", "false") + def word: Parser[String] = "\\w+".r + + def keyword: Parser[String] = word filter (keywords.contains) + def ident: Parser[String] = word filter(!keywords.contains(_)) + + def test = keyword ~ ident + + def main(args: Array[String]) { + println(parseAll(test, "if false")) + println(parseAll(test, "not true")) + println(parseAll(test, "if true")) + } +} diff --git a/test/files/run/parserForFilter.check b/test/files/run/parserForFilter.check new file mode 100644 index 0000000000..a53c147719 --- /dev/null +++ b/test/files/run/parserForFilter.check @@ -0,0 +1 @@ +[1.13] parsed: (second,first) diff --git a/test/files/run/parserForFilter.scala b/test/files/run/parserForFilter.scala new file mode 100644 index 0000000000..1bc44f8033 --- /dev/null +++ b/test/files/run/parserForFilter.scala @@ -0,0 +1,12 @@ +object Test extends scala.util.parsing.combinator.RegexParsers { + def word: Parser[String] = "\\w+".r + + def twoWords = for { + (a ~ b) <- word ~ word + } yield (b, a) + + def main(args: Array[String]) { + println(parseAll(twoWords, "first second")) + } +} + diff --git a/test/files/run/parserNoSuccessMessage.check b/test/files/run/parserNoSuccessMessage.check new file mode 100644 index 0000000000..fe00d2fd3a --- /dev/null +++ b/test/files/run/parserNoSuccessMessage.check @@ -0,0 +1,20 @@ +[1.2] failure: string matching regex `\d+' expected but `x' found + +-x + ^ +[1.1] failure: string matching regex `\d+' expected but `x' found + +x +^ +[1.3] parsed: (Some(-)~5) +[1.2] parsed: (None~5) +[1.2] error: Number expected! + +-x + ^ +[1.1] error: Number expected! + +x +^ +[1.3] parsed: (Some(-)~5) +[1.2] parsed: (None~5) diff --git a/test/files/run/parserNoSuccessMessage.scala b/test/files/run/parserNoSuccessMessage.scala new file mode 100644 index 0000000000..93aa252db0 --- /dev/null +++ b/test/files/run/parserNoSuccessMessage.scala @@ -0,0 +1,19 @@ +object Test extends scala.util.parsing.combinator.RegexParsers { + def sign = "-" + def number = "\\d+".r + def p = sign.? ~ number withErrorMessage "Number expected!" + def q = sign.? ~! number withErrorMessage "Number expected!" + + def main(args: Array[String]) { + println(parseAll(p, "-x")) + println(parseAll(p, "x")) + println(parseAll(p, "-5")) + println(parseAll(p, "5")) + println(parseAll(q, "-x")) + println(parseAll(q, "x")) + println(parseAll(q, "-5")) + println(parseAll(q, "5")) + } +} + + diff --git a/test/files/run/reify_anonymous.check b/test/files/run/reify_anonymous.check new file mode 100644 index 0000000000..b8626c4cff --- /dev/null +++ b/test/files/run/reify_anonymous.check @@ -0,0 +1 @@ +4 diff --git a/test/files/run/reify_anonymous.scala b/test/files/run/reify_anonymous.scala new file mode 100644 index 0000000000..1e7f3fe856 --- /dev/null +++ b/test/files/run/reify_anonymous.scala @@ -0,0 +1,14 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + println(new {def x = 2; def y = x * x}.y) + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/files/run/reify_generic.check b/test/files/run/reify_generic.check new file mode 100644 index 0000000000..b8626c4cff --- /dev/null +++ b/test/files/run/reify_generic.check @@ -0,0 +1 @@ +4 diff --git a/test/files/run/reify_generic.scala b/test/files/run/reify_generic.scala new file mode 100644 index 0000000000..aef038b2d8 --- /dev/null +++ b/test/files/run/reify_generic.scala @@ -0,0 +1,15 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + val product = List(1, 2, 3).head * List[Any](4, 2, 0).head.asInstanceOf[Int] + println(product) + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/files/run/reify_inheritance.check b/test/files/run/reify_inheritance.check new file mode 100644 index 0000000000..25bf17fc5a --- /dev/null +++ b/test/files/run/reify_inheritance.check @@ -0,0 +1 @@ +18
\ No newline at end of file diff --git a/test/files/run/reify_inheritance.scala b/test/files/run/reify_inheritance.scala new file mode 100644 index 0000000000..2a1b5f764f --- /dev/null +++ b/test/files/run/reify_inheritance.scala @@ -0,0 +1,23 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + class C { + def x = 2 + def y = x * x + } + + class D extends C { + override def x = 3 + } + + println(new D().y * new C().x) + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/files/run/reify_printf.check b/test/files/run/reify_printf.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/run/reify_printf.check diff --git a/test/files/run/reify_printf.scala b/test/files/run/reify_printf.scala new file mode 100644 index 0000000000..30901b98c2 --- /dev/null +++ b/test/files/run/reify_printf.scala @@ -0,0 +1,75 @@ +import java.io.{ ByteArrayOutputStream, PrintStream } +import scala.reflect.Code +import scala.reflect.mirror._ +import scala.reflect.api._ +import scala.reflect.api.Trees +import scala.reflect.internal.Types +import reflect.runtime.Mirror.ToolBox +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import scala.util.matching.Regex + +object Test extends App { + val tree = tree_printf(Code.lift("hello %s").tree, Code.lift("world").tree) + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter, args mkString " ") + val ttree = toolbox.typeCheck(tree) + + val output = new ByteArrayOutputStream() + Console.setOut(new PrintStream(output)) + val evaluated = toolbox.runExpr(ttree) + + assert(output.toString() == "hello world", output.toString() +" == hello world") + + /* + macro def printf(format: String, params: Any*) : String = tree_printf(format: Tree, (params: Seq[Tree]): _*) + */ + + var i = 0 + def gensym(name: String) = { i += 1; newTermName(name + i) } + + def createTempValDef( value : Tree, tpe : Type ) : (Option[Tree],Tree) = { + val local = gensym("temp") + ( + Some( + ValDef( + Modifiers() + , local + , TypeTree().setType(tpe) + , value + ) + ) + , Ident(local) + ) + } + + def tree_printf(format: Tree, params: Tree*) = { + val Literal(Constant(s_format: String)) = format + val paramsStack = scala.collection.mutable.Stack(params: _*) + val parsed = s_format.split("(?<=%[\\w%])|(?=%[\\w%])") map { + case "%d" => createTempValDef( paramsStack.pop, classToType(classOf[Int]) ) + case "%s" => createTempValDef( paramsStack.pop, classToType(classOf[String]) ) + case "%%" => { + (None:Option[Tree], Literal(Constant("%"))) + } + case part => { + (None:Option[Tree], Literal(Constant(part))) + } + } + + val evals = for ((Some(eval), _) <- parsed if eval != None) yield (eval: Tree) + val prints = for ((_, ref) <- parsed) yield + Apply( + Select( + Select( + Ident( newTermName("scala") ) + , newTermName("Predef") + ) + , newTermName("print") + ) + , List(ref) + ): Tree + Block((evals ++ prints).toList, Literal(Constant(()))) + } +} diff --git a/test/files/run/t4658.check b/test/files/run/t4658.check new file mode 100644 index 0000000000..743b0faee3 --- /dev/null +++ b/test/files/run/t4658.check @@ -0,0 +1,80 @@ +Ranges: +1073741824 +1073741824 +0 +0 +55 +25 +1 +-45 +-55 +0 +-24 +-30 +0 +-40 +-55 +-10 +-24 +-30 +-10 +IntRanges: +Disabled #1 +Disabled #2 +0 +0 +55 +25 +1 +-45 +-55 +0 +-24 +-30 +0 +-40 +-55 +-10 +-24 +-30 +-10 +LongRanges: +Disabled #1 +Disabled #2 +0 +0 +55 +25 +1 +-45 +-55 +0 +-24 +-30 +0 +-40 +-55 +-10 +-24 +-30 +-10 +BigIntRanges: +Disabled #1 +Disabled #2 +0 +0 +55 +25 +1 +-45 +-55 +0 +-24 +-30 +0 +-40 +-55 +-10 +-24 +-30 +-10 diff --git a/test/files/run/t4658.scala b/test/files/run/t4658.scala new file mode 100644 index 0000000000..e1799fae9b --- /dev/null +++ b/test/files/run/t4658.scala @@ -0,0 +1,41 @@ +import scala.collection.immutable.NumericRange +//#4658 +object Test { + + case class R(start: Int, end: Int, step: Int = 1, inclusive: Boolean = true) + + val rangeData = Array( + R(1, Int.MaxValue), R(-Int.MaxValue, -1), R(0, 0), R(0,0, inclusive = false), R(1,10), + R(1,10,2), R(1,10,11), R(-10, -5), R(-10, 0), R(-10, 10), R(-10, -5, 2), R(-10, 0, 2), R(-10, 10, 2), + R(-10, -5, inclusive = false), R(-10, 0, inclusive = false), R(-10, 10, inclusive = false), + R(-10, -5, 2, inclusive = false), R(-10, 0, 2, inclusive = false), R(-10, 10, 2, inclusive = false) + ) + + def ranges = rangeData.map(r => if (r.inclusive) r.start to r.end by r.step else r.start until r.end by r.step) + + def numericIntRanges = rangeData.map(r => if (r.inclusive) NumericRange.inclusive(r.start, r.end, r.step) else NumericRange(r.start, r.end, r.step)) + + def numericLongRanges = rangeData.map(r => if (r.inclusive) NumericRange.inclusive(r.start.toLong, r.end, r.step) else NumericRange(r.start.toLong, r.end, r.step)) + + def numericBigIntRanges = rangeData.map(r => if (r.inclusive) NumericRange.inclusive(BigInt(r.start), BigInt(r.end), BigInt(r.step)) else NumericRange(BigInt(r.start), BigInt(r.end), BigInt(r.step))) + + def main(args: Array[String]) { + // We drop the first two tests for all ranges which don't have a decent sum implementation, + // because it is just too slow. + println("Ranges:") + ranges.foreach{range => println(range.sum)} + println("IntRanges:") + println("Disabled #1") + println("Disabled #2") + numericIntRanges.drop(2).foreach{range => println(range.sum)} + println("LongRanges:") + println("Disabled #1") + println("Disabled #2") + numericLongRanges.drop(2).foreach{range => println(range.sum)} + println("BigIntRanges:") + println("Disabled #1") + println("Disabled #2") + numericBigIntRanges.drop(2).foreach{range => println(range.sum)} + } + +}
\ No newline at end of file diff --git a/test/files/run/t5230.check b/test/files/run/t5230.check new file mode 100644 index 0000000000..5db6ec9b38 --- /dev/null +++ b/test/files/run/t5230.check @@ -0,0 +1,2 @@ +2 +evaluated = null diff --git a/test/pending/run/t5230.scala b/test/files/run/t5230.scala index 5aab8f9290..5aab8f9290 100644 --- a/test/pending/run/t5230.scala +++ b/test/files/run/t5230.scala diff --git a/test/pending/run/reify_csv.check b/test/pending/run/reify_csv.check new file mode 100644 index 0000000000..b56f4bb50b --- /dev/null +++ b/test/pending/run/reify_csv.check @@ -0,0 +1,10 @@ +List(phase name, id, description) +record(parser,1,parse source into ASTs, perform simple desugaring) +record(namer,2,resolve names, attach symbols to named trees) +record(packageobjects,3,load package objects) +record(typer,4,the meat and potatoes: type the trees) +record(superaccessors,5,add super accessors in traits and nested classes) +record(pickler,6,serialize symbol tables) +record(refchecks,7,reference/override checking, translate nested objects) +record(selectiveanf,8,) +record(liftcode,9,reify trees) diff --git a/test/pending/run/reify_csv.scala b/test/pending/run/reify_csv.scala new file mode 100644 index 0000000000..a05a3b55d4 --- /dev/null +++ b/test/pending/run/reify_csv.scala @@ -0,0 +1,42 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val csv = """ + | phase name; id; description + | parser; 1; parse source into ASTs, perform simple desugaring + | namer; 2; resolve names, attach symbols to named trees + |packageobjects; 3; load package objects + | typer; 4; the meat and potatoes: type the trees + |superaccessors; 5; add super accessors in traits and nested classes + | pickler; 6; serialize symbol tables + | refchecks; 7; reference/override checking, translate nested objects + | selectiveanf; 8; + | liftcode; 9; reify trees""".stripMargin.split("\n").map{_.trim()}.drop(1).toList + + val fields = csv.head.split(";").map{_.trim()}.toList + println(fields) + + val code = scala.reflect.Code.lift({ + object Csv { + case class record(`phase name`: String, id: String, description: String) + + object record { + def parse(lines: List[String]) = { + lines drop(1) map { line => line.split(";", -1).toList match { + case phase$whitespace$name :: id :: description :: _ => record(phase$whitespace$name.trim(), id.trim(), description.trim()) + case _ => throw new Exception("format error") + }} + } + } + } + + Csv.record.parse(csv) foreach println + }) + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/pending/run/t5224.check b/test/pending/run/t5224.check new file mode 100644 index 0000000000..2b920773c0 --- /dev/null +++ b/test/pending/run/t5224.check @@ -0,0 +1,9 @@ +{ + @serializable class C extends Object with ScalaObject { + def <init>() = { + super.<init>(); + () + } + }; + () +}
\ No newline at end of file diff --git a/test/pending/run/t5224.scala b/test/pending/run/t5224.scala new file mode 100644 index 0000000000..865ce4bfe9 --- /dev/null +++ b/test/pending/run/t5224.scala @@ -0,0 +1,8 @@ +import scala.reflect._ +import scala.reflect.api._ + +object Test extends App { + println(scala.reflect.Code.lift{ + @serializable class C + }.tree.toString) +}
\ No newline at end of file diff --git a/test/pending/run/t5225_1.check b/test/pending/run/t5225_1.check new file mode 100644 index 0000000000..b29cd9c365 --- /dev/null +++ b/test/pending/run/t5225_1.check @@ -0,0 +1,4 @@ +{ + @transient @volatile var x: Int = 2; + () +}
\ No newline at end of file diff --git a/test/pending/run/t5225_1.scala b/test/pending/run/t5225_1.scala new file mode 100644 index 0000000000..454502e810 --- /dev/null +++ b/test/pending/run/t5225_1.scala @@ -0,0 +1,8 @@ +import scala.reflect._ +import scala.reflect.api._ + +object Test extends App { + println(scala.reflect.Code.lift{ + @transient @volatile var x = 2 + }.tree.toString) +}
\ No newline at end of file diff --git a/test/pending/run/t5225_2.check b/test/pending/run/t5225_2.check new file mode 100644 index 0000000000..88972fd27f --- /dev/null +++ b/test/pending/run/t5225_2.check @@ -0,0 +1,4 @@ +{ + def foo(@cloneable x: Int): String = ""; + () +} diff --git a/test/pending/run/t5225_2.scala b/test/pending/run/t5225_2.scala new file mode 100644 index 0000000000..82bad0f353 --- /dev/null +++ b/test/pending/run/t5225_2.scala @@ -0,0 +1,8 @@ +import scala.reflect._ +import scala.reflect.api._ + +object Test extends App { + println(scala.reflect.Code.lift{ + def foo(@cloneable x: Int) = "" + }.tree.toString) +}
\ No newline at end of file diff --git a/test/pending/run/t5229_1.check b/test/pending/run/t5229_1.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/pending/run/t5229_1.check diff --git a/test/pending/run/t5229_1.scala b/test/pending/run/t5229_1.scala new file mode 100644 index 0000000000..1d7bf0590b --- /dev/null +++ b/test/pending/run/t5229_1.scala @@ -0,0 +1,14 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + object C + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/pending/run/t5229_2.check b/test/pending/run/t5229_2.check new file mode 100644 index 0000000000..5db6ec9b38 --- /dev/null +++ b/test/pending/run/t5229_2.check @@ -0,0 +1,2 @@ +2 +evaluated = null diff --git a/test/pending/run/t5229_2.scala b/test/pending/run/t5229_2.scala new file mode 100644 index 0000000000..67be7328a6 --- /dev/null +++ b/test/pending/run/t5229_2.scala @@ -0,0 +1,19 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + object C { + val x = 2 + } + + println(C.x) + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + val evaluated = toolbox.runExpr(ttree) + println("evaluated = " + evaluated) +} diff --git a/test/pending/run/t5230.check b/test/pending/run/t5230.check deleted file mode 100644 index 5ef4ff4d04..0000000000 --- a/test/pending/run/t5230.check +++ /dev/null @@ -1 +0,0 @@ -evaluated = 2 diff --git a/test/pending/run/t5266_1.check b/test/pending/run/t5266_1.check new file mode 100644 index 0000000000..3feac16a0b --- /dev/null +++ b/test/pending/run/t5266_1.check @@ -0,0 +1,2 @@ +2 +evaluated = null
\ No newline at end of file diff --git a/test/pending/run/t5266_1.scala b/test/pending/run/t5266_1.scala new file mode 100644 index 0000000000..06a81a04ea --- /dev/null +++ b/test/pending/run/t5266_1.scala @@ -0,0 +1,23 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + def x = 2 + println(x) + }; + + val settings = new Settings + settings.debug.value = true + settings.Xshowtrees.value = true + settings.Xprint.value = List("typer") + settings.printtypes.value = true + settings.Ytyperdebug.value = true + + val reporter = new ConsoleReporter(settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + val evaluated = toolbox.runExpr(ttree) + println("evaluated = " + evaluated) +}
\ No newline at end of file diff --git a/test/pending/run/t5266_2.check b/test/pending/run/t5266_2.check new file mode 100644 index 0000000000..3feac16a0b --- /dev/null +++ b/test/pending/run/t5266_2.check @@ -0,0 +1,2 @@ +2 +evaluated = null
\ No newline at end of file diff --git a/test/pending/run/t5266_2.scala b/test/pending/run/t5266_2.scala new file mode 100644 index 0000000000..cd841da021 --- /dev/null +++ b/test/pending/run/t5266_2.scala @@ -0,0 +1,17 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + def x = 2 + def y = x + println(y) + }; + + val reporter = new ConsoleReporter(settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + val evaluated = toolbox.runExpr(ttree) + println("evaluated = " + evaluated) +} diff --git a/test/pending/run/t5269.check b/test/pending/run/t5269.check new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/test/pending/run/t5269.check @@ -0,0 +1 @@ +2 diff --git a/test/pending/run/t5269.scala b/test/pending/run/t5269.scala new file mode 100644 index 0000000000..a30509f3fe --- /dev/null +++ b/test/pending/run/t5269.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + trait Z { + val z = 2 + } + + class X extends Z { + def println() = Predef.println(z) + } + + new X().println() + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/pending/run/t5270.check b/test/pending/run/t5270.check new file mode 100644 index 0000000000..08839f6bb2 --- /dev/null +++ b/test/pending/run/t5270.check @@ -0,0 +1 @@ +200 diff --git a/test/pending/run/t5270.scala b/test/pending/run/t5270.scala new file mode 100644 index 0000000000..10f79790b0 --- /dev/null +++ b/test/pending/run/t5270.scala @@ -0,0 +1,26 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + class Y { + def y = 100 + } + + trait Z { this: Y => + val z = 2 * y + } + + class X extends Y with Z { + def println() = Predef.println(z) + } + + new X().println() + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/tools/get-scala-revision b/tools/get-scala-revision index 8731705d06..23b216aa2b 100755 --- a/tools/get-scala-revision +++ b/tools/get-scala-revision @@ -1,30 +1,12 @@ #!/bin/sh # # Usage: get-scala-revision [dir] -# Figures out current scala revision of an svn checkout or -# a git-svn mirror (or a git clone.) +# Figures out current scala revision of a git clone. # # If no dir is given, current working dir is used. -DIR="" -if [ $# -eq 0 ]; then - DIR=`pwd` -else - DIR=$1 -fi +[[ -n "$1" ]] && cd "$1" -cd $DIR - -if [ -d .svn ]; then - # 2>&1 to catch also error output (e.g. svn warnings) - svn info . 2>&1 | grep ^Revision | sed 's/Revision: //' -elif [ -d .git ]; then - GIT_PAGER=cat - # this grabs more than one line because otherwise if you have local - # commits which aren't in git-svn it won't see any revision. - git log -10 | grep git-svn-id | head -1 | sed 's/[^@]*@\([0-9]*\).*/\1/' -else - echo "${DIR} doesn't appear to be git or svn dir." >&2 - echo 0 - exit 1 -fi +# dev should be a tag at the merge-base of master and the +# most recent release. +git describe head --abbrev=7 --match dev diff --git a/tools/get-scala-revision.bat b/tools/get-scala-revision.bat index 880bcc3f5c..ed3ade8a3e 100644 --- a/tools/get-scala-revision.bat +++ b/tools/get-scala-revision.bat @@ -1,17 +1,11 @@ @echo off rem rem Usage: get-scala-revison.bat [dir] -rem Figures out current scala revision of an svn checkout or -rem a git-svn mirror (or a git clone.) +rem Figures out current scala revision of a git clone. rem rem If no dir is given, current working dir is used. -if "%OS%" NEQ "Windows_NT" ( - echo "Sorry, your version of Windows is too old to run Scala." - goto :eof -) @setlocal - set _DIR= if "%*"=="" ( for /f "delims=;" %%i in ('cd') do set "_DIR=%%i" @@ -20,23 +14,10 @@ if "%*"=="" ( ) cd %_DIR% -if exist .svn\NUL ( - rem 2>&1 to catch also error output (e.g. svn warnings) - for /f "skip=4 tokens=2" %%i in ('svn info') do ( - echo %%i - goto :end - ) -) else ( if exist .git\NUL ( - set _GIT_PAGER=type - rem this grabs more than one line because otherwise if you have local - rem commits which aren't in git-svn it won't see any revision. - rem TODO: git log -10 | findstr git-svn-id | ... +if exist .git\NUL ( + git describe head --abbrev=7 --match dev echo 0 -) else ( - echo %_DIR% doesn't appear to be git or svn dir. - echo 0 - exit 1 -)) +) :end @endlocal |