diff options
89 files changed, 632 insertions, 1757 deletions
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 045869d41a..ad778f447a 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -407,6 +407,14 @@ filter { { matchName="scala.collection.immutable.$colon$colon" problemName=MissingTypesProblem + }, + { + matchName="scala.annotation.showAsInfix$" + problemName=MissingClassProblem + }, + { + matchName="scala.annotation.showAsInfix" + problemName=MissingClassProblem } ] } diff --git a/project/PartestUtil.scala b/project/PartestUtil.scala index ab7e62b3b4..23570a88ec 100644 --- a/project/PartestUtil.scala +++ b/project/PartestUtil.scala @@ -90,6 +90,6 @@ object PartestUtil { val ScalacOptsParser = (token("-Dpartest.scalac_opts=") ~ token(NotSpace)) map { case opt ~ v => opt + v } val P = oneOf(knownUnaryOptions.map(x => token(x))) | SrcPath | TestPathParser | Grep | ScalacOptsParser - (Space ~> repsep(P, oneOrMore(Space))).map(_.mkString(" ")).?.map(_.getOrElse("")) <~ OptSpace + (Space ~> repsep(P, oneOrMore(Space))).map(_.mkString(" ")).?.map(_.getOrElse("")) } } diff --git a/scripts/jobs/integrate/bootstrap b/scripts/jobs/integrate/bootstrap index 3933854e4f..71936abf71 100755 --- a/scripts/jobs/integrate/bootstrap +++ b/scripts/jobs/integrate/bootstrap @@ -178,8 +178,7 @@ sbtResolve() { 'show update' >> $baseDir/logs/resolution 2>&1 } -# Oh boy... can't use scaladoc to document scala-xml/scala-parser-combinators -# if scaladoc depends on the same version of scala-xml/scala-parser-combinators. +# Oh boy... can't use scaladoc to document scala-xml if scaladoc depends on the same version of scala-xml. # Even if that version is available through the project's resolvers, sbt won't look past this project. # SOOOOO, we set the version to a dummy (-DOC), generate documentation, # then set the version to the right one and publish (which won't re-gen the docs). @@ -216,17 +215,6 @@ buildXML() { fi } -buildParsers() { - if [ "$PARSERS_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scala-lang.modules" "scala-parser-combinators" $PARSERS_VER ) - then echo "Found scala-parser-combinators $PARSERS_VER; not building." - else - update scala scala-parser-combinators "$PARSERS_REF" && gfxd - doc="$(docTask $PARSERS_BUILT)" - sbtBuild 'set version := "'$PARSERS_VER'-DOC"' $clean "$doc" 'set version := "'$PARSERS_VER'"' test "${buildTasks[@]}" - PARSERS_BUILT="yes" - fi -} - buildPartest() { if [ "$PARTEST_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scala-lang.modules" "scala-partest" $PARTEST_VER ) then echo "Found scala-partest $PARTEST_VER; not building." @@ -238,17 +226,6 @@ buildPartest() { fi } -buildSwing() { - if [ "$SWING_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scala-lang.modules" "scala-swing" $SWING_VER ) - then echo "Found scala-swing $SWING_VER; not building." - else - update scala scala-swing "$SWING_REF" && gfxd - doc="$(docTask $SWING_BUILT)" - sbtBuild 'set version := "'$SWING_VER'"' $clean "$doc" test "${buildTasks[@]}" - SWING_BUILT="yes" - fi -} - # should only be called with publishTasks publishing to private-repo buildScalaCheck(){ if [ "$SCALACHECK_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scalacheck" "scalacheck" $SCALACHECK_VER ) @@ -266,8 +243,6 @@ buildModules() { publishTasks=('set credentials += Credentials(Path.userHome / ".credentials-private-repo")' "set every publishTo := Some(\"private-repo\" at \"$releaseTempRepoUrl\")") buildTasks=($publishPrivateTask) buildXML - buildParsers - buildSwing # buildScalaCheck buildPartest } @@ -276,8 +251,6 @@ buildPublishedModules() { publishTasks=('set credentials += Credentials(Path.userHome / ".credentials-sonatype")' "set pgpPassphrase := Some(Array.empty)") buildTasks=($publishSonatypeTaskModules) buildXML - buildParsers - buildSwing buildPartest } @@ -381,36 +354,26 @@ deriveModuleVersions() { if [ "$moduleVersioning" == "versions.properties" ]; then # use versions.properties as defaults when no version specified on the command line XML_VER=${XML_VER-$scala_xml_version_number} - PARSERS_VER=${PARSERS_VER-$scala_parser_combinators_version_number} - SWING_VER=${SWING_VER-$scala_swing_version_number} PARTEST_VER=${PARTEST_VER-$partest_version_number} SCALACHECK_VER=${SCALACHECK_VER-$scalacheck_version_number} XML_REF="v$XML_VER" - PARSERS_REF="v$PARSERS_VER" - SWING_REF="v$SWING_VER" PARTEST_REF="v$PARTEST_VER" SCALACHECK_REF="$SCALACHECK_VER" # no `v` in their tags else # use HEAD as default when no revision is specified on the command line XML_REF=${XML_REF-"HEAD"} - PARSERS_REF=${PARSERS_REF-"HEAD"} - SWING_REF=${SWING_REF-"HEAD"} PARTEST_REF=${PARTEST_REF-"HEAD"} SCALACHECK_REF=${SCALACHECK_REF-"HEAD"} XML_VER=$(deriveVersion scala scala-xml "$XML_REF") - PARSERS_VER=$(deriveVersion scala scala-parser-combinators "$PARSERS_REF") - SWING_VER=$(deriveVersion scala scala-swing "$SWING_REF") PARTEST_VER=$(deriveVersion scala scala-partest "$PARTEST_REF") SCALACHECK_VER=$(deriveVersionAnyTag rickynils scalacheck "$SCALACHECK_REF") fi echo "Module versions (versioning strategy: $moduleVersioning):" - echo "PARSERS = $PARSERS_VER at $PARSERS_REF" echo "PARTEST = $PARTEST_VER at $PARTEST_REF" # echo "SCALACHECK = $SCALACHECK_VER at $SCALACHECK_REF" - echo "SWING = $SWING_VER at $SWING_REF" echo "XML = $XML_VER at $XML_REF" } @@ -444,8 +407,6 @@ constructUpdatedModuleVersions() { # force the new module versions for building the core. these may be different from the values in versions.properties, # either because the variables (XML_VER) were provided, or because we're building the modules from HEAD. # in the common case, the values are the same as in versions.properties. - updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-parser-combinators.version.number=$PARSERS_VER") - updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-swing.version.number=$SWING_VER") updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-xml.version.number=$XML_VER") updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dpartest.version.number=$PARTEST_VER") diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 40be302799..c1b0733895 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1198,7 +1198,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) first } - // --------------- Miscellania ------------------------------- + // --------------- Miscellanea ------------------------------- /** Progress tracking. Measured in "progress units" which are 1 per * compilation unit per phase completed. diff --git a/src/compiler/scala/tools/nsc/PhaseAssembly.scala b/src/compiler/scala/tools/nsc/PhaseAssembly.scala index ef9818c62d..df72c37e53 100644 --- a/src/compiler/scala/tools/nsc/PhaseAssembly.scala +++ b/src/compiler/scala/tools/nsc/PhaseAssembly.scala @@ -17,7 +17,7 @@ trait PhaseAssembly { self: Global => /** - * Aux datastructure for solving the constraint system + * Aux data structure for solving the constraint system * The dependency graph container with helper methods for node and edge creation */ private class DependencyGraph { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index c35c0a1019..0cdba861a5 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1263,8 +1263,8 @@ self => case CHARLIT => in.charVal case INTLIT => in.intVal(isNegated).toInt case LONGLIT => in.intVal(isNegated) - case FLOATLIT => in.floatVal(isNegated).toFloat - case DOUBLELIT => in.floatVal(isNegated) + case FLOATLIT => in.floatVal(isNegated) + case DOUBLELIT => in.doubleVal(isNegated) case STRINGLIT | STRINGPART => in.strVal.intern() case TRUE => true case FALSE => false diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 99713451ac..226c49ec07 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -983,23 +983,45 @@ trait Scanners extends ScannersCommon { def intVal: Long = intVal(negated = false) - /** Convert current strVal, base to double value + /** Convert current strVal, base to float value. */ - def floatVal(negated: Boolean): Double = { - val limit: Double = if (token == DOUBLELIT) Double.MaxValue else Float.MaxValue + def floatVal(negated: Boolean): Float = { try { - val value: Double = java.lang.Double.valueOf(strVal).doubleValue() - if (value > limit) + val value: Float = java.lang.Float.parseFloat(strVal) + if (value > Float.MaxValue) syntaxError("floating point number too large") + val zeroly = "0.fF" + if (value == 0.0f && strVal.exists(c => !zeroly.contains(c))) + syntaxError("floating point number too small") if (negated) -value else value } catch { case _: NumberFormatException => syntaxError("malformed floating point number") + 0.0f + } + } + + def floatVal: Float = floatVal(negated = false) + + /** Convert current strVal, base to double value. + */ + def doubleVal(negated: Boolean): Double = { + try { + val value: Double = java.lang.Double.parseDouble(strVal) + if (value > Double.MaxValue) + syntaxError("double precision floating point number too large") + val zeroly = "0.dD" + if (value == 0.0d && strVal.exists(c => !zeroly.contains(c))) + syntaxError("double precision floating point number too small") + if (negated) -value else value + } catch { + case _: NumberFormatException => + syntaxError("malformed double precision floating point number") 0.0 } } - def floatVal: Double = floatVal(negated = false) + def doubleVal: Double = doubleVal(negated = false) def checkNoLetter(): Unit = { if (isIdentifierPart(ch) && ch >= ' ') diff --git a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala index 1982c7f643..402dc66a7f 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala @@ -33,7 +33,7 @@ object AsmUtils { final val traceClassPattern = "" /** - * Print the bytedcode of classes as they are serialized by the ASM library. The serialization + * Print the bytecode of classes as they are serialized by the ASM library. The serialization * performed by `asm.ClassWriter` can change the code generated by GenBCode. For example, it * introduces stack map frames, it computes the maximal stack sizes, and it replaces dead * code by NOPs (see also https://github.com/scala/scala/pull/3726#issuecomment-42861780). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index c7952ffe94..76d042ce3b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -918,7 +918,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { (args zip params) filterNot isTrivial } - // first push *all* arguments. This makes sure muliple uses of the same labelDef-var will all denote the (previous) value. + // first push *all* arguments. This makes sure multiple uses of the same labelDef-var will all denote the (previous) value. aps foreach { case (arg, param) => genLoad(arg, locals(param).tk) } // `locals` is known to contain `param` because `genDefDef()` visited `labelDefsAtOrUnder` // second assign one by one to the LabelDef's variables. diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index 18e7500172..a74c70a684 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -188,7 +188,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * Data for emitting an EnclosingMethod attribute. None if `classSym` is a member class (not * an anonymous or local class). See doc in BTypes. * - * The class is parametrized by two functions to obtain a bytecode class descriptor for a class + * The class is parameterized by two functions to obtain a bytecode class descriptor for a class * symbol, and to obtain a method signature descriptor fro a method symbol. These function depend * on the implementation of GenASM / GenBCode, so they need to be passed in. */ @@ -332,7 +332,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { failNoForwarder("companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)") else if (companion.isTrait) failNoForwarder("companion is a trait") - // Now either succeeed, or issue some additional warnings for things which look like + // Now either succeed, or issue some additional warnings for things which look like // attempts to be java main methods. else (possibles exists definitions.isJavaMainMethod) || { possibles exists { m => @@ -541,9 +541,9 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * symbol (sym.annotations) or type (as an AnnotatedType, eliminated by erasure). * * For Scala annotations this is OK: they are stored in the pickle and ignored by the backend. - * Java annoations on the other hand are additionally emitted to the classfile in Java's format. + * Java annotations on the other hand are additionally emitted to the classfile in Java's format. * - * This means that [[Type]] instances within an AnnotaionInfo reach the backend non-erased. Examples: + * This means that [[Type]] instances within an AnnotationInfo reach the backend non-erased. Examples: * - @(javax.annotation.Resource @annotation.meta.getter) val x = 0 * Here, annotationInfo.atp is an AnnotatedType. * - @SomeAnnotation[T] val x = 0 diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala index 121091fe4f..3e3229d2c3 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala @@ -83,7 +83,7 @@ abstract class BTypes { val callsitePositions: concurrent.Map[MethodInsnNode, Position] = recordPerRunCache(TrieMap.empty) /** - * Stores callsite instructions of invocatinos annotated `f(): @inline/noinline`. + * Stores callsite instructions of invocations annotated `f(): @inline/noinline`. * Instructions are added during code generation (BCodeBodyBuilder). The maps are then queried * when building the CallGraph, every Callsite object has an annotated(No)Inline field. */ @@ -287,7 +287,7 @@ abstract class BTypes { } // The InlineInfo is built from the classfile (not from the symbol) for all classes that are NOT - // being compiled. For those classes, the info is only needed if the inliner is enabled, othewise + // being compiled. For those classes, the info is only needed if the inliner is enabled, otherwise // we can save the memory. if (!compilerSettings.optInlinerEnabled) BTypes.EmptyInlineInfo else fromClassfileAttribute getOrElse fromClassfileWithoutAttribute @@ -653,7 +653,7 @@ abstract class BTypes { * Fields in the InnerClass entries: * - inner class: the (nested) class C we are talking about * - outer class: the class of which C is a member. Has to be null for non-members, i.e. for - * local and anonymous classes. NOTE: this co-incides with the presence of an + * local and anonymous classes. NOTE: this coincides with the presence of an * EnclosingMethod attribute (see below) * - inner name: A string with the simple name of the inner class. Null for anonymous classes. * - flags: access property flags, details in JVMS, table in 4.7.6. Static flag: see @@ -702,7 +702,7 @@ abstract class BTypes { * local and anonymous classes, no matter if there is an enclosing method or not. Accordingly, the * "class" field (see below) must be always defined, while the "method" field may be null. * - * NOTE: When an EnclosingMethod attribute is requried (local and anonymous classes), the "outer" + * NOTE: When an EnclosingMethod attribute is required (local and anonymous classes), the "outer" * field in the InnerClass table must be null. * * Fields: @@ -1144,7 +1144,7 @@ object BTypes { /** * Metadata about a ClassBType, used by the inliner. * - * More information may be added in the future to enable more elaborate inlinine heuristics. + * More information may be added in the future to enable more elaborate inline heuristics. * Note that this class should contain information that can only be obtained from the ClassSymbol. * Information that can be computed from the ClassNode should be added to the call graph instead. * diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala index 84f6d87c5c..2cf5cfcb8d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala @@ -78,7 +78,7 @@ trait BytecodeWriters { } /* - * The ASM textual representation for bytecode overcomes disadvantages of javap ouput in three areas: + * The ASM textual representation for bytecode overcomes disadvantages of javap output in three areas: * (a) pickle dingbats undecipherable to the naked eye; * (b) two constant pools, while having identical contents, are displayed differently due to physical layout. * (c) stack maps (classfile version 50 and up) are displayed in encoded form by javap, diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala index e25b55e7ab..90da570f01 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala @@ -382,7 +382,8 @@ class BackendUtils[BT <: BTypes](val btypes: BT) { * but not for writing in the classfile. We let the ClassWriter recompute max's. * * NOTE 2: the maxStack value computed here may be larger than the smallest correct value - * that would allow running an analyzer, see `InstructionStackEffect.forAsmAnalysisConservative`. + * that would allow running an analyzer, see `InstructionStackEffect.forAsmAnalysis` and + * `InstructionStackEffect.maxStackGrowth`. * * NOTE 3: the implementation doesn't look at instructions that cannot be reached, it computes * the max local / stack size in the reachable code. These max's work just fine for running an diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala index ef961941a0..999c686aac 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala @@ -110,7 +110,7 @@ package scala.tools.nsc.backend.jvm * - Use YourKit for finding hotspots (cpu profiling). when it comes to drilling down into the details * of a hotspot, don't pay too much attention to the percentages / time counts. * - Should also try other profilers. - * - Use timers. When a method showed up as a hotspot, i added a timer around that method, and a + * - Use timers. When a method showed up as a hotspot, I added a timer around that method, and a * second one within the method to measure specific parts. The timers slow things down, but the * relative numbers show what parts of a method are slow. * diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala index a4cd8fce1e..78fc7e1ecf 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala @@ -69,7 +69,7 @@ class BoxUnbox[BT <: BTypes](val btypes: BT) { * E1: M1 only works if there's a single boxing operation. * def e1(b: Boolean) = { * val i: Integer = box(10) // 10 is stored into a new local, box operation and i removed - * val j: Integer = box(20) // 20 is stored into a new local, box operation adn j removed + * val j: Integer = box(20) // 20 is stored into a new local, box operation and j removed * val r = if (b) i else j // loads and stores of the box are eliminated, r no longer exists * unbox(r) // cannot rewrite: we don't know which local to load * } @@ -138,7 +138,7 @@ class BoxUnbox[BT <: BTypes](val btypes: BT) { * - note that the MatchError creation is dead code: local2 is never null. However, our nullness * analysis cannot identify this: it does not track nullness through tuple stores and loads. * - if we re-write the non-escaping consumers of the outer tuple, but keep the tuple allocation - * and the escaping consumer, we get the follwoing: + * and the escaping consumer, we get the following: * * load 1, load 2 * val newLocal1 = new Tuple2; load newLocal1 // stack: Tuple2 @@ -188,7 +188,7 @@ class BoxUnbox[BT <: BTypes](val btypes: BT) { var maxStackGrowth = 0 - /** Mehtod M1 for eliminating box-unbox pairs (see doc comment in the beginning of this file) */ + /** Method M1 for eliminating box-unbox pairs (see doc comment in the beginning of this file) */ def replaceBoxOperationsSingleCreation(creation: BoxCreation, finalCons: Set[BoxConsumer], boxKind: BoxKind, keepBox: Boolean): Unit = { /** * If the box is eliminated, all copy operations (loads, stores, others) of the box need to diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala index 78acd72dba..f2ff73c44d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala @@ -167,7 +167,7 @@ class ByteCodeRepository[BT <: BTypes](val classPath: ClassPath, val btypes: BT) * the users (e.g. the inliner) have to be aware of method selection. * * Note that the returned method may be abstract (ACC_ABSTRACT), native (ACC_NATIVE) or signature - * polymorphic (methods `invoke` and `invokeExact` in class `MehtodHandles`). + * polymorphic (methods `invoke` and `invokeExact` in class `MethodHandles`). * * @return The [[MethodNode]] of the requested method and the [[InternalName]] of its declaring * class, or an error message if the method could not be found. An error message is also @@ -204,8 +204,8 @@ class ByteCodeRepository[BT <: BTypes](val classPath: ClassPath, val btypes: BT) visited += i // abstract and static methods are excluded, see jvms-5.4.3.3 for (m <- findMethod(c) if !isPrivateMethod(m) && !isStaticMethod(m)) found += ((m, c)) - val recusionResult = findIn(c) - if (recusionResult.isDefined) return recusionResult + val recursionResult = findIn(c) + if (recursionResult.isDefined) return recursionResult } None } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala index 9c0dfb0ee2..a740ca525c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala @@ -285,7 +285,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { // final case class :: / final case object Nil // (l: List).map // can be inlined // we need to know that - // - the recevier is sealed + // - the receiver is sealed // - what are the children of the receiver // - all children are final // - none of the children overrides map diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala index b05669ce89..518646812e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala @@ -273,7 +273,7 @@ class CopyProp[BT <: BTypes](val btypes: BT) { } /** - * Eliminate the `numArgs` inputs of the instruction `prod` (which was eliminated). Fo + * Eliminate the `numArgs` inputs of the instruction `prod` (which was eliminated). For * each input value * - if the `prod` instruction is the single consumer, enqueue the producers of the input * - otherwise, insert a POP instruction to POP the input value @@ -465,7 +465,7 @@ class CopyProp[BT <: BTypes](val btypes: BT) { } /** - * Remove `xSTORE n; xLOAD n` paris if + * Remove `xSTORE n; xLOAD n` pairs if * - the local variable n is not used anywhere else in the method (1), and * - there are no executable instructions and no live labels (jump targets) between the two (2) * diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala index 16ed9da0e4..7bc4ea2392 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala @@ -82,7 +82,7 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI } /** - * De-serialize the attribute into an InlineInfo. The attribute starts at cr.b(off), but we don't + * Deserialize the attribute into an InlineInfo. The attribute starts at cr.b(off), but we don't * need to access that array directly, we can use the `read` methods provided by the ClassReader. * * `buf` is a pre-allocated character array that is guaranteed to be long enough to hold any diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala index b9f593a4d8..0ae8347dc5 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala @@ -683,7 +683,7 @@ class Inliner[BT <: BTypes](val btypes: BT) { * (A2) C and D are members of the same run-time package */ def classIsAccessible(accessed: BType, from: ClassBType): Either[OptimizerWarning, Boolean] = (accessed: @unchecked) match { - // TODO: A2 requires "same run-time package", which seems to be package + classloader (JMVS 5.3.). is the below ok? + // TODO: A2 requires "same run-time package", which seems to be package + classloader (JVMS 5.3.). is the below ok? case c: ClassBType => c.isPublic.map(_ || c.packageInternalName == from.packageInternalName) case a: ArrayBType => classIsAccessible(a.elementType, from) case _: PrimitiveBType => Right(true) @@ -725,7 +725,7 @@ class Inliner[BT <: BTypes](val btypes: BT) { * type from there (https://github.com/scala-opt/scala/issues/13). */ def memberIsAccessible(memberFlags: Int, memberDeclClass: ClassBType, memberRefClass: ClassBType, from: ClassBType): Either[OptimizerWarning, Boolean] = { - // TODO: B3 requires "same run-time package", which seems to be package + classloader (JMVS 5.3.). is the below ok? + // TODO: B3 requires "same run-time package", which seems to be package + classloader (JVMS 5.3.). is the below ok? def samePackageAsDestination = memberDeclClass.packageInternalName == from.packageInternalName def targetObjectConformsToDestinationClass = false // needs type propagation analysis, see above diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala index 4744cb9ab1..63360e17ff 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala @@ -125,7 +125,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) { if (callsite.isInlineAnnotated && callee.canInlineFromSource) { // By default, we only emit inliner warnings for methods annotated @inline. However, we don't // want to be unnecessarily noisy with `-opt-warnings:_`: for example, the inliner heuristic - // would attempty to inline `Function1.apply$sp$II`, as it's higher-order (the receiver is + // would attempt to inline `Function1.apply$sp$II`, as it's higher-order (the receiver is // a function), and it's concrete (forwards to `apply`). But because it's non-final, it cannot // be inlined. So we only create warnings here for methods annotated @inline. Some(Left(CalleeNotFinal( diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala index 65d1e20d69..9c22b09cdd 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala @@ -61,7 +61,7 @@ import scala.tools.nsc.backend.jvm.opt.BytecodeUtils._ * - empty local variable descriptors (local variables that were holding the box may become unused) * * copy propagation (replaces LOAD n to the LOAD m for the smallest m that is an alias of n) - * + enables downstrem: + * + enables downstream: * - stale stores (a stored value may not be loaded anymore) * - store-load pairs (a load n may now be right after a store n) * + NOTE: copy propagation is only executed once, in the first fixpoint loop iteration. none of diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala index 133a656206..1ea152b29c 100644 --- a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala +++ b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala @@ -106,7 +106,7 @@ trait JFileDirectoryLookup[FileEntryType <: ClassRepresentation] extends Directo // as the type of `case class C(); case class D(); List(C(), D()).head`, rather than the opposite order. // On Mac, the HFS performs this sorting transparently, but on Linux the order is unspecified. // - // Note this behaviour can be enabled with in javac with `javac -XDsortfiles`, but that's only + // Note this behaviour can be enabled in javac with `javac -XDsortfiles`, but that's only // intended to improve determinism of the compiler for compiler hackers. util.Arrays.sort(listing, (o1: File, o2: File) => o1.getName.compareTo(o2.getName)) listing diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 947af55724..3ef75679ee 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -276,7 +276,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { // SelectFromTypeTree otherwise. See #3567. // Select nodes can be later // converted in the typechecker to SelectFromTypeTree if the class - // turns out to be an instance ionner class instead of a static inner class. + // turns out to be an instance inner class instead of a static inner class. def typeSelect(t: Tree, name: Name) = t match { case Ident(_) | Select(_, _) => Select(t, name) case _ => SelectFromTypeTree(t, name.toTypeName) diff --git a/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala b/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala index a0bba46398..e027b065ac 100644 --- a/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala +++ b/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala @@ -99,7 +99,7 @@ trait AccessorSynthesis extends Transform with ast.TreeDSL { } - // TODO: better way to communicate from info transform to tree transfor? + // TODO: better way to communicate from info transform to tree transform? private[this] val _bitmapInfo = perRunCaches.newMap[Symbol, BitmapInfo] private[this] val _slowPathFor = perRunCaches.newMap[Symbol, Symbol]() diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 855e53710b..2e7ab8a887 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -152,7 +152,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val resTpOk = ( samResultType =:= UnitTpe || functionResultType =:= samResultType - || (isReferenceType(samResultType) && isReferenceType(functionResultType))) // yes, this is what the spec says -- no further correspondance required + || (isReferenceType(samResultType) && isReferenceType(functionResultType))) // yes, this is what the spec says -- no further correspondence required if (resTpOk && (samParamTypes corresponds functionParamTypes){ (samParamTp, funParamTp) => funParamTp =:= samParamTp || (isReferenceType(funParamTp) && isReferenceType(samParamTp) && funParamTp <:< samParamTp) }) target else { @@ -165,7 +165,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre // whenever a type in the sam's signature is (erases to) a primitive type, we must pick the sam's version, // as we don't implement the logic regarding widening that's performed by LMF -- we require =:= for primitives // - // We use the sam's type for the check whether we're dealin with a reference type, as it could be a generic type, + // We use the sam's type for the check whether we're dealing with a reference type, as it could be a generic type, // which means the function's parameter -- even if it expects a value class -- will need to be // boxed on the generic call to the sam method. diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala index fbf1e8cec1..b2bf9fad3f 100644 --- a/src/compiler/scala/tools/nsc/transform/Fields.scala +++ b/src/compiler/scala/tools/nsc/transform/Fields.scala @@ -58,7 +58,7 @@ import symtab.Flags._ * * In the even longer term (Scala 3?), I agree with @DarkDimius that it would make sense * to hide the difference between strict and lazy vals. All vals are lazy, - * but the memoization overhead is removed when we statically know they are forced during initialiation. + * but the memoization overhead is removed when we statically know they are forced during initialization. * We could still expose the low-level field semantics through `private[this] val`s. * * In any case, the current behavior of overriding vals is pretty surprising. diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 798cfcd072..169fe7588e 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -113,7 +113,7 @@ abstract class LambdaLift extends InfoTransform { * * For DelayedInit subclasses, constructor statements end up in the synthetic init method * instead of the constructor itself, so the access should go to the field. This method changes - * `logicallyEnclosingMember` in this case to return a temprorary symbol corresponding to that + * `logicallyEnclosingMember` in this case to return a temporary symbol corresponding to that * method. */ private def logicallyEnclosingMember(sym: Symbol): Symbol = { diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index de0db51b6c..96e2135c52 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -32,7 +32,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL with AccessorSynthes * we cannot emit PROTECTED methods in interfaces on the JVM, * but knowing that these trait methods are protected means we won't emit static forwarders. * - * JVMLS: "Methods of interfaces may have any of the flags in Table 4.6-A set + * JVMS: "Methods of interfaces may have any of the flags in Table 4.6-A set * except ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE (JLS §9.4)." * * TODO: can we just set the right flags from the start?? @@ -137,7 +137,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL with AccessorSynthes */ def addMember(clazz: Symbol, member: Symbol): Symbol = { debuglog(s"mixing into $clazz: ${member.defString}") - // This attachment is used to instruct the backend about which methids in traits require + // This attachment is used to instruct the backend about which methods in traits require // a static trait impl method. We remove this from the new symbol created for the method // mixed into the subclass. member.removeAttachment[NeedStaticImpl.type] diff --git a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala index ba303f7c2b..4c1705e386 100644 --- a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala +++ b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala @@ -35,7 +35,7 @@ abstract class SampleTransform extends Transform { atPos(tree1.pos)( // `atPos` fills in position of its tree argument Select( // The `Select` factory method is defined in class `Trees` sup, - currentOwner.newValue( // creates a new term symbol owned by `currentowner` + currentOwner.newValue( // creates a new term symbol owned by `currentOwner` newTermName("sample"), // The standard term name creator tree1.pos))))) case _ => diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 84f47c1caa..9161786d76 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1992,7 +1992,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { else exitingSpecialize(specializeCalls(unit).transform(tree)) // Remove the final modifier and @inline annotation from anything in the - // original class (since it's being overridden in at least onesubclass). + // original class (since it's being overridden in at least one subclass). // // We do this here so that the specialized subclasses will correctly copy // final and @inline. diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 096b6b9263..dcffd7a6ab 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -363,7 +363,7 @@ abstract class UnCurry extends InfoTransform * mark the method symbol SYNCHRONIZED for bytecode generation. * * Delambdafy targets are deemed ineligible as the Delambdafy phase will - * replace `this.synchronized` with `$this.synchronzed` now that it emits + * replace `this.synchronized` with `$this.synchronized` now that it emits * all lambda impl methods as static. */ private def translateSynchronized(tree: Tree) = tree match { @@ -705,7 +705,7 @@ abstract class UnCurry extends InfoTransform // // So what we need to do is to use the pre-uncurry type when creating `l$1`, which is `c.Tree` and is // correct. Now, there are two additional problems: - // 1. when varargs and byname params are involved, the uncurry transformation desugares these special + // 1. when varargs and byname params are involved, the uncurry transformation desugars these special // cases to actual typerefs, eg: // ``` // T* ~> Seq[T] (Scala-defined varargs) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala index cb3759e5fa..db6eac34cb 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala @@ -184,8 +184,8 @@ trait Logic extends Debugging { // push negation inside formula def negationNormalFormNot(p: Prop): Prop = p match { - case And(ops) => Or(ops.map(negationNormalFormNot)) // De'Morgan - case Or(ops) => And(ops.map(negationNormalFormNot)) // De'Morgan + case And(ops) => Or(ops.map(negationNormalFormNot)) // De Morgan + case Or(ops) => And(ops.map(negationNormalFormNot)) // De Morgan case Not(p) => negationNormalForm(p) case True => False case False => True diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index 89c793ec94..794d3d442a 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -564,11 +564,11 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { else scrut match { case Typed(tree, tpt) => val suppressExhaustive = tpt.tpe hasAnnotation UncheckedClass - val supressUnreachable = tree match { + val suppressUnreachable = tree match { case Ident(name) if name startsWith nme.CHECK_IF_REFUTABLE_STRING => true // SI-7183 don't warn for withFilter's that turn out to be irrefutable. case _ => false } - val suppression = Suppression(suppressExhaustive, supressUnreachable) + val suppression = Suppression(suppressExhaustive, suppressUnreachable) val hasSwitchAnnotation = treeInfo.isSwitchAnnotation(tpt.tpe) // matches with two or fewer cases need not apply for switchiness (if-then-else will do) // `case 1 | 2` is considered as two cases. diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index df014b5161..ea82739504 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -240,10 +240,6 @@ abstract class Duplicators extends Analyzer { result.symbol.updateAttachment(DelambdafyTarget) result - case fun: Function => - debuglog("Clearing the type and retyping Function: " + fun) - super.typed(fun.clearType, mode, pt) - case vdef @ ValDef(mods, name, tpt, rhs) => // log("vdef fixing tpe: " + tree.tpe + " with sym: " + tree.tpe.typeSymbol + " and " + invalidSyms) //if (mods.hasFlag(Flags.LAZY)) vdef.symbol.resetFlag(Flags.MUTABLE) // Martin to Iulian: lazy vars can now appear because they are no longer boxed; Please check that deleting this statement is OK. diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index e8147dbf3a..9dd260b274 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -495,21 +495,22 @@ trait Infer extends Checkable { } /** Return inferred type arguments, given type parameters, formal parameters, - * argument types, result type and expected result type. - * If this is not possible, throw a `NoInstance` exception. - * Undetermined type arguments are represented by `definitions.NothingTpe`. - * No check that inferred parameters conform to their bounds is made here. - * - * @param tparams the type parameters of the method - * @param formals the value parameter types of the method - * @param restpe the result type of the method - * @param argtpes the argument types of the application - * @param pt the expected return type of the application - * @return @see adjustTypeArgs - * - * @throws NoInstance - */ - def methTypeArgs(tparams: List[Symbol], formals: List[Type], restpe: Type, + * argument types, result type and expected result type. + * If this is not possible, throw a `NoInstance` exception. + * Undetermined type arguments are represented by `definitions.NothingTpe`. + * No check that inferred parameters conform to their bounds is made here. + * + * @param fn the function for reporting, may be empty + * @param tparams the type parameters of the method + * @param formals the value parameter types of the method + * @param restpe the result type of the method + * @param argtpes the argument types of the application + * @param pt the expected return type of the application + * @return @see adjustTypeArgs + * + * @throws NoInstance + */ + def methTypeArgs(fn: Tree, tparams: List[Symbol], formals: List[Type], restpe: Type, argtpes: List[Type], pt: Type): AdjustedTypeArgs.Result = { val tvars = tparams map freshVar if (!sameLength(formals, argtpes)) @@ -559,21 +560,12 @@ trait Infer extends Checkable { val hasAny = pt :: restpe :: formals ::: argtpes ::: loBounds exists (_.dealiasWidenChain exists containsAny) !hasAny } - def argumentPosition(idx: Int): Position = context.tree match { - case x: ValOrDefDef => x.rhs match { - case Apply(fn, args) if idx < args.size => args(idx).pos - case _ => context.tree.pos - } - case _ => context.tree.pos - } - if (settings.warnInferAny && context.reportErrors && canWarnAboutAny) { - foreachWithIndex(targs) ((targ, idx) => - targ.typeSymbol match { - case sym @ (AnyClass | AnyValClass) => - reporter.warning(argumentPosition(idx), s"a type was inferred to be `${sym.name}`; this may indicate a programming error.") - case _ => - } - ) + if (settings.warnInferAny && context.reportErrors && !fn.isEmpty && canWarnAboutAny) { + targs.foreach(_.typeSymbol match { + case sym @ (AnyClass | AnyValClass) => + reporter.warning(fn.pos, s"a type was inferred to be `${sym.name}`; this may indicate a programming error.") + case _ => + }) } adjustTypeArgs(tparams, tvars, targs, restpe) } @@ -735,7 +727,7 @@ trait Infer extends Checkable { ) def tryInstantiating(args: List[Type]) = falseIfNoInstance { val restpe = mt resultType args - val AdjustedTypeArgs.Undets(okparams, okargs, leftUndet) = methTypeArgs(undetparams, formals, restpe, args, pt) + val AdjustedTypeArgs.Undets(okparams, okargs, leftUndet) = methTypeArgs(EmptyTree, undetparams, formals, restpe, args, pt) val restpeInst = restpe.instantiateTypeParams(okparams, okargs) // #2665: must use weak conformance, not regular one (follow the monomorphic case above) exprTypeArgs(leftUndet, restpeInst, pt, useWeaklyCompatible = true) match { @@ -989,7 +981,7 @@ trait Infer extends Checkable { val restpe = fn.tpe.resultType(argtpes) val AdjustedTypeArgs.AllArgsAndUndets(okparams, okargs, allargs, leftUndet) = - methTypeArgs(undetparams, formals, restpe, argtpes, pt) + methTypeArgs(fn, undetparams, formals, restpe, argtpes, pt) if (checkBounds(fn, NoPrefix, NoSymbol, undetparams, allargs, "inferred ")) { val treeSubst = new TreeTypeSubstituter(okparams, okargs) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 27e214af97..31476e86cd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1130,7 +1130,7 @@ abstract class RefChecks extends Transform { } /** Sensibility check examines flavors of equals. */ def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match { - case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) && !currentOwner.isSynthetic => + case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) && (!currentOwner.isSynthetic || currentOwner.isAnonymousFunction) => checkSensibleEquals(pos, qual, name, fn.symbol, args.head) case _ => } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 58a44d3ac0..837ccf7e06 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -864,11 +864,24 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case _ => } debuglog(s"fallback on implicits: ${tree}/$resetTree") - val tree1 = typed(resetTree, mode) - // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that - // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin. - tree1 setType pluginsTyped(tree1.tpe, this, tree1, mode, pt) - if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, EmptyTree) + // SO-10066 Need to patch the enclosing tree in the context to make translation of Dynamic + // work during fallback typechecking below. + val resetContext: Context = { + object substResetForOriginal extends Transformer { + override def transform(tree: Tree): Tree = { + if (tree eq original) resetTree + else super.transform(tree) + } + } + context.make(substResetForOriginal.transform(context.tree)) + } + typerWithLocalContext(resetContext) { typer1 => + val tree1 = typer1.typed(resetTree, mode) + // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that + // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin. + tree1 setType pluginsTyped(tree1.tpe, typer1, tree1, mode, pt) + if (tree1.isEmpty) tree1 else typer1.adapt(tree1, mode, pt, EmptyTree) + } } ) else diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala index bd95fdbb50..80e82c85d8 100644 --- a/src/compiler/scala/tools/nsc/util/package.scala +++ b/src/compiler/scala/tools/nsc/util/package.scala @@ -89,7 +89,7 @@ package object util { implicit class StackTraceOps(private val e: Throwable) extends AnyVal with StackTracing { /** Format the stack trace, returning the prefix consisting of frames that satisfy * a given predicate. - * The format is similar to the typical case described in the JavaDoc + * The format is similar to the typical case described in the Javadoc * for [[java.lang.Throwable#printStackTrace]]. * If a stack trace is truncated, it will be followed by a line of the form * `... 3 elided`, by analogy to the lines `... 3 more` which indicate diff --git a/src/library/rootdoc.txt b/src/library/rootdoc.txt index d78df01046..0aef41c4da 100644 --- a/src/library/rootdoc.txt +++ b/src/library/rootdoc.txt @@ -44,8 +44,7 @@ Additional parts of the standard library are shipped as separate libraries. Thes - [[scala.reflect `scala.reflect`]] - Scala's reflection API (scala-reflect.jar) - [[scala.xml `scala.xml`]] - XML parsing, manipulation, and serialization (scala-xml.jar) - [[scala.swing `scala.swing`]] - A convenient wrapper around Java's GUI framework called Swing (scala-swing.jar) - - [[scala.util.parsing `scala.util.parsing`]] - [[scala.util.parsing.combinator Parser combinators]], including an - example implementation of a [[scala.util.parsing.json JSON parser]] (scala-parser-combinators.jar) + - [[scala.util.parsing `scala.util.parsing`]] - Parser combinators (scala-parser-combinators.jar) == Automatic imports == diff --git a/src/library/scala/annotation/showAsInfix.scala b/src/library/scala/annotation/showAsInfix.scala new file mode 100644 index 0000000000..6c25e08efa --- /dev/null +++ b/src/library/scala/annotation/showAsInfix.scala @@ -0,0 +1,27 @@ +package scala.annotation + +/** + * This annotation configures how Scala prints two-parameter generic types. + * + * By default, types with symbolic names are printed infix; while types without + * them are printed using the regular generic type syntax. + * + * Example of usage: + {{{ + scala> class Map[T, U] + defined class Map + + scala> def foo: Int Map Int = ??? + foo: Map[Int,Int] + + scala> @showAsInfix class Map[T, U] + defined class Map + + scala> def foo: Int Map Int = ??? + foo: Int Map Int + }}} + * + * @param enabled whether to show this type as an infix type operator. + * @since 2.12.2 + */ +class showAsInfix(enabled: Boolean = true) extends annotation.StaticAnnotation
\ No newline at end of file diff --git a/src/library/scala/collection/BitSetLike.scala b/src/library/scala/collection/BitSetLike.scala index 209b00ebf9..f0a70170c2 100644 --- a/src/library/scala/collection/BitSetLike.scala +++ b/src/library/scala/collection/BitSetLike.scala @@ -77,26 +77,26 @@ trait BitSetLike[+This <: BitSetLike[This] with SortedSet[Int]] extends SortedSe def rangeImpl(from: Option[Int], until: Option[Int]): This = { val a = toBitMask val len = a.length - if(from.isDefined) { + if (from.isDefined) { var f = from.get var pos = 0 - while(f >= 64 && pos < len) { + while (f >= 64 && pos < len) { f -= 64 a(pos) = 0 pos += 1 } - if(f > 0 && pos < len) a(pos) &= ~((1L << f)-1) + if (f > 0 && pos < len) a(pos) &= ~((1L << f)-1) } - if(until.isDefined) { + if (until.isDefined) { val u = until.get val w = u / 64 val b = u % 64 var clearw = w+1 - while(clearw < len) { + while (clearw < len) { a(clearw) = 0 clearw += 1 } - if(w < len) a(w) &= (1L << b)-1 + if (w < len) a(w) &= (1L << b)-1 } fromBitMaskNoCopy(a) } @@ -220,7 +220,7 @@ trait BitSetLike[+This <: BitSetLike[This] with SortedSet[Int]] extends SortedSe while (i >= 0) { val wi = word(i) if (wi != 0L) return WordLength*i + 63 - java.lang.Long.numberOfLeadingZeros(wi) - i += 1 + i -= 1 } throw new NoSuchElementException("Empty BitSet") } @@ -230,7 +230,7 @@ trait BitSetLike[+This <: BitSetLike[This] with SortedSet[Int]] extends SortedSe var pre = "" val max = nwords * WordLength var i = 0 - while(i != max) { + while (i != max) { if (contains(i)) { sb append pre append i pre = sep diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala index 1cd126f94f..0ee5542e30 100644 --- a/src/library/scala/collection/GenTraversableLike.scala +++ b/src/library/scala/collection/GenTraversableLike.scala @@ -249,30 +249,6 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with * @param bf $bfinfo * @return a new collection of type `That` which contains all elements * of this $coll followed by all elements of `that`. - * - * @usecase def ++[B](that: GenTraversableOnce[B]): $Coll[B] - * @inheritdoc - * - * Example: - * {{{ - * scala> val a = List(1) - * a: List[Int] = List(1) - * - * scala> val b = List(2) - * b: List[Int] = List(2) - * - * scala> val c = a ++ b - * c: List[Int] = List(1, 2) - * - * scala> val d = List('a') - * d: List[Char] = List(a) - * - * scala> val e = c ++ d - * e: List[AnyVal] = List(1, 2, a) - * }}} - * - * @return a new $coll which contains all elements of this $coll - * followed by all elements of `that`. */ def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index b89720da78..419206c226 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -177,14 +177,14 @@ self => } /** Groups elements in fixed size blocks by passing a "sliding window" - * over them (as opposed to partitioning them, as is done in grouped.) - * "Sliding window" step is 1 by default. + * over them (as opposed to partitioning them, as is done in `grouped`.) + * The "sliding window" step is set to one. * @see [[scala.collection.Iterator]], method `sliding` * * @param size the number of elements per group * @return An iterator producing ${coll}s of size `size`, except the - * last and the only element will be truncated if there are - * fewer elements than size. + * last element (which may be the only element) will be truncated + * if there are fewer than `size` elements remaining to be grouped. */ def sliding(size: Int): Iterator[Repr] = sliding(size, 1) @@ -196,8 +196,8 @@ self => * @param step the distance between the first elements of successive * groups * @return An iterator producing ${coll}s of size `size`, except the - * last and the only element will be truncated if there are - * fewer elements than size. + * last element (which may be the only element) will be truncated + * if there are fewer than `size` elements remaining to be grouped. */ def sliding(size: Int, step: Int): Iterator[Repr] = for (xs <- iterator.sliding(size, step)) yield { diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index d000d22f72..809e851494 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -1091,7 +1091,7 @@ trait Iterator[+A] extends TraversableOnce[A] { extends AbstractIterator[Seq[B]] with Iterator[Seq[B]] { - require(size >= 1 && step >= 1, "size=%d and step=%d, but both must be positive".format(size, step)) + require(size >= 1 && step >= 1, f"size=$size%d and step=$step%d, but both must be positive") private[this] var buffer: ArrayBuffer[B] = ArrayBuffer() // the buffer private[this] var filled = false // whether the buffer is "hot" @@ -1099,30 +1099,30 @@ trait Iterator[+A] extends TraversableOnce[A] { private[this] var pad: Option[() => B] = None // what to pad short sequences with /** Public functions which can be used to configure the iterator before use. - * - * Pads the last segment if necessary so that all segments will - * have the same size. - * - * @param x The element that will be appended to the last segment, if necessary. - * @return The same iterator, and ''not'' a new iterator. - * @note This method mutates the iterator it is called on, which can be safely used afterwards. - * @note This method is mutually exclusive with `withPartial(true)`. - */ + * + * Pads the last segment if necessary so that all segments will + * have the same size. + * + * @param x The element that will be appended to the last segment, if necessary. + * @return The same iterator, and ''not'' a new iterator. + * @note This method mutates the iterator it is called on, which can be safely used afterwards. + * @note This method is mutually exclusive with `withPartial(true)`. + */ def withPadding(x: => B): this.type = { pad = Some(() => x) this } - /** Public functions which can be used to configure the iterator before use. - * - * Select whether the last segment may be returned with less than `size` - * elements. If not, some elements of the original iterator may not be - * returned at all. - * - * @param x `true` if partial segments may be returned, `false` otherwise. - * @return The same iterator, and ''not'' a new iterator. - * @note This method mutates the iterator it is called on, which can be safely used afterwards. - * @note This method is mutually exclusive with `withPadding`. - */ + /** Public functions which can be used to configure the iterator before use. + * + * Select whether the last segment may be returned with less than `size` + * elements. If not, some elements of the original iterator may not be + * returned at all. + * + * @param x `true` if partial segments may be returned, `false` otherwise. + * @return The same iterator, and ''not'' a new iterator. + * @note This method mutates the iterator it is called on, which can be safely used afterwards. + * @note This method is mutually exclusive with `withPadding`. + */ def withPartial(x: Boolean): this.type = { _partial = x if (_partial == true) // reset pad since otherwise it will take precedence @@ -1231,9 +1231,15 @@ trait Iterator[+A] extends TraversableOnce[A] { new GroupedIterator[B](self, size, size) /** Returns an iterator which presents a "sliding window" view of - * another iterator. The first argument is the window size, and - * the second is how far to advance the window on each iteration; - * defaults to `1`. Example usages: + * this iterator. The first argument is the window size, and + * the second argument `step` is how far to advance the window + * on each iteration. The `step` defaults to `1`. + * + * The default `GroupedIterator` can be configured to either + * pad a partial result to size `size` or suppress the partial + * result entirely. + * + * Example usages: * {{{ * // Returns List(List(1, 2, 3), List(2, 3, 4), List(3, 4, 5)) * (1 to 5).iterator.sliding(3).toList @@ -1247,6 +1253,11 @@ trait Iterator[+A] extends TraversableOnce[A] { * (1 to 5).iterator.sliding(4, 3).withPadding(it2.next).toList * }}} * + * @return An iterator producing `Seq[B]`s of size `size`, except the + * last element (which may be the only element) will be truncated + * if there are fewer than `size` elements remaining to be grouped. + * This behavior can be configured. + * * @note Reuse: $consumesAndProducesIterator */ def sliding[B >: A](size: Int, step: Int = 1): GroupedIterator[B] = diff --git a/src/library/scala/collection/concurrent/TrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala index 769d7b0dac..fe0b5c4f0e 100644 --- a/src/library/scala/collection/concurrent/TrieMap.scala +++ b/src/library/scala/collection/concurrent/TrieMap.scala @@ -932,6 +932,33 @@ extends scala.collection.concurrent.Map[K, V] if (nonReadOnly) readOnlySnapshot().iterator else new TrieMapIterator(0, this) + //////////////////////////////////////////////////////////////////////////// + // + // SI-10177 These methods need overrides as the inherited implementations + // call `.iterator` more than once, which doesn't guarantee a coherent + // view of the data if there is a concurrent writer + // Note that the we don't need overrides for keysIterator or valuesIterator + // TrieMapTest validates the behaviour. + override def values: Iterable[V] = { + if (nonReadOnly) readOnlySnapshot().values + else super.values + } + override def keySet: Set[K] = { + if (nonReadOnly) readOnlySnapshot().keySet + else super.keySet + } + override def filterKeys(p: K => Boolean): collection.Map[K, V] = { + if (nonReadOnly) readOnlySnapshot().filterKeys(p) + else super.filterKeys(p) + } + override def mapValues[W](f: V => W): collection.Map[K, W] = { + if (nonReadOnly) readOnlySnapshot().mapValues(f) + else super.mapValues(f) + } + // END extra overrides + /////////////////////////////////////////////////////////////////// + + private def cachedSize() = { val r = RDCSS_READ_ROOT() r.cachedSize(this) diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala index 8288d8d480..b7966b0341 100644 --- a/src/library/scala/sys/process/ProcessBuilder.scala +++ b/src/library/scala/sys/process/ProcessBuilder.scala @@ -186,7 +186,7 @@ trait ProcessBuilder extends Source with Sink { def lineStream(log: ProcessLogger): Stream[String] /** Deprecated (renamed). Use `lineStream(log: ProcessLogger)` instead. */ - @deprecated("use stream instead", "2.11.0") + @deprecated("use lineStream instead", "2.11.0") def lines(log: ProcessLogger): Stream[String] = lineStream(log) /** Starts the process represented by this builder. The output is returned as @@ -210,7 +210,7 @@ trait ProcessBuilder extends Source with Sink { def lineStream_!(log: ProcessLogger): Stream[String] /** Deprecated (renamed). Use `lineStream_!(log: ProcessLogger)` instead. */ - @deprecated("use stream_! instead", "2.11.0") + @deprecated("use lineStream_! instead", "2.11.0") def lines_!(log: ProcessLogger): Stream[String] = lineStream_!(log) /** Starts the process represented by this builder, blocks until it exits, and diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index a6e584424b..8ba3e62ac2 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -316,8 +316,9 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => /** Check whether any of the arguments mention a symbol */ def refsSymbol(sym: Symbol) = hasArgWhich(_.symbol == sym) - def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue) - def intArg(index: Int) = constantAtIndex(index) map (_.intValue) + def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue) + def intArg(index: Int) = constantAtIndex(index) map (_.intValue) + def booleanArg(index: Int) = constantAtIndex(index) map (_.booleanValue) def symbolArg(index: Int) = argAtIndex(index) collect { case Apply(fun, Literal(str) :: Nil) if fun.symbol == definitions.Symbol_apply => newTermName(str.stringValue) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 9515309802..315af267bc 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -975,10 +975,10 @@ trait Definitions extends api.StandardDefinitions { } /** Given a class symbol C with type parameters T1, T2, ... Tn - * which have upper/lower bounds LB1/UB1, LB1/UB2, ..., LBn/UBn, + * which have upper/lower bounds LB1/UB1, LB2/UB2, ..., LBn/UBn, * returns an existential type of the form * - * C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... en >: LBn <: UBn }. + * C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... En >: LBn <: UBn }. */ def classExistentialType(prefix: Type, clazz: Symbol): Type = { val eparams = typeParamsToExistentials(clazz, clazz.unsafeTypeParams) @@ -1417,6 +1417,8 @@ trait Definitions extends api.StandardDefinitions { case _ => false } + lazy val ShowAsInfixAnnotationClass = rootMirror.getClassIfDefined("scala.annotation.showAsInfix") + // todo: reconcile with javaSignature!!! def signature(tp: Type): String = { def erasure(tp: Type): Type = tp match { diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala index 95b3b7fb14..1a1aa2e721 100644 --- a/src/reflect/scala/reflect/internal/Positions.scala +++ b/src/reflect/scala/reflect/internal/Positions.scala @@ -255,7 +255,7 @@ trait Positions extends api.Positions { self: SymbolTable => val annTrees = mdef.mods.annotations match { case Nil if mdef.symbol != null => // After typechecking, annotations are moved from the modifiers - // to the annotation on the symbol of the anotatee. + // to the annotation on the symbol of the annotatee. mdef.symbol.annotations.map(_.original) case anns => anns } diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala index 19804fc5f3..51fb31d36d 100644 --- a/src/reflect/scala/reflect/internal/Scopes.scala +++ b/src/reflect/scala/reflect/internal/Scopes.scala @@ -298,7 +298,7 @@ trait Scopes extends api.Scopes { self: SymbolTable => var e = lookupEntry(original.name.companionName) while (e != null) { // 1) Must be owned by the same Scope, to ensure that in - // `{ class C; { ...; object C } }`, the class is not seen as a comaniopn of the object. + // `{ class C; { ...; object C } }`, the class is not seen as a companion of the object. // 2) Must be a class and module symbol, so that `{ class C; def C }` or `{ type T; object T }` are not companions. def isClassAndModule(sym1: Symbol, sym2: Symbol) = sym1.isClass && sym2.isModule if ((e.owner eq entry.owner) && (isClassAndModule(original, e.sym) || isClassAndModule(e.sym, original))) { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index a6b6b1356c..b46f071717 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -309,6 +309,9 @@ trait Types /** Is this type completed (i.e. not a lazy type)? */ def isComplete: Boolean = true + /** Should this be printed as an infix type (@showAsInfix class &&[T, U])? */ + def isShowAsInfixType: Boolean = false + /** If this is a lazy type, assign a new type to `sym`. */ def complete(sym: Symbol) {} @@ -2102,6 +2105,15 @@ trait Types trivial = fromBoolean(!sym.isTypeParameter && pre.isTrivial && areTrivialTypes(args)) toBoolean(trivial) } + + /* It only makes sense to show 2-ary type constructors infix. + * By default we do only if it's a symbolic name. */ + override def isShowAsInfixType: Boolean = + hasLength(args, 2) && + sym.getAnnotation(ShowAsInfixAnnotationClass) + .map(_ booleanArg 0 getOrElse true) + .getOrElse(!Character.isUnicodeIdentifierStart(sym.decodedName.head)) + private[Types] def invalidateTypeRefCaches(): Unit = { parentsCache = null parentsPeriod = NoPeriod @@ -2327,6 +2339,22 @@ trait Types case arg :: Nil => s"($arg,)" case _ => args.mkString("(", ", ", ")") } + private def infixTypeString: String = { + /* SLS 3.2.8: all infix types have the same precedence. + * In A op B op' C, op and op' need the same associativity. + * Therefore, if op is left associative, anything on its right + * needs to be parenthesized if it's an infix type, and vice versa. */ + // we should only get here after `isShowInfixType` says we have 2 args + val l :: r :: Nil = args + + val isRightAssoc = typeSymbol.decodedName endsWith ":" + + val lstr = if (isRightAssoc && l.isShowAsInfixType) s"($l)" else l.toString + + val rstr = if (!isRightAssoc && r.isShowAsInfixType) s"($r)" else r.toString + + s"$lstr ${sym.decodedName} $rstr" + } private def customToString = sym match { case RepeatedParamClass | JavaRepeatedParamClass => args.head + "*" case ByNameParamClass => "=> " + args.head @@ -2350,6 +2378,8 @@ trait Types xs.init.mkString("(", ", ", ")") + " => " + xs.last } } + else if (isShowAsInfixType) + infixTypeString else if (isTupleTypeDirect(this)) tupleTypeString else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic) && (this ne dealias)) @@ -4152,7 +4182,7 @@ trait Types * The specification-enumerated non-value types are method types, polymorphic * method types, and type constructors. Supplements to the specified set of * non-value types include: types which wrap non-value symbols (packages - * abd statics), overloaded types. Varargs and by-name types T* and (=>T) are + * and statics), overloaded types. Varargs and by-name types T* and (=>T) are * not designated non-value types because there is code which depends on using * them as type arguments, but their precise status is unclear. */ @@ -4251,7 +4281,7 @@ trait Types case mt1 @ MethodType(params1, res1) => tp2 match { case mt2 @ MethodType(params2, res2) => - // sameLength(params1, params2) was used directly as pre-screening optimization (now done by matchesQuantified -- is that ok, performancewise?) + // sameLength(params1, params2) was used directly as pre-screening optimization (now done by matchesQuantified -- is that ok, performance-wise?) mt1.isImplicit == mt2.isImplicit && matchingParams(params1, params2, mt1.isJava, mt2.isJava) && matchesQuantified(params1, params2, res1, res2) @@ -4696,7 +4726,7 @@ trait Types case _ => Depth(1) } - //OPT replaced with tailrecursive function to save on #closures + //OPT replaced with tail recursive function to save on #closures // was: // var d = 0 // for (tp <- tps) d = d max by(tp) //!!!OPT!!! diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index fe1de91662..08ccac8069 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -385,7 +385,7 @@ abstract class UnPickler { // We're stuck with the order types are pickled in, but with judicious use // of named parameters we can recapture a declarative flavor in a few cases. - // But it's still a rat's nest of adhockery. + // But it's still a rat's nest of ad-hockery. (tag: @switch) match { case NOtpe => NoType case NOPREFIXtpe => NoPrefix diff --git a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala index 108ce45cca..6d9a9d6649 100644 --- a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala +++ b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala @@ -136,7 +136,7 @@ private[internal] trait GlbLubs { mergePrefixAndArgs(ts1, Covariant, depth) match { case NoType => loop(pretypes, tails) case tp if strictInference && willViolateRecursiveBounds(tp, ts0, ts1) => - log(s"Breaking recursion in lublist, advancing frontier and discaring merged prefix/args from $tp") + log(s"Breaking recursion in lublist, advancing frontier and discarding merged prefix/args from $tp") loop(pretypes, tails) case tp => loop(tp :: pretypes, tails) diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala index cf274f24bb..990092b749 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala @@ -404,7 +404,7 @@ trait TypeComparers { sym2.isClass && { val base = tr1 baseType sym2 // During bootstrap, `base eq NoType` occurs about 2.5 times as often as `base ne NoType`. - // The extra check seems like a worthwhile optimization (about 2.5M useless calls to isSubtype saved during that run). + // The extra check seems like a worthwhile optimization (about 2.5M useless calls to isSubType saved during that run). (base ne tr1) && (base ne NoType) && isSubType(base, tr2, depth) } || diff --git a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala index e321a07f51..2697824fd5 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala @@ -25,7 +25,7 @@ private[internal] trait TypeConstraints { // register with the auto-clearing cache manager perRunCaches.recordCache(this) - /** Undo all changes to constraints to type variables upto `limit`. */ + /** Undo all changes to constraints to type variables up to `limit`. */ //OPT this method is public so we can do `manual inlining` def undoTo(limit: UndoPairs) { assertCorrectThread() diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index de065d0b5d..0601067d26 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -312,7 +312,7 @@ private[internal] trait TypeMaps { * the corresponding class file might still not be read, so we do not * know what the type parameters of the type are. Therefore * the conversion of raw types to existential types might not have taken place - * in ClassFileparser.sigToType (where it is usually done). + * in ClassFileParser.sigToType (where it is usually done). */ def rawToExistential = new TypeMap { private var expanded = immutable.Set[Symbol]() @@ -404,7 +404,7 @@ private[internal] trait TypeMaps { case _ => super.mapOver(tp) } - // Do not discard the types of existential ident's. The + // Do not discard the types of existential idents. The // symbol of the Ident itself cannot be listed in the // existential's parameters, so the resulting existential // type would be ill-formed. @@ -504,7 +504,7 @@ private[internal] trait TypeMaps { && isBaseClassOfEnclosingClass(sym.owner) ) - private var capturedThisIds= 0 + private var capturedThisIds = 0 private def nextCapturedThisId() = { capturedThisIds += 1; capturedThisIds } /** Creates an existential representing a type parameter which appears * in the prefix of a ThisType. diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index e2f1e74740..24f8aa88e6 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -19,7 +19,7 @@ trait Erasure { /* A Java Array<T> is erased to Array[Object] (T can only be a reference type), where as a Scala Array[T] is * erased to Object. However, there is only symbol for the Array class. So to make the distinction between * a Java and a Scala array, we check if the owner of T comes from a Java class. - * This however caused issue SI-5654. The additional test for EXSITENTIAL fixes it, see the ticket comments. + * This however caused issue SI-5654. The additional test for EXISTENTIAL fixes it, see the ticket comments. * In short, members of an existential type (e.g. `T` in `forSome { type T }`) can have pretty arbitrary * owners (e.g. when computing lubs, <root> is used). All packageClass symbols have `isJavaDefined == true`. */ diff --git a/src/reflect/scala/reflect/internal/util/Statistics.scala b/src/reflect/scala/reflect/internal/util/Statistics.scala index 905f1bf26e..2d623f3367 100644 --- a/src/reflect/scala/reflect/internal/util/Statistics.scala +++ b/src/reflect/scala/reflect/internal/util/Statistics.scala @@ -78,7 +78,7 @@ object Statistics { /** Create a new stackable that shows as `prefix` and is active * in the same phases as its base timer. Stackable timers are subtimers - * that can be stacked ina timerstack, and that print aggregate, as well as specific + * that can be stacked in a timerstack, and that print aggregate, as well as specific * durations. */ def newStackableTimer(prefix: String, timer: Timer): StackableTimer = new StackableTimer(prefix, timer) diff --git a/src/reflect/scala/reflect/macros/blackbox/Context.scala b/src/reflect/scala/reflect/macros/blackbox/Context.scala index ce28b5911e..205e3ad1c3 100644 --- a/src/reflect/scala/reflect/macros/blackbox/Context.scala +++ b/src/reflect/scala/reflect/macros/blackbox/Context.scala @@ -26,7 +26,7 @@ package blackbox * Refer to the documentation of top-level traits in this package to learn the details. * * If a macro def refers to a macro impl that uses `blackbox.Context`, then this macro def becomes a blackbox macro, - * which means that its expansion will be upcast to its return type, enforcing faithfullness of that macro to its + * which means that its expansion will be upcast to its return type, enforcing faithfulness of that macro to its * type signature. Whitebox macros, i.e. the ones defined with `whitebox.Context`, aren't bound by this restriction, * which enables a number of important use cases, but they are also going to enjoy less support than blackbox macros, * so choose wisely. See the [[http://docs.scala-lang.org/overviews/macros/overview.html Macros Guide]] for more information. diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index f082ba2293..72e21f67fe 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -429,6 +429,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.hijackedCoreClasses definitions.symbolsNotPresentInBytecode definitions.isPossibleSyntheticParent + definitions.ShowAsInfixAnnotationClass definitions.abbrvTag definitions.numericWeight definitions.boxedModule diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala index ac5fec80b3..7f4e52e88d 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala @@ -11,8 +11,9 @@ package comment import scala.collection._ /** A body of text. A comment has a single body, which is composed of - * at least one block. Inside every body is exactly one summary (see - * [[scala.tools.nsc.doc.model.comment.Summary]]). */ + * at least one block. Inside every body is exactly one summary. + * @see [[Summary]] + */ final case class Body(blocks: Seq[Block]) { /** The summary text of the comment body. */ diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala index 5d0b6782bc..55527e43a1 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala @@ -12,7 +12,7 @@ import scala.collection._ /** A Scaladoc comment and all its tags. * - * '''Note:''' the only instantiation site of this class is in [[CommentFactory]]. + * '''Note:''' the only instantiation site of this class is in [[model.CommentFactory]]. * * @author Manohar Jonnalagedda * @author Gilles Dubochet */ diff --git a/test/files/neg/literals.check b/test/files/neg/literals.check index 148a9346c5..79b6d47782 100644 --- a/test/files/neg/literals.check +++ b/test/files/neg/literals.check @@ -19,6 +19,18 @@ literals.scala:23: error: missing integer number literals.scala:27: error: Decimal integer literals may not have a leading zero. (Octal syntax is obsolete.) def tooManyZeros: Int = 00 // line 26: no leading zero ^ +literals.scala:40: error: floating point number too small + def tooTiny: Float = { 0.7e-45f } // floating point number too small + ^ +literals.scala:42: error: double precision floating point number too small + def twoTiny: Double = { 2.0e-324 } // double precision floating point number too small + ^ +literals.scala:44: error: floating point number too large + def tooHuge: Float = { 3.4028236E38f } // floating point number too large + ^ +literals.scala:46: error: double precision floating point number too large + def twoHuge: Double = { 1.7976931348623159e308 } // double precision floating point number too large + ^ literals.scala:14: error: identifier expected but '}' found. def orphanDot: Int = { 9. } // line 12: ident expected ^ @@ -37,4 +49,4 @@ literals.scala:29: error: ';' expected but 'def' found. literals.scala:33: error: identifier expected but 'def' found. def zeroOfNineDot: Int = 09. // line 32: malformed integer, ident expected ^ -13 errors found +17 errors found diff --git a/test/files/neg/literals.scala b/test/files/neg/literals.scala index 3df7f0b408..22d5d9acd1 100644 --- a/test/files/neg/literals.scala +++ b/test/files/neg/literals.scala @@ -1,6 +1,6 @@ /* This took me literally all day. -*/ + */ trait RejectedLiterals { def missingHex: Int = { 0x } // line 4: was: not reported, taken as zero @@ -34,3 +34,14 @@ trait Braceless { def noHexFloat: Double = 0x1.2 // line 34: ';' expected but double literal found. } + +trait MoreSadness { + + def tooTiny: Float = { 0.7e-45f } // floating point number too small + + def twoTiny: Double = { 2.0e-324 } // double precision floating point number too small + + def tooHuge: Float = { 3.4028236E38f } // floating point number too large + + def twoHuge: Double = { 1.7976931348623159e308 } // double precision floating point number too large +} diff --git a/test/files/neg/t10066.check b/test/files/neg/t10066.check new file mode 100644 index 0000000000..3555205d83 --- /dev/null +++ b/test/files/neg/t10066.check @@ -0,0 +1,7 @@ +t10066.scala:33: error: could not find implicit value for parameter extractor: dynamicrash.Extractor[String] + println(storage.foo[String]) + ^ +t10066.scala:37: error: could not find implicit value for parameter extractor: dynamicrash.Extractor[A] + println(storage.foo) + ^ +two errors found diff --git a/test/files/neg/t10066.scala b/test/files/neg/t10066.scala new file mode 100644 index 0000000000..ef52f333dd --- /dev/null +++ b/test/files/neg/t10066.scala @@ -0,0 +1,38 @@ +package dynamicrash + +import scala.language.dynamics + +class Config + +trait Extractor[A] { + def extract(config: Config, name: String): A +} + +object Extractor { + // note missing "implicit" + val stringExtractor = new Extractor[String] { + override def extract(config: Config, name: String): String = ??? + } +} + +class Workspace extends Dynamic { + val config: Config = new Config + + def selectDynamic[A](name: String)(implicit extractor: Extractor[A]): A = + extractor.extract(config, name) +} + +object Main { + val storage = new Workspace + + // this line works fine + // val a = storage.foo + + // this line crashes the compiler ("head of empty list") + // in ContextErrors$InferencerContextErrors$InferErrorGen$.NotWithinBoundsErrorMessage + println(storage.foo[String]) + + // this line crashes the compiler in different way ("unknown type") + // in the backend, warning: an unexpected type representation reached the compiler backend while compiling Test.scala: <error> + println(storage.foo) +} diff --git a/test/files/neg/t9636.check b/test/files/neg/t9636.check new file mode 100644 index 0000000000..f36d1d32b2 --- /dev/null +++ b/test/files/neg/t9636.check @@ -0,0 +1,6 @@ +t9636.scala:11: warning: a type was inferred to be `AnyVal`; this may indicate a programming error. + if (signature.sameElements(Array(0x1F, 0x8B))) { + ^ +error: No warnings can be incurred under -Xfatal-warnings. +one warning found +one error found diff --git a/test/files/neg/t9636.flags b/test/files/neg/t9636.flags new file mode 100644 index 0000000000..7949c2afa2 --- /dev/null +++ b/test/files/neg/t9636.flags @@ -0,0 +1 @@ +-Xlint -Xfatal-warnings diff --git a/test/files/neg/t9636.scala b/test/files/neg/t9636.scala new file mode 100644 index 0000000000..7ad5fb3e9e --- /dev/null +++ b/test/files/neg/t9636.scala @@ -0,0 +1,17 @@ + +import java.io._ +import java.util.zip._ + +class C { + def isWrapper(is: FileInputStream): InputStream = { + val pb = new PushbackInputStream(is, 2) + val signature = new Array[Byte](2) + pb.read(signature) + pb.unread(signature) + if (signature.sameElements(Array(0x1F, 0x8B))) { + new GZIPInputStream(new BufferedInputStream(pb)) + } else { + pb + } + } +} diff --git a/test/files/neg/t9675.check b/test/files/neg/t9675.check new file mode 100644 index 0000000000..255477499c --- /dev/null +++ b/test/files/neg/t9675.check @@ -0,0 +1,27 @@ +t9675.scala:4: warning: comparing values of types Test.A and String using `!=' will always yield true + val func1 = (x: A) => { x != "x" } + ^ +t9675.scala:6: warning: comparing values of types Test.A and String using `!=' will always yield true + val func2 = (x: A) => { x != "x" }: Boolean + ^ +t9675.scala:8: warning: comparing values of types Test.A and String using `!=' will always yield true + val func3: Function1[A, Boolean] = (x) => { x != "x" } + ^ +t9675.scala:11: warning: comparing values of types Test.A and String using `!=' will always yield true + def apply(x: A): Boolean = { x != "x" } + ^ +t9675.scala:14: warning: comparing values of types Test.A and String using `!=' will always yield true + def method(x: A): Boolean = { x != "x" } + ^ +t9675.scala:18: warning: comparing values of types Test.A and String using `!=' will always yield true + A("x") != "x" + ^ +t9675.scala:20: warning: comparing values of types Test.A and String using `!=' will always yield true + val func5: Function1[A, Boolean] = (x) => { x != "x" } + ^ +t9675.scala:22: warning: comparing values of types Test.A and String using `!=' will always yield true + List(A("x")).foreach((item: A) => item != "x") + ^ +error: No warnings can be incurred under -Xfatal-warnings. +8 warnings found +one error found diff --git a/test/files/neg/t9675.flags b/test/files/neg/t9675.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/neg/t9675.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/neg/t9675.scala b/test/files/neg/t9675.scala new file mode 100644 index 0000000000..f76b74b6ac --- /dev/null +++ b/test/files/neg/t9675.scala @@ -0,0 +1,24 @@ +object Test { + case class A(x: String) + + val func1 = (x: A) => { x != "x" } + + val func2 = (x: A) => { x != "x" }: Boolean + + val func3: Function1[A, Boolean] = (x) => { x != "x" } + + val func4 = new Function1[A, Boolean] { + def apply(x: A): Boolean = { x != "x" } + } + + def method(x: A): Boolean = { x != "x" } + case class PersonInfo(rankPayEtc: Unit) + + def main(args: Array[String]) { + A("x") != "x" + + val func5: Function1[A, Boolean] = (x) => { x != "x" } + + List(A("x")).foreach((item: A) => item != "x") + } +} diff --git a/test/files/neg/warn-inferred-any.check b/test/files/neg/warn-inferred-any.check index 8ad81d1529..2b321a83c9 100644 --- a/test/files/neg/warn-inferred-any.check +++ b/test/files/neg/warn-inferred-any.check @@ -9,7 +9,7 @@ warn-inferred-any.scala:17: warning: a type was inferred to be `AnyVal`; this ma ^ warn-inferred-any.scala:25: warning: a type was inferred to be `Any`; this may indicate a programming error. def za = f(1, "one") - ^ + ^ error: No warnings can be incurred under -Xfatal-warnings. four warnings found one error found diff --git a/test/files/pos/t10066.scala b/test/files/pos/t10066.scala new file mode 100644 index 0000000000..bef85cb08c --- /dev/null +++ b/test/files/pos/t10066.scala @@ -0,0 +1,38 @@ +package dynamicrash + +import scala.language.dynamics + +class Config + +trait Extractor[A] { + def extract(config: Config, name: String): A +} + +object Extractor { + // this has "implicit", unlike the corresponding neg test + implicit val stringExtractor = new Extractor[String] { + override def extract(config: Config, name: String): String = ??? + } +} + +class Workspace extends Dynamic { + val config: Config = new Config + + def selectDynamic[A](name: String)(implicit extractor: Extractor[A]): A = + extractor.extract(config, name) +} + +object Main { + val storage = new Workspace + + // this line works fine + // val a = storage.foo + + // this line crashes the compiler ("head of empty list") + // in ContextErrors$InferencerContextErrors$InferErrorGen$.NotWithinBoundsErrorMessage + println(storage.foo[String]) + + // this line crashes the compiler in different way ("unknown type") + // in the backend, warning: an unexpected type representation reached the compiler backend while compiling Test.scala: <error> + println(storage.foo) +} diff --git a/test/files/run/literals.scala b/test/files/run/literals.scala index 13fda05876..25501123b5 100644 --- a/test/files/run/literals.scala +++ b/test/files/run/literals.scala @@ -84,6 +84,10 @@ object Test { check_success("3.14f == 3.14f", 3.14f, 3.14f) check_success("6.022e23f == 6.022e23f", 6.022e23f, 6.022e23f) check_success("09f == 9.0f", 09f, 9.0f) + check_success("1.00000017881393421514957253748434595763683319091796875001f == 1.0000001f", + 1.00000017881393421514957253748434595763683319091796875001f, + 1.0000001f) + check_success("3.4028235E38f == Float.MaxValue", 3.4028235E38f, Float.MaxValue) check_success("1.asInstanceOf[Float] == 1.0", 1.asInstanceOf[Float], 1.0f) check_success("1l.asInstanceOf[Float] == 1.0", 1l.asInstanceOf[Float], 1.0f) @@ -97,6 +101,7 @@ object Test { check_success("3.14 == 3.14", 3.14, 3.14) check_success("1e-9d == 1.0e-9", 1e-9d, 1.0e-9) check_success("1e137 == 1.0e137", 1e137, 1.0e137) + check_success("1.7976931348623157e308d == Double.MaxValue", 1.7976931348623157e308d, Double.MaxValue) check_success("1.asInstanceOf[Double] == 1.0", 1.asInstanceOf[Double], 1.0) check_success("1l.asInstanceOf[Double] == 1.0", 1l.asInstanceOf[Double], 1.0) diff --git a/test/files/run/t10072.scala b/test/files/run/t10072.scala new file mode 100644 index 0000000000..0f1dca1838 --- /dev/null +++ b/test/files/run/t10072.scala @@ -0,0 +1,18 @@ +trait T[A] { + def a: A + def foldLeft[B](zero: B, op: (B, A) => B): B = op(zero, a) + def sum[B >: A](zero: B): B +} + +class C[@specialized(Int) A](val a: A) extends T[A] { + override def sum[@specialized(Int) B >: A](zero: B): B = foldLeft(zero, (x: B, y: B) => x) +} + +object Test extends App { + def factory[T](a: T): C[T] = new C[T](a) + + assert(new C[Int](1).sum(2) == 2) + assert(new C[String]("ho").sum("hu") == "hu") + assert(factory[Int](1).sum(2) == 2) + assert(factory[String]("ho").sum("hu") == "hu") +} diff --git a/test/files/run/t4700.check b/test/files/run/t4700.check new file mode 100644 index 0000000000..ae854b959d --- /dev/null +++ b/test/files/run/t4700.check @@ -0,0 +1,44 @@ + +scala> import scala.annotation.showAsInfix +import scala.annotation.showAsInfix + +scala> class &&[T,U] +defined class $amp$amp + +scala> def foo: Int && Boolean = ??? +foo: Int && Boolean + +scala> def foo: Int && Boolean && String = ??? +foo: Int && Boolean && String + +scala> def foo: Int && (Boolean && String) = ??? +foo: Int && (Boolean && String) + +scala> @showAsInfix type Mappy[T, U] = Map[T, U] +defined type alias Mappy + +scala> def foo: Int Mappy (Boolean && String) = ??? +foo: Int Mappy (Boolean && String) + +scala> @showAsInfix(false) class ||[T,U] +defined class $bar$bar + +scala> def foo: Int || Boolean = ??? +foo: ||[Int,Boolean] + +scala> class &:[L, R] +defined class $amp$colon + +scala> def foo: Int &: String = ??? +foo: Int &: String + +scala> def foo: Int &: Boolean &: String = ??? +foo: Int &: Boolean &: String + +scala> def foo: (Int && String) &: Boolean = ??? +foo: (Int && String) &: Boolean + +scala> def foo: Int && (Boolean &: String) = ??? +foo: Int && (Boolean &: String) + +scala> :quit diff --git a/test/files/run/t4700.scala b/test/files/run/t4700.scala new file mode 100644 index 0000000000..7c02676e89 --- /dev/null +++ b/test/files/run/t4700.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.interpreter._ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ + |import scala.annotation.showAsInfix + |class &&[T,U] + |def foo: Int && Boolean = ??? + |def foo: Int && Boolean && String = ??? + |def foo: Int && (Boolean && String) = ??? + |@showAsInfix type Mappy[T, U] = Map[T, U] + |def foo: Int Mappy (Boolean && String) = ??? + |@showAsInfix(false) class ||[T,U] + |def foo: Int || Boolean = ??? + |class &:[L, R] + |def foo: Int &: String = ??? + |def foo: Int &: Boolean &: String = ??? + |def foo: (Int && String) &: Boolean = ??? + |def foo: Int && (Boolean &: String) = ??? + |""".stripMargin +} + diff --git a/test/junit/scala/collection/concurrent/TrieMapTest.scala b/test/junit/scala/collection/concurrent/TrieMapTest.scala new file mode 100644 index 0000000000..ed67f3e9a9 --- /dev/null +++ b/test/junit/scala/collection/concurrent/TrieMapTest.scala @@ -0,0 +1,54 @@ +package scala.collection.concurrent + +import org.junit.{Assert, Test} + +class TrieMapTest { + + private def check[T](result2: List[Any])(f: TrieMap[String, String] => TraversableOnce[Any]) = { + val m = TrieMap[String, String]() + val values = f(m) + m.put("k", "v") + Assert.assertEquals(Nil, values.toList) + Assert.assertEquals(result2, f(m).toList) + } + + @Test + def iterator(): Unit = { + check(List(("k", "v")))(_.iterator) + } + + @Test + def values(): Unit = { + check(List("v"))(_.values) + } + + @Test + def valuesIterator(): Unit = { + check(List("v"))(_.valuesIterator) + } + + @Test + def keySet(): Unit = { + check(List("k"))(_.keySet) + } + + @Test + def keysIterator(): Unit = { + check(List("k"))(_.keysIterator) + } + + @Test + def keys(): Unit = { + check(List("k"))(_.keys) + } + + @Test + def filterKeys(): Unit = { + check(List(("k", "v")))(_.filterKeys(_ => true)) + } + + @Test + def mapValues(): Unit = { + check(List(("k", "v")))(_.mapValues(x => x)) + } +} diff --git a/test/junit/scala/collection/mutable/BitSetTest.scala b/test/junit/scala/collection/mutable/BitSetTest.scala index 84b906e8d5..f0a0ef5d75 100644 --- a/test/junit/scala/collection/mutable/BitSetTest.scala +++ b/test/junit/scala/collection/mutable/BitSetTest.scala @@ -7,7 +7,7 @@ import org.junit.runners.JUnit4 @RunWith(classOf[JUnit4]) class BitSetTest { // Test for SI-8910 - @Test def capacityExpansionTest() { + @Test def capacityExpansionTest(): Unit = { val bitSet = BitSet.empty val size = bitSet.toBitMask.length bitSet ^= bitSet @@ -20,7 +20,7 @@ class BitSetTest { assert(bitSet.toBitMask.length == size, "Capacity of bitset changed after &~=") } - @Test def test_SI8917() { + @Test def test_SI8917(): Unit = { val bigBitSet = BitSet(1, 100, 10000) val littleBitSet = BitSet(100) bigBitSet &= littleBitSet @@ -29,10 +29,16 @@ class BitSetTest { assert(littleBitSet.toBitMask.length < bigBitSet.toBitMask.length, "Needlessly extended the size of bitset on &=") } - @Test def test_SI8647() { + @Test def test_SI8647(): Unit = { val bs = BitSet() bs.map(_ + 1) // Just needs to compile val xs = bs: SortedSet[Int] xs.map(_ + 1) // Also should compile (did before) } + + @Test def t10164(): Unit = { + val bs = BitSet() + val last = (bs ++ (0 to 128)).last // Just needs not to throw + assert(last == 128) + } } diff --git a/test/partest b/test/partest deleted file mode 100755 index d74176aa8a..0000000000 --- a/test/partest +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bash -# -############################################################################## -# Scala test runner 2.10.0 -############################################################################## -# (c) 2002-2013 LAMP/EPFL -# -# This is free software; see the distribution for copying conditions. -# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. -############################################################################## - -findScalaHome () { - # see SI-2092 and SI-5792 - local source="${BASH_SOURCE[0]}" - while [ -h "$source" ] ; do - local linked="$(readlink "$source")" - local dir="$( cd -P $(dirname "$source") && cd -P $(dirname "$linked") && pwd )" - source="$dir/$(basename "$linked")" - done - ( ( cd -P "$(dirname "$source")/.." > /dev/null ) && pwd ) -} - -# Use tput to detect color-capable terminal. -# (note: I have found that on Cygwin, the script sometimes dies here. -# it doesn't happen from the Cygwin prompt when ssh'ing in to -# jenkins-worker-windows-publish, only when I make a Jenkins job -# that runs this script. I don't know why. it may have to do with -# which bash flags are set (-e? -x?) and with bash flags propagating -# from one script to another? not sure. anyway, normally in a CI -# context we run partest through sbt, not through this script, so I'm -# not investigating further for now.) -term_colors=$(tput colors 2>/dev/null) -if [[ $? == 0 ]] && [[ $term_colors -gt 2 ]]; then - git_diff_options="--color=always --word-diff" - color_opts="-Dpartest.colors=$term_colors" -else - unset color_opts - git_diff_options="--nocolor" -fi - -cygwin=false; -darwin=false; -case "`uname`" in - CYGWIN*) cygwin=true ;; - Darwin*) darwin=true ;; -esac - -# Finding the root folder for this Scala distribution -SCALA_HOME="$(findScalaHome)" - -if $cygwin; then - SCALA_HOME=`cygpath --windows --short-name "$SCALA_HOME"` - SCALA_HOME=`cygpath --unix "$SCALA_HOME"` -fi - -# Let sbt construct the classpath used to run partest (downloading partest from maven if necessary) -# PARTEST_CLASSPATH="" -if [ -z "$PARTEST_CLASSPATH" ] ; then - if [ ! -f "$SCALA_HOME/build/quick/partest.properties" ] ; then - (cd "$SCALA_HOME" && sbt dist/mkQuick) # builds quick, downloads partest and writes classpath to build/quick/partest.properties - fi - - PARTEST_CLASSPATH=$( cat "$SCALA_HOME/build/quick/partest.properties" | grep partest.classpath | sed -e 's/\\:/:/g' | cut -f2- -d= ) - - # sanity check, disabled to save time - # $( javap -classpath $PARTEST_CLASSPATH scala.tools.partest.nest.NestRunner &> /dev/null ) || unset PARTEST_CLASSPATH -fi - -# if [ -z "$PARTEST_CLASSPATH" ] ; then -# if [ -f "$SCALA_HOME/lib/scala-partest.jar" ] ; then -# for ext in "$SCALA_HOME"/lib/* ; do -# if [ -z "$PARTEST_CLASSPATH" ] ; then -# PARTEST_CLASSPATH="$ext" -# else -# PARTEST_CLASSPATH="$PARTEST_CLASSPATH:$ext" -# fi -# done -# elif [ -f "$SCALA_HOME/build/pack/lib/scala-partest.jar" ] ; then -# for lib in `echo "scala-partest scala-library scala-parser-combinators scala-xml scala-reflect scala-compiler diffutils"`; do -# ext="$SCALA_HOME/build/pack/lib/$lib.jar" -# if [ -z "$PARTEST_CLASSPATH" ] ; then -# PARTEST_CLASSPATH="$ext" -# else -# PARTEST_CLASSPATH="$PARTEST_CLASSPATH:$ext" -# fi -# done -# fi -# fi - -# Locate a javac command -# Try: JAVA_HOME, sibling to specific JAVACMD, or PATH -# Don't fail if there is no javac, since not all tests require it. -if [ -z "$JAVAC_CMD" ] ; then - if [ -n "${JAVA_HOME}" ] && [ -f "${JAVA_HOME}/bin/javac" ] ; then - JAVAC_CMD="${JAVA_HOME}/bin/javac" - fi - if [ -z "$JAVAC_CMD" ] && [ -n "$JAVACMD" ] ; then - JDIR=`dirname "${JAVACMD}"` - JAVAC_CMD="${JDIR}/javac" - fi - if [ -z "$JAVAC_CMD" ] ; then - JAVAC_CMD=`type -p javac` - fi -fi - -if $cygwin; then - if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then - format=mixed - else - format=windows - fi - if [ -n "${JAVA_HOME}" ] ; then - JAVA_HOME=`cygpath --$format "$JAVA_HOME"` - fi - if [ -n "${JAVACMD}" ] ; then - JAVACMD=`cygpath --$format "$JAVACMD"` - fi - if [ -n "${JAVAC_CMD}" ] ; then - JAVAC_CMD=`cygpath --$format "$JAVAC_CMD"` - fi - SCALA_HOME=`cygpath --$format "$SCALA_HOME"` -fi - -# last arg wins, so if JAVA_OPTS already contains -Xmx or -Xms the -# supplied argument will be used. -JAVA_OPTS="-Xmx1024M -Xms64M $JAVA_OPTS" - -# the sbt task doesn't supply any options by default, -# so don't do that here either -- note that you may want to pass -optimise -# to mimic what happens during nightlies. -# [ -n "$SCALAC_OPTS" ] || SCALAC_OPTS="-deprecation" - -partestDebugStr="" -if [ ! -z "${PARTEST_DEBUG}" ] ; then - partestDebugStr="-Dpartest.debug=${PARTEST_DEBUG}" -fi - -# note that variables which may intentionally be empty must not -# be quoted: otherwise an empty string will appear as a command line -# argument, and java will think that is the program to run. -"${JAVACMD:=java}" \ - $JAVA_OPTS -cp "$PARTEST_CLASSPATH" \ - ${partestDebugStr} \ - ${color_opts} \ - -Dfile.encoding=UTF-8 \ - -Dscala.home="${SCALA_HOME}" \ - -Dpartest.javacmd="${JAVACMD}" \ - -Dpartest.java_opts="${JAVA_OPTS}" \ - -Dpartest.scalac_opts="${SCALAC_OPTS}" \ - -Dpartest.javac_cmd="${JAVAC_CMD}" \ - scala.tools.partest.nest.ConsoleRunner "$@" diff --git a/test/simplejson/__init__.py b/test/simplejson/__init__.py deleted file mode 100644 index d5b4d39913..0000000000 --- a/test/simplejson/__init__.py +++ /dev/null @@ -1,318 +0,0 @@ -r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of -JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data -interchange format. - -:mod:`simplejson` exposes an API familiar to users of the standard library -:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained -version of the :mod:`json` library contained in Python 2.6, but maintains -compatibility with Python 2.4 and Python 2.5 and (currently) has -significant performance advantages, even without using the optional C -extension for speedups. - -Encoding basic Python object hierarchies:: - - >>> import simplejson as json - >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) - '["foo", {"bar": ["baz", null, 1.0, 2]}]' - >>> print json.dumps("\"foo\bar") - "\"foo\bar" - >>> print json.dumps(u'\u1234') - "\u1234" - >>> print json.dumps('\\') - "\\" - >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True) - {"a": 0, "b": 0, "c": 0} - >>> from StringIO import StringIO - >>> io = StringIO() - >>> json.dump(['streaming API'], io) - >>> io.getvalue() - '["streaming API"]' - -Compact encoding:: - - >>> import simplejson as json - >>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':')) - '[1,2,3,{"4":5,"6":7}]' - -Pretty printing:: - - >>> import simplejson as json - >>> s = json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4) - >>> print '\n'.join([l.rstrip() for l in s.splitlines()]) - { - "4": 5, - "6": 7 - } - -Decoding JSON:: - - >>> import simplejson as json - >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}] - >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj - True - >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar' - True - >>> from StringIO import StringIO - >>> io = StringIO('["streaming API"]') - >>> json.load(io)[0] == 'streaming API' - True - -Specializing JSON object decoding:: - - >>> import simplejson as json - >>> def as_complex(dct): - ... if '__complex__' in dct: - ... return complex(dct['real'], dct['imag']) - ... return dct - ... - >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', - ... object_hook=as_complex) - (1+2j) - >>> import decimal - >>> json.loads('1.1', parse_float=decimal.Decimal) == decimal.Decimal('1.1') - True - -Specializing JSON object encoding:: - - >>> import simplejson as json - >>> def encode_complex(obj): - ... if isinstance(obj, complex): - ... return [obj.real, obj.imag] - ... raise TypeError(repr(o) + " is not JSON serializable") - ... - >>> json.dumps(2 + 1j, default=encode_complex) - '[2.0, 1.0]' - >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) - '[2.0, 1.0]' - >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) - '[2.0, 1.0]' - - -Using simplejson.tool from the shell to validate and pretty-print:: - - $ echo '{"json":"obj"}' | python -m simplejson.tool - { - "json": "obj" - } - $ echo '{ 1.2:3.4}' | python -m simplejson.tool - Expecting property name: line 1 column 2 (char 2) -""" -__version__ = '2.0.9' -__all__ = [ - 'dump', 'dumps', 'load', 'loads', - 'JSONDecoder', 'JSONEncoder', -] - -__author__ = 'Bob Ippolito <bob@redivi.com>' - -from decoder import JSONDecoder -from encoder import JSONEncoder - -_default_encoder = JSONEncoder( - skipkeys=False, - ensure_ascii=True, - check_circular=True, - allow_nan=True, - indent=None, - separators=None, - encoding='utf-8', - default=None, -) - -def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, - allow_nan=True, cls=None, indent=None, separators=None, - encoding='utf-8', default=None, **kw): - """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a - ``.write()``-supporting file-like object). - - If ``skipkeys`` is true then ``dict`` keys that are not basic types - (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) - will be skipped instead of raising a ``TypeError``. - - If ``ensure_ascii`` is false, then the some chunks written to ``fp`` - may be ``unicode`` instances, subject to normal Python ``str`` to - ``unicode`` coercion rules. Unless ``fp.write()`` explicitly - understands ``unicode`` (as in ``codecs.getwriter()``) this is likely - to cause an error. - - If ``check_circular`` is false, then the circular reference check - for container types will be skipped and a circular reference will - result in an ``OverflowError`` (or worse). - - If ``allow_nan`` is false, then it will be a ``ValueError`` to - serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) - in strict compliance of the JSON specification, instead of using the - JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). - - If ``indent`` is a non-negative integer, then JSON array elements and object - members will be pretty-printed with that indent level. An indent level - of 0 will only insert newlines. ``None`` is the most compact representation. - - If ``separators`` is an ``(item_separator, dict_separator)`` tuple - then it will be used instead of the default ``(', ', ': ')`` separators. - ``(',', ':')`` is the most compact JSON representation. - - ``encoding`` is the character encoding for str instances, default is UTF-8. - - ``default(obj)`` is a function that should return a serializable version - of obj or raise TypeError. The default simply raises TypeError. - - To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the - ``.default()`` method to serialize additional types), specify it with - the ``cls`` kwarg. - - """ - # cached encoder - if (not skipkeys and ensure_ascii and - check_circular and allow_nan and - cls is None and indent is None and separators is None and - encoding == 'utf-8' and default is None and not kw): - iterable = _default_encoder.iterencode(obj) - else: - if cls is None: - cls = JSONEncoder - iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, - check_circular=check_circular, allow_nan=allow_nan, indent=indent, - separators=separators, encoding=encoding, - default=default, **kw).iterencode(obj) - # could accelerate with writelines in some versions of Python, at - # a debuggability cost - for chunk in iterable: - fp.write(chunk) - - -def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, - allow_nan=True, cls=None, indent=None, separators=None, - encoding='utf-8', default=None, **kw): - """Serialize ``obj`` to a JSON formatted ``str``. - - If ``skipkeys`` is false then ``dict`` keys that are not basic types - (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) - will be skipped instead of raising a ``TypeError``. - - If ``ensure_ascii`` is false, then the return value will be a - ``unicode`` instance subject to normal Python ``str`` to ``unicode`` - coercion rules instead of being escaped to an ASCII ``str``. - - If ``check_circular`` is false, then the circular reference check - for container types will be skipped and a circular reference will - result in an ``OverflowError`` (or worse). - - If ``allow_nan`` is false, then it will be a ``ValueError`` to - serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in - strict compliance of the JSON specification, instead of using the - JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). - - If ``indent`` is a non-negative integer, then JSON array elements and - object members will be pretty-printed with that indent level. An indent - level of 0 will only insert newlines. ``None`` is the most compact - representation. - - If ``separators`` is an ``(item_separator, dict_separator)`` tuple - then it will be used instead of the default ``(', ', ': ')`` separators. - ``(',', ':')`` is the most compact JSON representation. - - ``encoding`` is the character encoding for str instances, default is UTF-8. - - ``default(obj)`` is a function that should return a serializable version - of obj or raise TypeError. The default simply raises TypeError. - - To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the - ``.default()`` method to serialize additional types), specify it with - the ``cls`` kwarg. - - """ - # cached encoder - if (not skipkeys and ensure_ascii and - check_circular and allow_nan and - cls is None and indent is None and separators is None and - encoding == 'utf-8' and default is None and not kw): - return _default_encoder.encode(obj) - if cls is None: - cls = JSONEncoder - return cls( - skipkeys=skipkeys, ensure_ascii=ensure_ascii, - check_circular=check_circular, allow_nan=allow_nan, indent=indent, - separators=separators, encoding=encoding, default=default, - **kw).encode(obj) - - -_default_decoder = JSONDecoder(encoding=None, object_hook=None) - - -def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, **kw): - """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing - a JSON document) to a Python object. - - If the contents of ``fp`` is encoded with an ASCII based encoding other - than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must - be specified. Encodings that are not ASCII based (such as UCS-2) are - not allowed, and should be wrapped with - ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode`` - object and passed to ``loads()`` - - ``object_hook`` is an optional function that will be called with the - result of any object literal decode (a ``dict``). The return value of - ``object_hook`` will be used instead of the ``dict``. This feature - can be used to implement custom decoders (e.g. JSON-RPC class hinting). - - To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` - kwarg. - - """ - return loads(fp.read(), - encoding=encoding, cls=cls, object_hook=object_hook, - parse_float=parse_float, parse_int=parse_int, - parse_constant=parse_constant, **kw) - - -def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, **kw): - """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON - document) to a Python object. - - If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding - other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name - must be specified. Encodings that are not ASCII based (such as UCS-2) - are not allowed and should be decoded to ``unicode`` first. - - ``object_hook`` is an optional function that will be called with the - result of any object literal decode (a ``dict``). The return value of - ``object_hook`` will be used instead of the ``dict``. This feature - can be used to implement custom decoders (e.g. JSON-RPC class hinting). - - ``parse_float``, if specified, will be called with the string - of every JSON float to be decoded. By default this is equivalent to - float(num_str). This can be used to use another datatype or parser - for JSON floats (e.g. decimal.Decimal). - - ``parse_int``, if specified, will be called with the string - of every JSON int to be decoded. By default this is equivalent to - int(num_str). This can be used to use another datatype or parser - for JSON integers (e.g. float). - - ``parse_constant``, if specified, will be called with one of the - following strings: -Infinity, Infinity, NaN, null, true, false. - This can be used to raise an exception if invalid JSON numbers - are encountered. - - To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` - kwarg. - - """ - if (cls is None and encoding is None and object_hook is None and - parse_int is None and parse_float is None and - parse_constant is None and not kw): - return _default_decoder.decode(s) - if cls is None: - cls = JSONDecoder - if object_hook is not None: - kw['object_hook'] = object_hook - if parse_float is not None: - kw['parse_float'] = parse_float - if parse_int is not None: - kw['parse_int'] = parse_int - if parse_constant is not None: - kw['parse_constant'] = parse_constant - return cls(encoding=encoding, **kw).decode(s) diff --git a/test/simplejson/decoder.py b/test/simplejson/decoder.py deleted file mode 100644 index b769ea486c..0000000000 --- a/test/simplejson/decoder.py +++ /dev/null @@ -1,354 +0,0 @@ -"""Implementation of JSONDecoder -""" -import re -import sys -import struct - -from simplejson.scanner import make_scanner -try: - from simplejson._speedups import scanstring as c_scanstring -except ImportError: - c_scanstring = None - -__all__ = ['JSONDecoder'] - -FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL - -def _floatconstants(): - _BYTES = '7FF80000000000007FF0000000000000'.decode('hex') - if sys.byteorder != 'big': - _BYTES = _BYTES[:8][::-1] + _BYTES[8:][::-1] - nan, inf = struct.unpack('dd', _BYTES) - return nan, inf, -inf - -NaN, PosInf, NegInf = _floatconstants() - - -def linecol(doc, pos): - lineno = doc.count('\n', 0, pos) + 1 - if lineno == 1: - colno = pos - else: - colno = pos - doc.rindex('\n', 0, pos) - return lineno, colno - - -def errmsg(msg, doc, pos, end=None): - # Note that this function is called from _speedups - lineno, colno = linecol(doc, pos) - if end is None: - #fmt = '{0}: line {1} column {2} (char {3})' - #return fmt.format(msg, lineno, colno, pos) - fmt = '%s: line %d column %d (char %d)' - return fmt % (msg, lineno, colno, pos) - endlineno, endcolno = linecol(doc, end) - #fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})' - #return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end) - fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' - return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) - - -_CONSTANTS = { - '-Infinity': NegInf, - 'Infinity': PosInf, - 'NaN': NaN, -} - -STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS) -BACKSLASH = { - '"': u'"', '\\': u'\\', '/': u'/', - 'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t', -} - -DEFAULT_ENCODING = "utf-8" - -def py_scanstring(s, end, encoding=None, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match): - """Scan the string s for a JSON string. End is the index of the - character in s after the quote that started the JSON string. - Unescapes all valid JSON string escape sequences and raises ValueError - on attempt to decode an invalid string. If strict is False then literal - control characters are allowed in the string. - - Returns a tuple of the decoded string and the index of the character in s - after the end quote.""" - if encoding is None: - encoding = DEFAULT_ENCODING - chunks = [] - _append = chunks.append - begin = end - 1 - while 1: - chunk = _m(s, end) - if chunk is None: - raise ValueError( - errmsg("Unterminated string starting at", s, begin)) - end = chunk.end() - content, terminator = chunk.groups() - # Content is contains zero or more unescaped string characters - if content: - if not isinstance(content, unicode): - content = unicode(content, encoding) - _append(content) - # Terminator is the end of string, a literal control character, - # or a backslash denoting that an escape sequence follows - if terminator == '"': - break - elif terminator != '\\': - if strict: - msg = "Invalid control character %r at" % (terminator,) - #msg = "Invalid control character {0!r} at".format(terminator) - raise ValueError(errmsg(msg, s, end)) - else: - _append(terminator) - continue - try: - esc = s[end] - except IndexError: - raise ValueError( - errmsg("Unterminated string starting at", s, begin)) - # If not a unicode escape sequence, must be in the lookup table - if esc != 'u': - try: - char = _b[esc] - except KeyError: - msg = "Invalid \\escape: " + repr(esc) - raise ValueError(errmsg(msg, s, end)) - end += 1 - else: - # Unicode escape sequence - esc = s[end + 1:end + 5] - next_end = end + 5 - if len(esc) != 4: - msg = "Invalid \\uXXXX escape" - raise ValueError(errmsg(msg, s, end)) - uni = int(esc, 16) - # Check for surrogate pair on UCS-4 systems - if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535: - msg = "Invalid \\uXXXX\\uXXXX surrogate pair" - if not s[end + 5:end + 7] == '\\u': - raise ValueError(errmsg(msg, s, end)) - esc2 = s[end + 7:end + 11] - if len(esc2) != 4: - raise ValueError(errmsg(msg, s, end)) - uni2 = int(esc2, 16) - uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) - next_end += 6 - char = unichr(uni) - end = next_end - # Append the unescaped character - _append(char) - return u''.join(chunks), end - - -# Use speedup if available -scanstring = c_scanstring or py_scanstring - -WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS) -WHITESPACE_STR = ' \t\n\r' - -def JSONObject((s, end), encoding, strict, scan_once, object_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): - pairs = {} - # Use a slice to prevent IndexError from being raised, the following - # check will raise a more specific ValueError if the string is empty - nextchar = s[end:end + 1] - # Normally we expect nextchar == '"' - if nextchar != '"': - if nextchar in _ws: - end = _w(s, end).end() - nextchar = s[end:end + 1] - # Trivial empty object - if nextchar == '}': - return pairs, end + 1 - elif nextchar != '"': - raise ValueError(errmsg("Expecting property name", s, end)) - end += 1 - while True: - key, end = scanstring(s, end, encoding, strict) - - # To skip some function call overhead we optimize the fast paths where - # the JSON key separator is ": " or just ":". - if s[end:end + 1] != ':': - end = _w(s, end).end() - if s[end:end + 1] != ':': - raise ValueError(errmsg("Expecting : delimiter", s, end)) - - end += 1 - - try: - if s[end] in _ws: - end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() - except IndexError: - pass - - try: - value, end = scan_once(s, end) - except StopIteration: - raise ValueError(errmsg("Expecting object", s, end)) - pairs[key] = value - - try: - nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end] - except IndexError: - nextchar = '' - end += 1 - - if nextchar == '}': - break - elif nextchar != ',': - raise ValueError(errmsg("Expecting , delimiter", s, end - 1)) - - try: - nextchar = s[end] - if nextchar in _ws: - end += 1 - nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end] - except IndexError: - nextchar = '' - - end += 1 - if nextchar != '"': - raise ValueError(errmsg("Expecting property name", s, end - 1)) - - if object_hook is not None: - pairs = object_hook(pairs) - return pairs, end - -def JSONArray((s, end), scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): - values = [] - nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end:end + 1] - # Look-ahead for trivial empty array - if nextchar == ']': - return values, end + 1 - _append = values.append - while True: - try: - value, end = scan_once(s, end) - except StopIteration: - raise ValueError(errmsg("Expecting object", s, end)) - _append(value) - nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end:end + 1] - end += 1 - if nextchar == ']': - break - elif nextchar != ',': - raise ValueError(errmsg("Expecting , delimiter", s, end)) - - try: - if s[end] in _ws: - end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() - except IndexError: - pass - - return values, end - -class JSONDecoder(object): - """Simple JSON <http://json.org> decoder - - Performs the following translations in decoding by default: - - +---------------+-------------------+ - | JSON | Python | - +===============+===================+ - | object | dict | - +---------------+-------------------+ - | array | list | - +---------------+-------------------+ - | string | unicode | - +---------------+-------------------+ - | number (int) | int, long | - +---------------+-------------------+ - | number (real) | float | - +---------------+-------------------+ - | true | True | - +---------------+-------------------+ - | false | False | - +---------------+-------------------+ - | null | None | - +---------------+-------------------+ - - It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as - their corresponding ``float`` values, which is outside the JSON spec. - - """ - - def __init__(self, encoding=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, strict=True): - """``encoding`` determines the encoding used to interpret any ``str`` - objects decoded by this instance (utf-8 by default). It has no - effect when decoding ``unicode`` objects. - - Note that currently only encodings that are a superset of ASCII work, - strings of other encodings should be passed in as ``unicode``. - - ``object_hook``, if specified, will be called with the result - of every JSON object decoded and its return value will be used in - place of the given ``dict``. This can be used to provide custom - deserializations (e.g. to support JSON-RPC class hinting). - - ``parse_float``, if specified, will be called with the string - of every JSON float to be decoded. By default this is equivalent to - float(num_str). This can be used to use another datatype or parser - for JSON floats (e.g. decimal.Decimal). - - ``parse_int``, if specified, will be called with the string - of every JSON int to be decoded. By default this is equivalent to - int(num_str). This can be used to use another datatype or parser - for JSON integers (e.g. float). - - ``parse_constant``, if specified, will be called with one of the - following strings: -Infinity, Infinity, NaN. - This can be used to raise an exception if invalid JSON numbers - are encountered. - - """ - self.encoding = encoding - self.object_hook = object_hook - self.parse_float = parse_float or float - self.parse_int = parse_int or int - self.parse_constant = parse_constant or _CONSTANTS.__getitem__ - self.strict = strict - self.parse_object = JSONObject - self.parse_array = JSONArray - self.parse_string = scanstring - self.scan_once = make_scanner(self) - - def decode(self, s, _w=WHITESPACE.match): - """Return the Python representation of ``s`` (a ``str`` or ``unicode`` - instance containing a JSON document) - - """ - obj, end = self.raw_decode(s, idx=_w(s, 0).end()) - end = _w(s, end).end() - if end != len(s): - raise ValueError(errmsg("Extra data", s, end, len(s))) - return obj - - def raw_decode(self, s, idx=0): - """Decode a JSON document from ``s`` (a ``str`` or ``unicode`` beginning - with a JSON document) and return a 2-tuple of the Python - representation and the index in ``s`` where the document ended. - - This can be used to decode a JSON document from a string that may - have extraneous data at the end. - - """ - try: - obj, end = self.scan_once(s, idx) - except StopIteration: - raise ValueError("No JSON object could be decoded") - return obj, end diff --git a/test/simplejson/encoder.py b/test/simplejson/encoder.py deleted file mode 100644 index cf58290366..0000000000 --- a/test/simplejson/encoder.py +++ /dev/null @@ -1,440 +0,0 @@ -"""Implementation of JSONEncoder -""" -import re - -try: - from simplejson._speedups import encode_basestring_ascii as c_encode_basestring_ascii -except ImportError: - c_encode_basestring_ascii = None -try: - from simplejson._speedups import make_encoder as c_make_encoder -except ImportError: - c_make_encoder = None - -ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') -ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') -HAS_UTF8 = re.compile(r'[\x80-\xff]') -ESCAPE_DCT = { - '\\': '\\\\', - '"': '\\"', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', -} -for i in range(0x20): - #ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i)) - ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) - -# Assume this produces an infinity on all machines (probably not guaranteed) -INFINITY = float('1e66666') -FLOAT_REPR = repr - -def encode_basestring(s): - """Return a JSON representation of a Python string - - """ - def replace(match): - return ESCAPE_DCT[match.group(0)] - return '"' + ESCAPE.sub(replace, s) + '"' - - -def py_encode_basestring_ascii(s): - """Return an ASCII-only JSON representation of a Python string - - """ - if isinstance(s, str) and HAS_UTF8.search(s) is not None: - s = s.decode('utf-8') - def replace(match): - s = match.group(0) - try: - return ESCAPE_DCT[s] - except KeyError: - n = ord(s) - if n < 0x10000: - #return '\\u{0:04x}'.format(n) - return '\\u%04x' % (n,) - else: - # surrogate pair - n -= 0x10000 - s1 = 0xd800 | ((n >> 10) & 0x3ff) - s2 = 0xdc00 | (n & 0x3ff) - #return '\\u{0:04x}\\u{1:04x}'.format(s1, s2) - return '\\u%04x\\u%04x' % (s1, s2) - return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' - - -encode_basestring_ascii = c_encode_basestring_ascii or py_encode_basestring_ascii - -class JSONEncoder(object): - """Extensible JSON <http://json.org> encoder for Python data structures. - - Supports the following objects and types by default: - - +-------------------+---------------+ - | Python | JSON | - +===================+===============+ - | dict | object | - +-------------------+---------------+ - | list, tuple | array | - +-------------------+---------------+ - | str, unicode | string | - +-------------------+---------------+ - | int, long, float | number | - +-------------------+---------------+ - | True | true | - +-------------------+---------------+ - | False | false | - +-------------------+---------------+ - | None | null | - +-------------------+---------------+ - - To extend this to recognize other objects, subclass and implement a - ``.default()`` method with another method that returns a serializable - object for ``o`` if possible, otherwise it should call the superclass - implementation (to raise ``TypeError``). - - """ - item_separator = ', ' - key_separator = ': ' - def __init__(self, skipkeys=False, ensure_ascii=True, - check_circular=True, allow_nan=True, sort_keys=False, - indent=None, separators=None, encoding='utf-8', default=None): - """Constructor for JSONEncoder, with sensible defaults. - - If skipkeys is false, then it is a TypeError to attempt - encoding of keys that are not str, int, long, float or None. If - skipkeys is True, such items are simply skipped. - - If ensure_ascii is true, the output is guaranteed to be str - objects with all incoming unicode characters escaped. If - ensure_ascii is false, the output will be unicode object. - - If check_circular is true, then lists, dicts, and custom encoded - objects will be checked for circular references during encoding to - prevent an infinite recursion (which would cause an OverflowError). - Otherwise, no such check takes place. - - If allow_nan is true, then NaN, Infinity, and -Infinity will be - encoded as such. This behavior is not JSON specification compliant, - but is consistent with most JavaScript based encoders and decoders. - Otherwise, it will be a ValueError to encode such floats. - - If sort_keys is true, then the output of dictionaries will be - sorted by key; this is useful for regression tests to ensure - that JSON serializations can be compared on a day-to-day basis. - - If indent is a non-negative integer, then JSON array - elements and object members will be pretty-printed with that - indent level. An indent level of 0 will only insert newlines. - None is the most compact representation. - - If specified, separators should be a (item_separator, key_separator) - tuple. The default is (', ', ': '). To get the most compact JSON - representation you should specify (',', ':') to eliminate whitespace. - - If specified, default is a function that gets called for objects - that can't otherwise be serialized. It should return a JSON encodable - version of the object or raise a ``TypeError``. - - If encoding is not None, then all input strings will be - transformed into unicode using that encoding prior to JSON-encoding. - The default is UTF-8. - - """ - - self.skipkeys = skipkeys - self.ensure_ascii = ensure_ascii - self.check_circular = check_circular - self.allow_nan = allow_nan - self.sort_keys = sort_keys - self.indent = indent - if separators is not None: - self.item_separator, self.key_separator = separators - if default is not None: - self.default = default - self.encoding = encoding - - def default(self, o): - """Implement this method in a subclass such that it returns - a serializable object for ``o``, or calls the base implementation - (to raise a ``TypeError``). - - For example, to support arbitrary iterators, you could - implement default like this:: - - def default(self, o): - try: - iterable = iter(o) - except TypeError: - pass - else: - return list(iterable) - return JSONEncoder.default(self, o) - - """ - raise TypeError(repr(o) + " is not JSON serializable") - - def encode(self, o): - """Return a JSON string representation of a Python data structure. - - >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) - '{"foo": ["bar", "baz"]}' - - """ - # This is for extremely simple cases and benchmarks. - if isinstance(o, basestring): - if isinstance(o, str): - _encoding = self.encoding - if (_encoding is not None - and not (_encoding == 'utf-8')): - o = o.decode(_encoding) - if self.ensure_ascii: - return encode_basestring_ascii(o) - else: - return encode_basestring(o) - # This doesn't pass the iterator directly to ''.join() because the - # exceptions aren't as detailed. The list call should be roughly - # equivalent to the PySequence_Fast that ''.join() would do. - chunks = self.iterencode(o, _one_shot=True) - if not isinstance(chunks, (list, tuple)): - chunks = list(chunks) - return ''.join(chunks) - - def iterencode(self, o, _one_shot=False): - """Encode the given object and yield each string - representation as available. - - For example:: - - for chunk in JSONEncoder().iterencode(bigobject): - mysocket.write(chunk) - - """ - if self.check_circular: - markers = {} - else: - markers = None - if self.ensure_ascii: - _encoder = encode_basestring_ascii - else: - _encoder = encode_basestring - if self.encoding != 'utf-8': - def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding): - if isinstance(o, str): - o = o.decode(_encoding) - return _orig_encoder(o) - - def floatstr(o, allow_nan=self.allow_nan, _repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY): - # Check for specials. Note that this type of test is processor- and/or - # platform-specific, so do tests which don't depend on the internals. - - if o != o: - text = 'NaN' - elif o == _inf: - text = 'Infinity' - elif o == _neginf: - text = '-Infinity' - else: - return _repr(o) - - if not allow_nan: - raise ValueError( - "Out of range float values are not JSON compliant: " + - repr(o)) - - return text - - - if _one_shot and c_make_encoder is not None and not self.indent and not self.sort_keys: - _iterencode = c_make_encoder( - markers, self.default, _encoder, self.indent, - self.key_separator, self.item_separator, self.sort_keys, - self.skipkeys, self.allow_nan) - else: - _iterencode = _make_iterencode( - markers, self.default, _encoder, self.indent, floatstr, - self.key_separator, self.item_separator, self.sort_keys, - self.skipkeys, _one_shot) - return _iterencode(o, 0) - -def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot, - ## HACK: hand-optimized bytecode; turn globals into locals - False=False, - True=True, - ValueError=ValueError, - basestring=basestring, - dict=dict, - float=float, - id=id, - int=int, - isinstance=isinstance, - list=list, - long=long, - str=str, - tuple=tuple, - ): - - def _iterencode_list(lst, _current_indent_level): - if not lst: - yield '[]' - return - if markers is not None: - markerid = id(lst) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = lst - buf = '[' - if _indent is not None: - _current_indent_level += 1 - newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) - separator = _item_separator + newline_indent - buf += newline_indent - else: - newline_indent = None - separator = _item_separator - first = True - for value in lst: - if first: - first = False - else: - buf = separator - if isinstance(value, basestring): - yield buf + _encoder(value) - elif value is None: - yield buf + 'null' - elif value is True: - yield buf + 'true' - elif value is False: - yield buf + 'false' - elif isinstance(value, (int, long)): - yield buf + str(value) - elif isinstance(value, float): - yield buf + _floatstr(value) - else: - yield buf - if isinstance(value, (list, tuple)): - chunks = _iterencode_list(value, _current_indent_level) - elif isinstance(value, dict): - chunks = _iterencode_dict(value, _current_indent_level) - else: - chunks = _iterencode(value, _current_indent_level) - for chunk in chunks: - yield chunk - if newline_indent is not None: - _current_indent_level -= 1 - yield '\n' + (' ' * (_indent * _current_indent_level)) - yield ']' - if markers is not None: - del markers[markerid] - - def _iterencode_dict(dct, _current_indent_level): - if not dct: - yield '{}' - return - if markers is not None: - markerid = id(dct) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = dct - yield '{' - if _indent is not None: - _current_indent_level += 1 - newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) - item_separator = _item_separator + newline_indent - yield newline_indent - else: - newline_indent = None - item_separator = _item_separator - first = True - if _sort_keys: - items = dct.items() - items.sort(key=lambda kv: kv[0]) - else: - items = dct.iteritems() - for key, value in items: - if isinstance(key, basestring): - pass - # JavaScript is weakly typed for these, so it makes sense to - # also allow them. Many encoders seem to do something like this. - elif isinstance(key, float): - key = _floatstr(key) - elif key is True: - key = 'true' - elif key is False: - key = 'false' - elif key is None: - key = 'null' - elif isinstance(key, (int, long)): - key = str(key) - elif _skipkeys: - continue - else: - raise TypeError("key " + repr(key) + " is not a string") - if first: - first = False - else: - yield item_separator - yield _encoder(key) - yield _key_separator - if isinstance(value, basestring): - yield _encoder(value) - elif value is None: - yield 'null' - elif value is True: - yield 'true' - elif value is False: - yield 'false' - elif isinstance(value, (int, long)): - yield str(value) - elif isinstance(value, float): - yield _floatstr(value) - else: - if isinstance(value, (list, tuple)): - chunks = _iterencode_list(value, _current_indent_level) - elif isinstance(value, dict): - chunks = _iterencode_dict(value, _current_indent_level) - else: - chunks = _iterencode(value, _current_indent_level) - for chunk in chunks: - yield chunk - if newline_indent is not None: - _current_indent_level -= 1 - yield '\n' + (' ' * (_indent * _current_indent_level)) - yield '}' - if markers is not None: - del markers[markerid] - - def _iterencode(o, _current_indent_level): - if isinstance(o, basestring): - yield _encoder(o) - elif o is None: - yield 'null' - elif o is True: - yield 'true' - elif o is False: - yield 'false' - elif isinstance(o, (int, long)): - yield str(o) - elif isinstance(o, float): - yield _floatstr(o) - elif isinstance(o, (list, tuple)): - for chunk in _iterencode_list(o, _current_indent_level): - yield chunk - elif isinstance(o, dict): - for chunk in _iterencode_dict(o, _current_indent_level): - yield chunk - else: - if markers is not None: - markerid = id(o) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = o - o = _default(o) - for chunk in _iterencode(o, _current_indent_level): - yield chunk - if markers is not None: - del markers[markerid] - - return _iterencode diff --git a/test/simplejson/scanner.py b/test/simplejson/scanner.py deleted file mode 100644 index adbc6ec979..0000000000 --- a/test/simplejson/scanner.py +++ /dev/null @@ -1,65 +0,0 @@ -"""JSON token scanner -""" -import re -try: - from simplejson._speedups import make_scanner as c_make_scanner -except ImportError: - c_make_scanner = None - -__all__ = ['make_scanner'] - -NUMBER_RE = re.compile( - r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', - (re.VERBOSE | re.MULTILINE | re.DOTALL)) - -def py_make_scanner(context): - parse_object = context.parse_object - parse_array = context.parse_array - parse_string = context.parse_string - match_number = NUMBER_RE.match - encoding = context.encoding - strict = context.strict - parse_float = context.parse_float - parse_int = context.parse_int - parse_constant = context.parse_constant - object_hook = context.object_hook - - def _scan_once(string, idx): - try: - nextchar = string[idx] - except IndexError: - raise StopIteration - - if nextchar == '"': - return parse_string(string, idx + 1, encoding, strict) - elif nextchar == '{': - return parse_object((string, idx + 1), encoding, strict, _scan_once, object_hook) - elif nextchar == '[': - return parse_array((string, idx + 1), _scan_once) - elif nextchar == 'n' and string[idx:idx + 4] == 'null': - return None, idx + 4 - elif nextchar == 't' and string[idx:idx + 4] == 'true': - return True, idx + 4 - elif nextchar == 'f' and string[idx:idx + 5] == 'false': - return False, idx + 5 - - m = match_number(string, idx) - if m is not None: - integer, frac, exp = m.groups() - if frac or exp: - res = parse_float(integer + (frac or '') + (exp or '')) - else: - res = parse_int(integer) - return res, m.end() - elif nextchar == 'N' and string[idx:idx + 3] == 'NaN': - return parse_constant('NaN'), idx + 3 - elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity': - return parse_constant('Infinity'), idx + 8 - elif nextchar == '-' and string[idx:idx + 9] == '-Infinity': - return parse_constant('-Infinity'), idx + 9 - else: - raise StopIteration - - return _scan_once - -make_scanner = c_make_scanner or py_make_scanner diff --git a/test/simplejson/tool.py b/test/simplejson/tool.py deleted file mode 100644 index 90443317b2..0000000000 --- a/test/simplejson/tool.py +++ /dev/null @@ -1,37 +0,0 @@ -r"""Command-line tool to validate and pretty-print JSON - -Usage:: - - $ echo '{"json":"obj"}' | python -m simplejson.tool - { - "json": "obj" - } - $ echo '{ 1.2:3.4}' | python -m simplejson.tool - Expecting property name: line 1 column 2 (char 2) - -""" -import sys -import simplejson - -def main(): - if len(sys.argv) == 1: - infile = sys.stdin - outfile = sys.stdout - elif len(sys.argv) == 2: - infile = open(sys.argv[1], 'rb') - outfile = sys.stdout - elif len(sys.argv) == 3: - infile = open(sys.argv[1], 'rb') - outfile = open(sys.argv[2], 'wb') - else: - raise SystemExit(sys.argv[0] + " [infile [outfile]]") - try: - obj = simplejson.load(infile) - except ValueError, e: - raise SystemExit(e) - simplejson.dump(obj, outfile, sort_keys=True, indent=4) - outfile.write('\n') - - -if __name__ == '__main__': - main() diff --git a/tools/partest-ack b/tools/partest-ack deleted file mode 100755 index ab722e3b1c..0000000000 --- a/tools/partest-ack +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash -# -# wrapper around partest for fine-grained test selection via ack - -declare quiet failed update partest_debug -declare cotouched since sortCommand -declare -a ack_args partest_args scalac_args -declare -r standard_ack_args="--noenv -s --java --scala --type-add=scala:ext:flags,check --files-with-matches" - -partest_args=( --show-diff ) -bindir="$(cd "$(dirname "$0")" && pwd)" -base="$bindir/.." -cd "$base" || { echo "Could not change to base directory $base" && exit 1; } -filesdir="test/files" -sortCommand="sort -u" -partestPaths="$bindir/partest-paths" - -[[ -x "$partestPaths" ]] || { echo "Cannot find partest-paths in $partestPaths" && exit 1; } - -[[ $# -gt 0 ]] || { - cat <<EOM -Usage: $0 <regex> [-dfquvp] [ack options] - - -f pass --failed to partest - -q pass --terse to partest - -u pass --update-check to partest - -p <path> select tests appearing in commits where <path> was also modified - -s <time> select tests touched since <time> (git format, e.g. 1.month.ago) - -r run tests in random order - -Given a regular expression (and optionally, any arguments accepted by ack) -runs all the tests for which any associated file matches the regex. Associated -files include .check and .flags files. Tests in directories will match if any -file matches. A file can match the regex by its contents or by its name. - -You must have ack version 2.12+ installed: http://beyondgrep.com/ack-2.12-single-file - -Examples: - - > tools/partest-ack 'case (class|object) Baz' - % testsWithMatchingPaths ... 0 - % testsWithMatchingCode ... 3 - # 3 tests to run. - - > tools/partest-ack -s 12.hours.ago - % testsTouchedSinceGitTime ... 33 - # 33 tests to run. - - > tools/partest-ack -p src/library/scala/Enumeration.scala - % testsModifiedInSameCommit ... 80 - # 80 tests to run. - - > tools/partest-ack -f - % tests-which-failed ... 42 - # 42 tests to run. - - > tools/partest-ack "kinds of the type arguments" - % testsWithMatchingPaths ... 0 - % testsWithMatchingCode ... 6 - # 6 tests to run. -EOM - - exit 0 -} - -while getopts :fuvdrp:s: opt; do - case $opt in - f) failed=true && partest_args+=" --failed" ;; - p) cotouched="$cotouched $OPTARG" ;; - r) sortCommand="randomSort" ;; - s) since="$OPTARG" ;; - q) partest_args+=" --terse" ;; - u) partest_args+=" --update-check" ;; - v) partest_args+=" --verbose" ;; - :) echo "Option -$OPTARG requires an argument." >&2 ;; - *) ack_args+="-$OPTARG" ;; # don't drop unknown args, assume they're for ack - esac -done - -shift $((OPTIND-1)) -ack_args=( "${ack_args[@]}" "$@" ) - -# These methods all just create paths which may or may not be tests -# all are filtered through partest-paths which limits the output to actual tests -regexPathTests () { find "$filesdir" | ack --noenv "$@"; } -failedTests () { for p in $(find "$filesdir" -name '*.log'); do p1=${p%.log} && p2=${p1%-*} && echo "$p2"; done; } -sinceTests() { git log --since="$@" --name-only --pretty="format:" -- "$filesdir"; } -regexCodeTests () { ack $standard_ack_args "$@" -- "$filesdir"; } -sameCommitTests() { for rev in $(git rev-list HEAD -- "$@"); do git --no-pager show --pretty="format:" --name-only "$rev" -- "$filesdir"; done; } - -countStdout () { - local -i count=0 - while read line; do - printf "$line\n" && count+=1 - done - - printf >&2 " $count\n" -} - -randomSort () { - sort -u | while read line; do echo "$RANDOM $line"; done | sort | sed -E 's/^[0-9]+ //' -} - -testRun () { - local description="$1" && shift - printf >&2 "%% tests %-25s ... " "$description" - "$@" | "$partestPaths" | countStdout | egrep -v '^[ ]*$' -} - -allMatches() { - [[ -n $ack_args ]] && testRun "with matching paths" regexPathTests "${ack_args[@]}" - [[ -n $ack_args ]] && testRun "with matching code" regexCodeTests "${ack_args[@]}" - [[ -n $cotouched ]] && testRun "modified in same commit" sameCommitTests $cotouched - [[ -n $since ]] && testRun "modified since time" sinceTests "$since" - [[ -n $failed ]] && testRun "failed on last run" failedTests -} - -paths=$(allMatches | $sortCommand) - -[[ -z $paths ]] && [[ -z $failed ]] && echo >&2 "No matching tests." && exit 0; - -count=$(echo $(echo "$paths" | wc -w)) -[[ "$count" -eq 0 ]] && echo >&2 "No tests to run." && exit 0; - -# Output a command line which will re-run these same tests. -echo "# $count tests to run." -printf "%-52s %s\n" "$base/test/partest ${partest_args[*]}" "\\" -for path in $paths; do printf " %-50s %s\n" "$path" "\\"; done -echo "" - -test/partest ${partest_args[*]} $paths diff --git a/tools/partest-paths b/tools/partest-paths deleted file mode 100755 index 6ce403a04e..0000000000 --- a/tools/partest-paths +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -# -# Given a list of files on stdin, translates them into a set -# of tests covering those files. That means paths which aren't -# part of a test are dropped and the rest are rewritten to the -# primary test path, with duplicates dropped. - -cd "$(dirname "$0")/.." - -# We have to enumerate good test dirs since partest chokes and fails -# on continuations, bench, etc. tests -pathRegex="test/files/(pos|neg|jvm|run|scalap|presentation)/[^/.]+([.]scala)?\$" - -# Echo the argument only if it matches our idea of a test and exists. -isPath () { [[ "$1" =~ $pathRegex ]] && [[ -e "$1" ]]; } - -# Filter stdin down to actual test paths. -asTestPaths() { - while read -r p; do - # Matched file at the standard test depth - p1="${p%.*}" && isPath "$p1.scala" && echo "$p1.scala" && continue - # Or, matched file may be in a test subdirectory, so strip the last path segment and check - p2="${p1%/*}" && isPath "$p2" && echo "$p2" && continue - done -} - -asTestPaths | sort -u |