summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-backward.whitelist.conf219
-rw-r--r--bincompat-forward.whitelist.conf357
-rw-r--r--build.sbt1
-rw-r--r--project/BuildSettings.scala2
-rw-r--r--project/GenerateAnyVals.scala2
-rw-r--r--project/JarJar.scala2
-rw-r--r--project/MiMa.scala2
-rw-r--r--project/Osgi.scala2
-rw-r--r--project/ParserUtil.scala2
-rw-r--r--project/PartestUtil.scala2
-rw-r--r--project/Quiet.scala2
-rw-r--r--project/ScalaOptionParser.scala2
-rw-r--r--project/ScalaTool.scala2
-rw-r--r--project/ScriptCommands.scala2
-rw-r--r--project/VersionUtil.scala2
-rw-r--r--spec/05-classes-and-objects.md10
-rw-r--r--spec/README.md6
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala32
-rw-r--r--src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala86
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala12
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala38
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala30
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala47
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala5
-rw-r--r--src/compiler/scala/tools/util/PathResolver.scala2
-rw-r--r--src/library/scala/collection/immutable/FilteredTraversableInternal.scala104
-rw-r--r--src/library/scala/collection/immutable/List.scala53
-rw-r--r--src/library/scala/collection/immutable/Queue.scala2
-rw-r--r--src/library/scala/collection/immutable/RedBlackTree.scala5
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala74
-rw-r--r--src/library/scala/collection/mutable/WrappedArray.scala71
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala16
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Names.scala6
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Scopes.scala33
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala2
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala5
-rw-r--r--src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedOps.scala11
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ExprTyper.scala14
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Formatting.scala35
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala7
-rw-r--r--src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala33
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ReplReporter.scala33
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Scripted.scala2
-rw-r--r--test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala72
-rw-r--r--test/files/jvm/interpreter.check8
-rw-r--r--test/files/neg/badtok-1.check8
-rw-r--r--test/files/neg/badtok-1.scala7
-rw-r--r--test/files/neg/t5856.check2
-rw-r--r--test/files/pos/sam_erasure_boundedwild.scala11
-rw-r--r--test/files/pos/t9331.scala6
-rw-r--r--test/files/run/elidable-opt.check2
-rw-r--r--test/files/run/elidable.check2
-rw-r--r--test/files/run/elidable.scala42
-rw-r--r--test/files/run/existentials-in-compiler.check68
-rw-r--r--test/files/run/existentials-in-compiler.scala2
-rw-r--r--test/files/run/literals.scala10
-rw-r--r--test/files/run/reify_newimpl_22.check2
-rw-r--r--test/files/run/reify_newimpl_23.check2
-rw-r--r--test/files/run/reify_newimpl_25.check2
-rw-r--r--test/files/run/reify_newimpl_26.check2
-rw-r--r--test/files/run/repl-colon-type.check16
-rw-r--r--test/files/run/t10026.check1
-rw-r--r--test/files/run/t10026.scala11
-rw-r--r--test/files/run/t1459.check3
-rw-r--r--test/files/run/t1459/InheritingPrinter.scala6
-rw-r--r--test/files/run/t1459/JavaPrinter.java7
-rw-r--r--test/files/run/t1459/ScalaPrinter.scala6
-rw-r--r--test/files/run/t1459/Test.java15
-rw-r--r--test/files/run/t1459/VarArg.java3
-rw-r--r--test/files/run/t1459generic.check4
-rw-r--r--test/files/run/t1459generic/Impl.scala4
-rw-r--r--test/files/run/t1459generic/Test.java10
-rw-r--r--test/files/run/t1459generic/VarargGeneric.java7
-rw-r--r--test/files/run/t8918-unary-ids.check14
-rw-r--r--test/files/run/t9013/Test.java20
-rw-r--r--test/files/run/t9013/test.scala18
-rw-r--r--test/files/run/t9114.scala31
-rw-r--r--test/files/run/t9170.scala4
-rw-r--r--test/files/run/t9880-9881.check36
-rw-r--r--test/files/run/t9880-9881.scala29
-rw-r--r--test/junit/scala/collection/IndexedSeqTest.scala578
-rw-r--r--test/junit/scala/reflect/internal/NamesTest.scala25
-rw-r--r--test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala41
-rw-r--r--test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala2
-rw-r--r--test/scalacheck/duration.scala5
-rw-r--r--versions.properties2
96 files changed, 2232 insertions, 338 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf
index b88fa64584..9ea78a2977 100644
--- a/bincompat-backward.whitelist.conf
+++ b/bincompat-backward.whitelist.conf
@@ -34,6 +34,14 @@ filter {
problemName=DirectMissingMethodProblem
},
{
+ matchName="scala.reflect.runtime.SynchronizedOps.scala$reflect$runtime$SynchronizedOps$$super$newMappedBaseTypeSeq"
+ problemName=ReversedMissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.SynchronizedOps#SynchronizedBaseTypeSeq.lateMap"
+ problemName=DirectMissingMethodProblem
+ },
+ {
matchName="scala.collection.immutable.HashMap.contains0"
problemName=DirectMissingMethodProblem
},
@@ -48,6 +56,217 @@ filter {
{
matchName="scala.collection.immutable.HashMap#HashMapCollision1.contains0"
problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip3"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ // see SI-8200
+ {
+ matchName="scala.reflect.api.StandardLiftables#StandardLiftableInstances.liftTree"
+ problemName=MissingMethodProblem
+ },
+ // see SI-8331
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi#SyntacticTypeAppliedExtractor.unapply"
+ problemName=IncompatibleResultTypeProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi#SyntacticTypeAppliedExtractor.unapply"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSelectType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticAppliedType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSelectTerm"
+ problemName=MissingMethodProblem
+ },
+ // see SI-8366
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticPartialFunction"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Mirror.symbolOf"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Mirror.typeOf"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Mirror.weakTypeOf"
+ problemName=MissingMethodProblem
+ },
+ // see SI-8388
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticIdentExtractor"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSingletonType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTermIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTypeIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticCompoundType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticAnnotatedType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTypeProjection"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticExistentialType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.SynchronizedOps.newNestedScope"
+ problemName=MissingMethodProblem
+ },
+ // https://github.com/scala/scala/pull/3848 -- SI-8680
+ {
+ matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$6"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$5"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$4"
+ problemName=MissingMethodProblem
+ },
+ // SI-8946
+ {
+ matchName="scala.reflect.runtime.ThreadLocalStorage#MyThreadLocalStorage.values"
+ problemName=MissingMethodProblem
+ },
+ // the below method was the unused private (sic!) method but the compatibility checker was complaining about it
+ {
+ matchName="scala.reflect.io.ZipArchive.scala$reflect$io$ZipArchive$$walkIterator"
+ problemName=MissingMethodProblem
+ },
+ // SI-8362: AbstractPromise extends AtomicReference
+ // It's ok to change a package-protected class in an impl package,
+ // even though it's not clear why it changed -- bug in generic signature generation?
+ // -public class scala.concurrent.impl.Promise$DefaultPromise<T> extends scala.concurrent.impl.AbstractPromise implements scala.concurrent.impl.Promise<T>
+ // +public class scala.concurrent.impl.Promise$DefaultPromise<T extends java.lang.Object> extends scala.concurrent.impl.AbstractPromise implements scala.concurrent.impl.Promise<T>
+ {
+ matchName="scala.concurrent.impl.Promise$DefaultPromise"
+ problemName=MissingTypesProblem
+ },
+ // SI-9488: Due to SI-8362 above, toString was silently changed to the AtomicReference toString implementation,
+ // This is fixed by SI-9488, and this should be safe since the class in question is stdlib internal.
+ {
+ matchName="scala.concurrent.impl.Promise.toString"
+ problemName=MissingMethodProblem
+ },
+ // https://github.com/scala/scala/pull/5652
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.slice"
+ problemName=FinalMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.slice"
+ problemName=FinalMethodProblem
}
]
}
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index eee2d6df34..b765fb384b 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -44,6 +44,14 @@ filter {
problemName=DirectMissingMethodProblem
},
{
+ matchName="scala.reflect.runtime.SynchronizedOps.newMappedBaseTypeSeq"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaUniverse.newMappedBaseTypeSeq"
+ problemName=DirectMissingMethodProblem
+ },
+ {
matchName="scala.collection.immutable.HashMap.contains0"
problemName=DirectMissingMethodProblem
},
@@ -60,6 +68,355 @@ filter {
problemName=DirectMissingMethodProblem
},
{
+ matchName="scala.reflect.api.SerializedTypeTag.serialVersionUID"
+ problemName=MissingFieldProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofChar"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofShort"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofByte.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofByte.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofBoolean.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofBoolean.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofChar.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofChar.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofDouble.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofDouble.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofUnit"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofInt"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofBoolean"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofShort.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofShort.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofRef.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofRef.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofUnit.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofUnit.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOpsImpl"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofInt.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofInt.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofDouble"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofRef"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofLong.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofLong.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofByte"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.sliceImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.emptyImpl$extension"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofByte"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofBoolean"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofChar"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofDouble"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofShort"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofRef"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofUnit"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofInt"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArrayImpl"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofLong"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray$ofFloat"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofFloat.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.WrappedArray#ofFloat.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofLong"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps$ofFloat"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.sliceImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.emptyImpl"
+ problemName=DirectMissingMethodProblem
+ },
+ // introduce FilteredTraversableInternal
+ {
+ matchName="scala.collection.immutable.Nil$"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.immutable.FilteredTraversableInternal"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.collection.immutable.List"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.collection.immutable.$colon$colon"
+ problemName=MissingTypesProblem
+ },
+ {
matchName="scala.annotation.showAsInfix$"
problemName=MissingClassProblem
},
diff --git a/build.sbt b/build.sbt
index 6bb9c10166..6a74107de5 100644
--- a/build.sbt
+++ b/build.sbt
@@ -32,6 +32,7 @@
* - to modularize the Scala compiler or library further
*/
+import scala.build._
import VersionUtil._
// Scala dependencies:
diff --git a/project/BuildSettings.scala b/project/BuildSettings.scala
index 76cd888a2d..8456f91f86 100644
--- a/project/BuildSettings.scala
+++ b/project/BuildSettings.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import sbt._
/** This object defines keys that should be visible with an unqualified name in all .sbt files and the command line */
diff --git a/project/GenerateAnyVals.scala b/project/GenerateAnyVals.scala
index 84454cb0ed..f349bfd16b 100644
--- a/project/GenerateAnyVals.scala
+++ b/project/GenerateAnyVals.scala
@@ -1,3 +1,5 @@
+package scala.build
+
/** Code generation of the AnyVal types and their companions. */
trait GenerateAnyValReps {
self: GenerateAnyVals =>
diff --git a/project/JarJar.scala b/project/JarJar.scala
index 918060c9ee..3cb9e4cfff 100644
--- a/project/JarJar.scala
+++ b/project/JarJar.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import org.pantsbuild.jarjar
import org.pantsbuild.jarjar._
import org.pantsbuild.jarjar.util._
diff --git a/project/MiMa.scala b/project/MiMa.scala
index ceda8f5594..fb9bb175ab 100644
--- a/project/MiMa.scala
+++ b/project/MiMa.scala
@@ -1,3 +1,5 @@
+package scala.build
+
// It would be nice to use sbt-mima-plugin here, but the plugin is missing
// at least two features we need:
// * ability to run MiMa twice, swapping `curr` and `prev`, to detect
diff --git a/project/Osgi.scala b/project/Osgi.scala
index 082fd91ed1..b05751958a 100644
--- a/project/Osgi.scala
+++ b/project/Osgi.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import aQute.bnd.osgi.Builder
import aQute.bnd.osgi.Constants._
import java.util.Properties
diff --git a/project/ParserUtil.scala b/project/ParserUtil.scala
index cdaf8831a5..bbd9129dbe 100644
--- a/project/ParserUtil.scala
+++ b/project/ParserUtil.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import sbt._
import sbt.complete.Parser._
import sbt.complete.Parsers._
diff --git a/project/PartestUtil.scala b/project/PartestUtil.scala
index 23570a88ec..127dcafefa 100644
--- a/project/PartestUtil.scala
+++ b/project/PartestUtil.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import sbt._
import sbt.complete._, Parser._, Parsers._
diff --git a/project/Quiet.scala b/project/Quiet.scala
index 0a186d8f28..8ae08ad5a6 100644
--- a/project/Quiet.scala
+++ b/project/Quiet.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import sbt._
import Keys._
diff --git a/project/ScalaOptionParser.scala b/project/ScalaOptionParser.scala
index 27ed1f0e6f..0208921959 100644
--- a/project/ScalaOptionParser.scala
+++ b/project/ScalaOptionParser.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import ParserUtil._
import sbt._
import sbt.complete.Parser._
diff --git a/project/ScalaTool.scala b/project/ScalaTool.scala
index 98e18235c4..ace547c640 100644
--- a/project/ScalaTool.scala
+++ b/project/ScalaTool.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import sbt._
import org.apache.commons.lang3.SystemUtils
import org.apache.commons.lang3.StringUtils.replaceEach
diff --git a/project/ScriptCommands.scala b/project/ScriptCommands.scala
index 8d5d09943a..f6b700f007 100644
--- a/project/ScriptCommands.scala
+++ b/project/ScriptCommands.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import sbt._
import Keys._
import BuildSettings.autoImport._
diff --git a/project/VersionUtil.scala b/project/VersionUtil.scala
index 7c4909697f..ebc2488345 100644
--- a/project/VersionUtil.scala
+++ b/project/VersionUtil.scala
@@ -1,3 +1,5 @@
+package scala.build
+
import sbt._
import Keys._
import java.util.Properties
diff --git a/spec/05-classes-and-objects.md b/spec/05-classes-and-objects.md
index 6738c7a5b7..5bd520589d 100644
--- a/spec/05-classes-and-objects.md
+++ b/spec/05-classes-and-objects.md
@@ -597,10 +597,12 @@ overridden in subclasses. A `final` class may not be inherited by
a template. `final` is redundant for object definitions. Members
of final classes or objects are implicitly also final, so the
`final` modifier is generally redundant for them, too. Note, however, that
-[constant value definitions](04-basic-declarations-and-definitions.html#value-declarations-and-definitions) do require
-an explicit `final` modifier, even if they are defined in a final class or
-object. `final` may not be applied to incomplete members, and it may not be
-combined in one modifier list with `sealed`.
+[constant value definitions](04-basic-declarations-and-definitions.html#value-declarations-and-definitions)
+do require an explicit `final` modifier,
+even if they are defined in a final class or object.
+`final` is permitted for abstract classes
+but it may not be applied to traits or incomplete members,
+and it may not be combined in one modifier list with `sealed`.
### `sealed`
The `sealed` modifier applies to class definitions. A
diff --git a/spec/README.md b/spec/README.md
index b19ce6441f..ad524dfdf3 100644
--- a/spec/README.md
+++ b/spec/README.md
@@ -8,7 +8,11 @@ Third, we'd like to support different output formats. An html page per chapter w
## Editing
-We use Jekyll 2 and [Redcarpet](https://github.com/vmg/redcarpet) to generate the html. Essentially, this is what github pages use.
+At the time of writing we are using Jekyll 3.3.0 and [Redcarpet 3.3.2](https://github.com/vmg/redcarpet) to generate the html.
+
+Check `Gemfile` for the current versions.
+
+We aim to track the configuration GitHub Pages use but at times differences will arise as GitHub Pages evolves.
## Building
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 226c49ec07..d72002f0a7 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -543,24 +543,36 @@ trait Scanners extends ScannersCommon {
}
fetchDoubleQuote()
case '\'' =>
+ def unclosedCharLit() = {
+ val msg = "unclosed character literal"
+ // previous token was Symbol contiguous with the orphan single quote at offset
+ if (token == SYMBOLLIT && offset == lastOffset) {
+ syntaxError(s"""$msg (or use " for string literal "$strVal")""")
+ } else {
+ syntaxError(msg)
+ }
+ }
def fetchSingleQuote() = {
nextChar()
if (isIdentifierStart(ch))
charLitOr(getIdentRest)
else if (isOperatorPart(ch) && (ch != '\\'))
charLitOr(getOperatorRest)
+ else if (ch == '\'') {
+ nextChar()
+ val advice = if (ch == '\'') { do nextChar() while (ch == '\''); " (use '\\'' for single quote)" } else ""
+ syntaxError(s"empty character literal${advice}")
+ }
else if (!isAtEnd && (ch != SU && ch != CR && ch != LF || isUnicodeEscape)) {
getLitChar()
- if (ch == '\'') {
+ if (ch != '\'') unclosedCharLit()
+ else {
nextChar()
token = CHARLIT
setStrVal()
- } else {
- syntaxError("unclosed character literal")
}
}
- else
- syntaxError("unclosed character literal")
+ else unclosedCharLit()
}
fetchSingleQuote()
case '.' =>
@@ -792,7 +804,7 @@ trait Scanners extends ScannersCommon {
next.token = kwArray(idx)
}
} else {
- syntaxError("invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected")
+ syntaxError(s"invalid string interpolation $$$ch, expected: $$$$, $$identifier or $${expression}")
}
} else {
val isUnclosedLiteral = !isUnicodeEscape && (ch == SU || (!multiLine && (ch == CR || ch == LF)))
@@ -983,6 +995,8 @@ trait Scanners extends ScannersCommon {
def intVal: Long = intVal(negated = false)
+ private val zeroFloat = raw"[0.]+(?:[eE][+-]?[0-9]+)?[fFdD]?".r
+
/** Convert current strVal, base to float value.
*/
def floatVal(negated: Boolean): Float = {
@@ -990,8 +1004,7 @@ trait Scanners extends ScannersCommon {
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)))
+ if (value == 0.0f && !zeroFloat.pattern.matcher(strVal).matches)
syntaxError("floating point number too small")
if (negated) -value else value
} catch {
@@ -1010,8 +1023,7 @@ trait Scanners extends ScannersCommon {
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)))
+ if (value == 0.0d && !zeroFloat.pattern.matcher(strVal).matches)
syntaxError("double precision floating point number too small")
if (negated) -value else value
} catch {
diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
index 1ea152b29c..fbd59eb04a 100644
--- a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
@@ -10,9 +10,10 @@ import java.util.function.IntFunction
import java.util
import java.util.Comparator
-import scala.reflect.io.{AbstractFile, PlainFile}
+import scala.reflect.io.{AbstractFile, PlainFile, PlainNioFile}
import scala.tools.nsc.util.{ClassPath, ClassRepresentation}
import FileUtils._
+import scala.collection.JavaConverters._
/**
* A trait allowing to look for classpath entries in directories. It provides common logic for
@@ -121,51 +122,78 @@ trait JFileDirectoryLookup[FileEntryType <: ClassRepresentation] extends Directo
def asClassPathStrings: Seq[String] = Seq(dir.getPath)
}
-object JImageDirectoryLookup {
- import java.nio.file._, java.net.URI, scala.collection.JavaConverters._
- def apply(): List[ClassPath] = {
+object JrtClassPath {
+ import java.nio.file._, java.net.URI
+ def apply(): Option[ClassPath] = {
try {
val fs = FileSystems.getFileSystem(URI.create("jrt:/"))
- val dir: Path = fs.getPath("/modules")
- val modules = Files.list(dir).iterator().asScala.toList
- modules.map(m => new JImageDirectoryLookup(fs, m.getFileName.toString))
+ Some(new JrtClassPath(fs))
} catch {
case _: ProviderNotFoundException | _: FileSystemNotFoundException =>
- Nil
+ None
}
}
}
-class JImageDirectoryLookup(fs: java.nio.file.FileSystem, module: String) extends DirectoryLookup[ClassFileEntryImpl] with NoSourcePaths {
+
+/**
+ * Implementation `ClassPath` based on the JDK 9 encapsulated runtime modules (JEP-220)
+ *
+ * https://bugs.openjdk.java.net/browse/JDK-8066492 is the most up to date reference
+ * for the structure of the jrt:// filesystem.
+ *
+ * The implementation assumes that no classes exist in the empty package.
+ */
+final class JrtClassPath(fs: java.nio.file.FileSystem) extends ClassPath with NoSourcePaths {
import java.nio.file.Path, java.nio.file._
type F = Path
- val dir: Path = fs.getPath("/modules/" + module)
+ private val dir: Path = fs.getPath("/packages")
- protected def emptyFiles: Array[Path] = Array.empty
- protected def getSubDir(packageDirName: String): Option[Path] = {
- val packageDir = dir.resolve(packageDirName)
- if (Files.exists(packageDir) && Files.isDirectory(packageDir)) Some(packageDir)
- else None
+ // e.g. "java.lang" -> Seq("/modules/java.base")
+ private val packageToModuleBases: Map[String, Seq[Path]] = {
+ val ps = Files.newDirectoryStream(dir).iterator().asScala
+ def lookup(pack: Path): Seq[Path] = {
+ Files.list(pack).iterator().asScala.map(l => if (Files.isSymbolicLink(l)) Files.readSymbolicLink(l) else l).toList
+ }
+ ps.map(p => (p.toString.stripPrefix("/packages/"), lookup(p))).toMap
}
- protected def listChildren(dir: Path, filter: Option[Path => Boolean]): Array[Path] = {
- import scala.collection.JavaConverters._
- val f = filter.getOrElse((p: Path) => true)
- Files.list(dir).iterator().asScala.filter(f).toArray[Path]
+
+ override private[nsc] def packages(inPackage: String): Seq[PackageEntry] = {
+ def matches(packageDottedName: String) =
+ if (packageDottedName.contains("."))
+ packageOf(packageDottedName) == inPackage
+ else inPackage == ""
+ packageToModuleBases.keysIterator.filter(matches).map(PackageEntryImpl(_)).toVector
+ }
+ private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = {
+ if (inPackage == "") Nil
+ else {
+ packageToModuleBases.getOrElse(inPackage, Nil).flatMap(x =>
+ Files.list(x.resolve(inPackage.replace('.', '/'))).iterator().asScala.filter(_.getFileName.toString.endsWith(".class"))).map(x =>
+ ClassFileEntryImpl(new PlainNioFile(x))).toVector
+ }
}
- protected def getName(f: Path): String = f.getFileName.toString
- protected def toAbstractFile(f: Path): AbstractFile = new scala.reflect.io.PlainNioFile(f)
- protected def isPackage(f: Path): Boolean = Files.isDirectory(f) && mayBeValidPackage(f.getFileName.toString)
+
+ override private[nsc] def list(inPackage: String): ClassPathEntries =
+ if (inPackage == "") ClassPathEntries(packages(inPackage), Nil)
+ else ClassPathEntries(packages(inPackage), classes(inPackage))
def asURLs: Seq[URL] = Seq(dir.toUri.toURL)
- def asClassPathStrings: Seq[String] = asURLs.map(_.toString)
+ // We don't yet have a scheme to represent the JDK modules in our `-classpath`.
+ // java models them as entries in the new "module path", we'll probably need to follow this.
+ def asClassPathStrings: Seq[String] = Nil
def findClassFile(className: String): Option[AbstractFile] = {
- val relativePath = FileUtils.dirPath(className) + ".class"
- val classFile = dir.resolve(relativePath)
- if (Files.exists(classFile)) Some(new scala.reflect.io.PlainNioFile(classFile)) else None
+ if (!className.contains(".")) None
+ else {
+ val inPackage = packageOf(className)
+ packageToModuleBases.getOrElse(inPackage, Nil).iterator.flatMap{x =>
+ val file = x.resolve(className.replace('.', '/') + ".class")
+ if (Files.exists(file)) new scala.reflect.io.PlainNioFile(file) :: Nil else Nil
+ }.take(1).toList.headOption
+ }
}
- override protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file)
- override protected def isMatchingFile(f: Path): Boolean = Files.isRegularFile(f) && f.getFileName.toString.endsWith(".class")
- override private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = files(inPackage)
+ private def packageOf(dottedClassName: String): String =
+ dottedClassName.substring(0, dottedClassName.lastIndexOf("."))
}
case class DirectoryClassPath(dir: File) extends JFileDirectoryLookup[ClassFileEntryImpl] with NoSourcePaths {
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index 99263bf834..f1f5f37c36 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -14,8 +14,10 @@ import StringOps.{countElementsAsString => countAs, trimAllTrailingSpace => trim
/** This class implements a Reporter that displays messages on a text console.
*/
-class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: PrintWriter) extends AbstractReporter {
- def this(settings: Settings) = this(settings, Console.in, new PrintWriter(Console.err, true))
+class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: PrintWriter, echoWriter: PrintWriter) extends AbstractReporter {
+ def this(settings: Settings) = this(settings, Console.in, new PrintWriter(Console.err, true), new PrintWriter(Console.out, true))
+ def this(settings: Settings, reader: BufferedReader, writer: PrintWriter) =
+ this(settings, reader, writer, writer)
/** Whether a short file name should be displayed before errors */
var shortname: Boolean = false
@@ -41,6 +43,12 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
writer.flush()
}
+ /** Prints the message to the echoWriter, which is usually stdout. */
+ override def echo(msg: String): Unit = {
+ echoWriter.println(trimTrailing(msg))
+ echoWriter.flush()
+ }
+
/** Prints the message with the given position indication. */
def printMessage(posIn: Position, msg: String): Unit = printMessage(formatMessage(posIn, msg, shortname))
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 1a4671e15f..9129478b41 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -663,10 +663,9 @@ abstract class ClassfileParser {
// so have to check unsafeTypeParams.isEmpty before worrying about raw type case below,
// or we'll create a boatload of needless existentials.
else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) tp
- else debuglogResult(s"raw type from $classSym"){
+ else debuglogResult(s"raw type from $classSym") {
// raw type - existentially quantify all type parameters
- val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams)
- newExistentialType(eparams, typeRef(pre, classSym, eparams.map(_.tpeHK)))
+ classExistentialType(pre, classSym)
}
case tp =>
assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp")
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 3ce7db35d8..e327a6658c 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -456,7 +456,15 @@ abstract class Erasure extends InfoTransform
override def newTyper(context: Context) = new Eraser(context)
class ComputeBridges(unit: CompilationUnit, root: Symbol) {
- assert(phase == currentRun.erasurePhase, phase)
+
+ class BridgesCursor(root: Symbol) extends overridingPairs.Cursor(root) {
+ override def parents = List(root.info.firstParent)
+ // Varargs bridges may need generic bridges due to the non-repeated part of the signature of the involved methods.
+ // The vararg bridge is generated during refchecks (probably to simplify override checking),
+ // but then the resulting varargs "bridge" method may itself need an actual erasure bridge.
+ // TODO: like javac, generate just one bridge method that wraps Seq <-> varargs and does erasure-induced casts
+ override def exclude(sym: Symbol) = !sym.isMethod || super.exclude(sym)
+ }
var toBeRemoved = immutable.Set[Symbol]()
val site = root.thisType
@@ -464,12 +472,7 @@ abstract class Erasure extends InfoTransform
val bridgeTarget = mutable.HashMap[Symbol, Symbol]()
var bridges = List[Tree]()
- val opc = enteringExplicitOuter {
- new overridingPairs.Cursor(root) {
- override def parents = List(root.info.firstParent)
- override def exclude(sym: Symbol) = !sym.isMethod || super.exclude(sym)
- }
- }
+ val opc = enteringExplicitOuter { new BridgesCursor(root) }
def compute(): (List[Tree], immutable.Set[Symbol]) = {
while (opc.hasNext) {
@@ -860,6 +863,16 @@ abstract class Erasure extends InfoTransform
}
}
+ private class DoubleDefsCursor(root: Symbol) extends Cursor(root) {
+ // specialized members have no type history before 'specialize', causing double def errors for curried defs
+ override def exclude(sym: Symbol): Boolean = (
+ sym.isType
+ || super.exclude(sym)
+ || !sym.hasTypeAt(currentRun.refchecksPhase.id)
+ )
+ override def matches(lo: Symbol, high: Symbol) = !high.isPrivate
+ }
+
/** Emit an error if there is a double definition. This can happen if:
*
* - A template defines two members with the same name and erased type.
@@ -870,21 +883,12 @@ abstract class Erasure extends InfoTransform
*/
private def checkNoDoubleDefs(root: Symbol) {
checkNoDeclaredDoubleDefs(root)
- object opc extends Cursor(root) {
- // specialized members have no type history before 'specialize', causing double def errors for curried defs
- override def exclude(sym: Symbol): Boolean = (
- sym.isType
- || super.exclude(sym)
- || !sym.hasTypeAt(currentRun.refchecksPhase.id)
- )
- override def matches(lo: Symbol, high: Symbol) = !high.isPrivate
- }
def isErasureDoubleDef(pair: SymbolPair) = {
import pair._
log(s"Considering for erasure clash:\n$pair")
!exitingRefchecks(lowType matches highType) && sameTypeAfterErasure(low, high)
}
- opc.iterator filter isErasureDoubleDef foreach doubleDefError
+ (new DoubleDefsCursor(root)).iterator filter isErasureDoubleDef foreach doubleDefError
}
/** Add bridge definitions to a template. This means:
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index dcffd7a6ab..f35dd6556f 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -342,12 +342,16 @@ abstract class UnCurry extends InfoTransform
* the whole tree with it.
*/
private def replaceElidableTree(tree: Tree): Tree = {
+ def elisionOf(t: Type): Tree = t.typeSymbol match {
+ case StringClass => Literal(Constant("")) setType t
+ case _ => gen.mkZero(t)
+ }
tree match {
case DefDef(_,_,_,_,_,rhs) =>
- val rhs1 = if (rhs == EmptyTree) rhs else Block(Nil, gen.mkZero(rhs.tpe)) setType rhs.tpe
+ val rhs1 = if (rhs == EmptyTree) rhs else Block(Nil, elisionOf(rhs.tpe)) setType rhs.tpe
deriveDefDef(tree)(_ => rhs1) setSymbol tree.symbol setType tree.tpe
case _ =>
- gen.mkZero(tree.tpe) setType tree.tpe
+ elisionOf(tree.tpe)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
index 6fdaa79c10..dc0a457be7 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
@@ -116,8 +116,8 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis {
case _ =>
}
- debug.patmat("sharedPrefix: "+ sharedPrefix)
- debug.patmat("suffix: "+ sharedPrefix)
+ debug.patmat(s"sharedPrefix: $sharedPrefix")
+ debug.patmat(s"suffix: $suffix")
// if the shared prefix contains interesting conditions (!= True)
// and the last of such interesting shared conditions reuses another treemaker's test
// replace the whole sharedPrefix by a ReusingCondTreeMaker
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
index 5750f8f7e7..39971590c7 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
@@ -109,25 +109,29 @@ trait MatchTranslation {
// example check: List[Int] <:< ::[Int]
private def extractorStep(): TranslationStep = {
- def paramType = extractor.aligner.wholeType
import extractor.treeMaker
- // chain a type-testing extractor before the actual extractor call
- // it tests the type, checks the outer pointer and casts to the expected type
- // TODO: the outer check is mandated by the spec for case classes, but we do it for user-defined unapplies as well [SPEC]
- // (the prefix of the argument passed to the unapply must equal the prefix of the type of the binder)
- lazy val typeTest = TypeTestTreeMaker(binder, binder, paramType, paramType)(pos, extractorArgTypeTest = true)
- // check whether typetest implies binder is not null,
- // even though the eventual null check will be on typeTest.nextBinder
- // it'll be equal to binder casted to paramType anyway (and the type test is on binder)
- def extraction: TreeMaker = treeMaker(typeTest.nextBinder, typeTest impliesBinderNonNull binder, pos)
// paramType = the type expected by the unapply
// TODO: paramType may contain unbound type params (run/t2800, run/t3530)
- val makers = (
+ val makers = {
+ val paramType = extractor.aligner.wholeType
// Statically conforms to paramType
if (tpe <:< paramType) treeMaker(binder, false, pos) :: Nil
- else typeTest :: extraction :: Nil
- )
+ else {
+ // chain a type-testing extractor before the actual extractor call
+ // it tests the type, checks the outer pointer and casts to the expected type
+ // TODO: the outer check is mandated by the spec for case classes, but we do it for user-defined unapplies as well [SPEC]
+ // (the prefix of the argument passed to the unapply must equal the prefix of the type of the binder)
+ val typeTest = TypeTestTreeMaker(binder, binder, paramType, paramType)(pos, extractorArgTypeTest = true)
+ val binderKnownNonNull = typeTest impliesBinderNonNull binder
+
+ // check whether typetest implies binder is not null,
+ // even though the eventual null check will be on typeTest.nextBinder
+ // it'll be equal to binder casted to paramType anyway (and the type test is on binder)
+ typeTest :: treeMaker(typeTest.nextBinder, binderKnownNonNull, pos) :: Nil
+ }
+ }
+
step(makers: _*)(extractor.subBoundTrees: _*)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index d349597b14..503f64a44f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -64,9 +64,8 @@ trait Contexts { self: Analyzer =>
for (imps <- allImportInfos.remove(unit)) {
for (imp <- imps.reverse.distinct) {
val used = allUsedSelectors(imp)
- def isMask(s: ImportSelector) = s.name != nme.WILDCARD && s.rename == nme.WILDCARD
- imp.tree.selectors filterNot (s => isMask(s) || used(s)) foreach { sel =>
+ imp.tree.selectors filterNot (s => isMaskImport(s) || used(s)) foreach { sel =>
reporter.warning(imp posOf sel, "Unused import")
}
}
@@ -74,6 +73,10 @@ trait Contexts { self: Analyzer =>
}
}
+ def isMaskImport(s: ImportSelector): Boolean = s.name != nme.WILDCARD && s.rename == nme.WILDCARD
+ def isIndividualImport(s: ImportSelector): Boolean = s.name != nme.WILDCARD && s.rename != nme.WILDCARD
+ def isWildcardImport(s: ImportSelector): Boolean = s.name == nme.WILDCARD
+
var lastAccessCheckDetails: String = ""
/** List of symbols to import from in a root context. Typically that
@@ -1193,27 +1196,33 @@ trait Contexts { self: Analyzer =>
res
}
- final def lookupCompanionOf(original: Symbol): Symbol = {
- if (original.isModuleClass) original.sourceModule
- else lookupScopeEntry(original) match {
- case null => NoSymbol
- case entry => entry.owner.lookupCompanion(original)
+ final def lookupCompanionInIncompleteOwner(original: Symbol): Symbol = {
+ /* Search scopes in current and enclosing contexts for the definition of `symbol` */
+ def lookupScopeEntry(symbol: Symbol): ScopeEntry = {
+ var res: ScopeEntry = null
+ var ctx = this
+ while (res == null && ctx.outer != ctx) {
+ val s = ctx.scope lookupSymbolEntry symbol
+ if (s != null)
+ res = s
+ else
+ ctx = ctx.outer
+ }
+ res
}
- }
- /** Search scopes in current and enclosing contexts for the definition of `symbol` */
- private def lookupScopeEntry(symbol: Symbol): ScopeEntry = {
- var res: ScopeEntry = null
- var ctx = this
- while (res == null && ctx.outer != ctx) {
- val s = ctx.scope lookupSymbolEntry symbol
- if (s != null)
- res = s
- else
- ctx = ctx.outer
+ // 1) Must be owned by the same Scope, to ensure that in
+ // `{ 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.
+ lookupScopeEntry(original) match {
+ case null => NoSymbol
+ case entry =>
+ def isCompanion(sym: Symbol): Boolean =
+ (original.isModule && sym.isClass || sym.isModule && original.isClass) && sym.isCoDefinedWith(original)
+ entry.owner.lookupNameInSameScopeAs(original, original.name.companionName).filter(isCompanion)
}
- res
}
+
} //class Context
/** A `Context` focussed on an `Import` tree */
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 395bda234b..28169c9da1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1955,9 +1955,12 @@ trait Namers extends MethodSynthesis {
// Doing this generally would trigger cycles; that's what we also
// use the lower-level scan through the current Context as a fall back.
if (!currentRun.compiles(owner)) owner.initialize
- original.companionSymbol orElse {
- ctx.lookupCompanionOf(original)
- }
+
+ if (original.isModuleClass) original.sourceModule
+ else if (!owner.isTerm && owner.hasCompleteInfo)
+ original.companionSymbol
+ else
+ ctx.lookupCompanionInIncompleteOwner(original)
}
/** A version of `Symbol#linkedClassOfClass` that works with local companions, ala `companionSymbolOf`. */
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index a787a7bc12..31476e86cd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -189,7 +189,7 @@ abstract class RefChecks extends Transform {
def varargBridge(member: Symbol, bridgetpe: Type): Tree = {
log(s"Generating varargs bridge for ${member.fullLocationString} of type $bridgetpe")
- val newFlags = (member.flags | VBRIDGE | ARTIFACT) & ~PRIVATE
+ val newFlags = (member.flags | VBRIDGE) & ~PRIVATE
val bridge = member.cloneSymbolImpl(clazz, newFlags) setPos clazz.pos
bridge.setInfo(bridgetpe.cloneInfo(bridge))
clazz.info.decls enter bridge
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 6d883aee3d..7943187f35 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -130,8 +130,9 @@ trait SyntheticMethods extends ast.TreeDSL {
*/
def canEqualMethod: Tree = {
syntheticCanEqual = true
- createMethod(nme.canEqual_, List(AnyTpe), BooleanTpe)(m =>
- Ident(m.firstParam) IS_OBJ classExistentialType(clazz))
+ createMethod(nme.canEqual_, List(AnyTpe), BooleanTpe) { m =>
+ Ident(m.firstParam) IS_OBJ classExistentialType(context.prefix, clazz)
+ }
}
/* that match { case _: this.C => true ; case _ => false }
diff --git a/src/compiler/scala/tools/util/PathResolver.scala b/src/compiler/scala/tools/util/PathResolver.scala
index 188cabbc8d..f845656980 100644
--- a/src/compiler/scala/tools/util/PathResolver.scala
+++ b/src/compiler/scala/tools/util/PathResolver.scala
@@ -234,7 +234,7 @@ final class PathResolver(settings: Settings) {
// Assemble the elements!
def basis = List[Traversable[ClassPath]](
- JImageDirectoryLookup.apply(), // 0. The Java 9 classpath (backed by the jrt:/ virtual system)
+ JrtClassPath.apply(), // 0. The Java 9 classpath (backed by the jrt:/ virtual system, if available)
classesInPath(javaBootClassPath), // 1. The Java bootstrap class path.
contentsOfDirsInPath(javaExtDirs), // 2. The Java extension class path.
classesInExpandedPath(javaUserClassPath), // 3. The Java application class path.
diff --git a/src/library/scala/collection/immutable/FilteredTraversableInternal.scala b/src/library/scala/collection/immutable/FilteredTraversableInternal.scala
new file mode 100644
index 0000000000..35585b7826
--- /dev/null
+++ b/src/library/scala/collection/immutable/FilteredTraversableInternal.scala
@@ -0,0 +1,104 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+package collection
+package immutable
+
+import scala.annotation.tailrec
+
+/**
+ * Optimised filter functions for List
+ * n.b. this is an internal class to help maintain compatibility and should not be used directly.
+ */
+private[immutable] trait FilteredTraversableInternal[+A, +Repr <: AnyRef with TraversableLike[A, Repr]] extends TraversableLike[A, Repr] {
+
+ // Optimized for List
+
+ override def filter(p: A => Boolean): Self = filterImpl(p, isFlipped = false)
+
+ override def filterNot(p: A => Boolean): Self = filterImpl(p, isFlipped = true)
+
+ private[this] def filterImpl(p: A => Boolean, isFlipped: Boolean): Self = {
+
+ // everything seen so far so far is not included
+ @tailrec def noneIn(l: Repr): Repr = {
+ if (l.isEmpty)
+ Nil.asInstanceOf[Repr]
+ else {
+ val h = l.head
+ val t = l.tail
+ if (p(h) != isFlipped)
+ allIn(l, t)
+ else
+ noneIn(t)
+ }
+ }
+
+ // everything from 'start' is included, if everything from this point is in we can return the origin
+ // start otherwise if we discover an element that is out we must create a new partial list.
+ @tailrec def allIn(start: Repr, remaining: Repr): Repr = {
+ if (remaining.isEmpty)
+ start
+ else {
+ val x = remaining.head
+ if (p(x) != isFlipped)
+ allIn(start, remaining.tail)
+ else
+ partialFill(start, remaining)
+ }
+ }
+
+ // we have seen elements that should be included then one that should be excluded, start building
+ def partialFill(origStart: Repr, firstMiss: Repr): Repr = {
+ val newHead = new ::(origStart.head, Nil)
+ var toProcess = origStart.tail
+ var currentLast = newHead
+
+ // we know that all elements are :: until at least firstMiss.tail
+ while (!(toProcess eq firstMiss)) {
+ val newElem = new ::(toProcess.head, Nil)
+ currentLast.tl = newElem
+ currentLast = newElem
+ toProcess = toProcess.tail
+ }
+
+ // at this point newHead points to a list which is a duplicate of all the 'in' elements up to the first miss.
+ // currentLast is the last element in that list.
+
+ // now we are going to try and share as much of the tail as we can, only moving elements across when we have to.
+ var next = firstMiss.tail
+ var nextToCopy = next // the next element we would need to copy to our list if we cant share.
+ while (!next.isEmpty) {
+ // generally recommended is next.isNonEmpty but this incurs an extra method call.
+ val head: A = next.head
+ if (p(head) != isFlipped) {
+ next = next.tail
+ } else {
+ // its not a match - do we have outstanding elements?
+ while (!(nextToCopy eq next)) {
+ val newElem = new ::(nextToCopy.head, Nil)
+ currentLast.tl = newElem
+ currentLast = newElem
+ nextToCopy = nextToCopy.tail
+ }
+ nextToCopy = next.tail
+ next = next.tail
+ }
+ }
+
+ // we have remaining elements - they are unchanged attach them to the end
+ if (!nextToCopy.isEmpty)
+ currentLast.tl = nextToCopy.asInstanceOf[List[A]]
+
+ newHead.asInstanceOf[Repr]
+ }
+
+ noneIn(repr)
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index e5444533a8..e12ce7c2eb 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -88,6 +88,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
with Product
with GenericTraversableTemplate[A, List]
with LinearSeqOptimized[A, List[A]]
+ with FilteredTraversableInternal[A, List[A]]
with scala.Serializable {
override def companion: GenericCompanion[List] = List
@@ -163,30 +164,41 @@ sealed abstract class List[+A] extends AbstractSeq[A]
// Note to developers: there exists a duplication between this function and `reflect.internal.util.Collections#map2Conserve`.
// If any successful optimization attempts or other changes are made, please rehash them there too.
@tailrec
- def loop(mapped: ListBuffer[B], unchanged: List[A], pending: List[A]): List[B] =
- if (pending.isEmpty) {
- if (mapped eq null) unchanged
- else mapped.prependToList(unchanged)
+ def loop(mappedHead: List[B] = Nil, mappedLast: ::[B], unchanged: List[A], pending: List[A]): List[B] =
+ if (pending.isEmpty) {
+ if (mappedHead eq null) unchanged
+ else {
+ mappedLast.tl = unchanged
+ mappedHead
}
+ }
+ else {
+ val head0 = pending.head
+ val head1 = f(head0)
+
+ if (head1 eq head0.asInstanceOf[AnyRef])
+ loop(mappedHead, mappedLast, unchanged, pending.tail)
else {
- val head0 = pending.head
- val head1 = f(head0)
-
- if (head1 eq head0.asInstanceOf[AnyRef])
- loop(mapped, unchanged, pending.tail)
- else {
- val b = if (mapped eq null) new ListBuffer[B] else mapped
- var xc = unchanged
- while (xc ne pending) {
- b += xc.head
- xc = xc.tail
- }
- b += head1
- val tail0 = pending.tail
- loop(b, tail0, tail0)
+ var xc = unchanged
+ var mappedHead1: List[B] = mappedHead
+ var mappedLast1: ::[B] = mappedLast
+ while (xc ne pending) {
+ val next = new ::[B](xc.head, Nil)
+ if (mappedHead1 eq null) mappedHead1 = next
+ if (mappedLast1 ne null) mappedLast1.tl = next
+ mappedLast1 = next
+ xc = xc.tail
}
+ val next = new ::(head1, Nil)
+ if (mappedHead1 eq null) mappedHead1 = next
+ if (mappedLast1 ne null) mappedLast1.tl = next
+ mappedLast1 = next
+ val tail0 = pending.tail
+ loop(mappedHead1, mappedLast1, tail0, tail0)
+
}
- loop(null, this, this)
+ }
+ loop(null, null, this, this)
}
// Overridden methods from IterableLike and SeqLike or overloaded variants of such methods
@@ -402,6 +414,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
// Create a proxy for Java serialization that allows us to avoid mutation
// during deserialization. This is the Serialization Proxy Pattern.
protected final def writeReplace(): AnyRef = new List.SerializationProxy(this)
+
}
/** The empty list.
diff --git a/src/library/scala/collection/immutable/Queue.scala b/src/library/scala/collection/immutable/Queue.scala
index 240b5c899e..5081b39bdc 100644
--- a/src/library/scala/collection/immutable/Queue.scala
+++ b/src/library/scala/collection/immutable/Queue.scala
@@ -125,7 +125,7 @@ sealed class Queue[+A] protected(protected val in: List[A], protected val out: L
/** Returns a new queue with all elements provided by an `Iterable` object
* added at the end of the queue.
*
- * The elements are prepended in the order they are given out by the
+ * The elements are appended in the order they are given out by the
* iterator.
*
* @param iter an iterable object
diff --git a/src/library/scala/collection/immutable/RedBlackTree.scala b/src/library/scala/collection/immutable/RedBlackTree.scala
index afb4c9c552..4f2e9115fe 100644
--- a/src/library/scala/collection/immutable/RedBlackTree.scala
+++ b/src/library/scala/collection/immutable/RedBlackTree.scala
@@ -516,9 +516,10 @@ object RedBlackTree {
*
* According to {@see Integer#numberOfLeadingZeros} ceil(log_2(n)) = (32 - Integer.numberOfLeadingZeros(n - 1))
*
- * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one.
+ * Although we don't store the deepest nodes in the path during iteration,
+ * we potentially do so in `startFrom`.
*/
- val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2 - 1
+ val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2
new Array[Tree[A, B]](maximumHeight)
}
private[this] var index = 0
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 29382134aa..5de3dad256 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -10,6 +10,8 @@ package scala
package collection
package mutable
+import java.util
+
import scala.reflect.ClassTag
import parallel.mutable.ParArray
@@ -180,6 +182,23 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara
def seq = thisCollection
}
+/** to provide binary compat for 2.11 and 2.12 this class contains
+ * functionality that should be migrated to ArrayOps in 2.13
+ *
+ */
+private[mutable] sealed trait ArrayOpsImpl[T] extends Any with ArrayOps[T] {
+ override final def slice(from: Int, until: Int): Array[T] = {
+ val start = if (from < 0) 0 else from
+ if (until <= start || start >= repr.length)
+ return emptyImpl
+ val end = if (until > length) length else until
+ sliceImpl(start, end)
+ }
+ protected def emptyImpl: Array[T]
+ protected def sliceImpl(from: Int, until: Int): Array[T]
+
+}
+
/**
* A companion object for `ArrayOps`.
*
@@ -187,12 +206,24 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara
*/
object ArrayOps {
+ private val emptyByteArray = new Array[Byte](0)
+ private val emptyShortArray = new Array[Short](0)
+ private val emptyIntArray = new Array[Int](0)
+ private val emptyLongArray = new Array[Long](0)
+ private val emptyFloatArray = new Array[Float](0)
+ private val emptyDoubleArray = new Array[Double](0)
+ private val emptyUnitArray = new Array[Unit](0)
+ private val emptyCharArray = new Array[Char](0)
+ private val emptyBooleanArray = new Array[Boolean](0)
+
/** A subclass of `ArrayOps` for arrays containing reference types. */
- final class ofRef[T <: AnyRef](override val repr: Array[T]) extends AnyVal with ArrayOps[T] with ArrayLike[T, Array[T]] {
+ final class ofRef[T <: AnyRef](override val repr: Array[T]) extends AnyVal with ArrayOpsImpl[T] with ArrayLike[T, Array[T]] {
override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr)
override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr)
override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](repr.getClass.getComponentType))
+ protected override def emptyImpl:Array[T] = util.Arrays.copyOf[T](repr,0)
+ protected override def sliceImpl(from: Int, until: Int): Array[T] = util.Arrays.copyOfRange[T](repr, from, until)
def length: Int = repr.length
def apply(index: Int): T = repr(index)
@@ -200,11 +231,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Byte`s. */
- final class ofByte(override val repr: Array[Byte]) extends AnyVal with ArrayOps[Byte] with ArrayLike[Byte, Array[Byte]] {
+ final class ofByte(override val repr: Array[Byte]) extends AnyVal with ArrayOpsImpl[Byte] with ArrayLike[Byte, Array[Byte]] {
override protected[this] def thisCollection: WrappedArray[Byte] = new WrappedArray.ofByte(repr)
override protected[this] def toCollection(repr: Array[Byte]): WrappedArray[Byte] = new WrappedArray.ofByte(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofByte
+ protected override def emptyImpl = emptyByteArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Byte = repr(index)
@@ -212,11 +245,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Short`s. */
- final class ofShort(override val repr: Array[Short]) extends AnyVal with ArrayOps[Short] with ArrayLike[Short, Array[Short]] {
+ final class ofShort(override val repr: Array[Short]) extends AnyVal with ArrayOpsImpl[Short] with ArrayLike[Short, Array[Short]] {
override protected[this] def thisCollection: WrappedArray[Short] = new WrappedArray.ofShort(repr)
override protected[this] def toCollection(repr: Array[Short]): WrappedArray[Short] = new WrappedArray.ofShort(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofShort
+ protected override def emptyImpl = emptyShortArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Short = repr(index)
@@ -224,11 +259,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Char`s. */
- final class ofChar(override val repr: Array[Char]) extends AnyVal with ArrayOps[Char] with ArrayLike[Char, Array[Char]] {
+ final class ofChar(override val repr: Array[Char]) extends AnyVal with ArrayOpsImpl[Char] with ArrayLike[Char, Array[Char]] {
override protected[this] def thisCollection: WrappedArray[Char] = new WrappedArray.ofChar(repr)
override protected[this] def toCollection(repr: Array[Char]): WrappedArray[Char] = new WrappedArray.ofChar(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofChar
+ protected override def emptyImpl = emptyCharArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Char = repr(index)
@@ -236,11 +273,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Int`s. */
- final class ofInt(override val repr: Array[Int]) extends AnyVal with ArrayOps[Int] with ArrayLike[Int, Array[Int]] {
+ final class ofInt(override val repr: Array[Int]) extends AnyVal with ArrayOpsImpl[Int] with ArrayLike[Int, Array[Int]] {
override protected[this] def thisCollection: WrappedArray[Int] = new WrappedArray.ofInt(repr)
override protected[this] def toCollection(repr: Array[Int]): WrappedArray[Int] = new WrappedArray.ofInt(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofInt
+ protected override def emptyImpl = emptyIntArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Int = repr(index)
@@ -248,11 +287,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Long`s. */
- final class ofLong(override val repr: Array[Long]) extends AnyVal with ArrayOps[Long] with ArrayLike[Long, Array[Long]] {
+ final class ofLong(override val repr: Array[Long]) extends AnyVal with ArrayOpsImpl[Long] with ArrayLike[Long, Array[Long]] {
override protected[this] def thisCollection: WrappedArray[Long] = new WrappedArray.ofLong(repr)
override protected[this] def toCollection(repr: Array[Long]): WrappedArray[Long] = new WrappedArray.ofLong(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofLong
+ protected override def emptyImpl = emptyLongArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Long = repr(index)
@@ -260,11 +301,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Float`s. */
- final class ofFloat(override val repr: Array[Float]) extends AnyVal with ArrayOps[Float] with ArrayLike[Float, Array[Float]] {
+ final class ofFloat(override val repr: Array[Float]) extends AnyVal with ArrayOpsImpl[Float] with ArrayLike[Float, Array[Float]] {
override protected[this] def thisCollection: WrappedArray[Float] = new WrappedArray.ofFloat(repr)
override protected[this] def toCollection(repr: Array[Float]): WrappedArray[Float] = new WrappedArray.ofFloat(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofFloat
+ protected override def emptyImpl = emptyFloatArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Float = repr(index)
@@ -272,11 +315,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Double`s. */
- final class ofDouble(override val repr: Array[Double]) extends AnyVal with ArrayOps[Double] with ArrayLike[Double, Array[Double]] {
+ final class ofDouble(override val repr: Array[Double]) extends AnyVal with ArrayOpsImpl[Double] with ArrayLike[Double, Array[Double]] {
override protected[this] def thisCollection: WrappedArray[Double] = new WrappedArray.ofDouble(repr)
override protected[this] def toCollection(repr: Array[Double]): WrappedArray[Double] = new WrappedArray.ofDouble(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofDouble
+ protected override def emptyImpl = emptyDoubleArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Double = repr(index)
@@ -284,11 +329,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Boolean`s. */
- final class ofBoolean(override val repr: Array[Boolean]) extends AnyVal with ArrayOps[Boolean] with ArrayLike[Boolean, Array[Boolean]] {
+ final class ofBoolean(override val repr: Array[Boolean]) extends AnyVal with ArrayOpsImpl[Boolean] with ArrayLike[Boolean, Array[Boolean]] {
override protected[this] def thisCollection: WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr)
override protected[this] def toCollection(repr: Array[Boolean]): WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofBoolean
+ protected override def emptyImpl = emptyBooleanArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Boolean = repr(index)
@@ -296,11 +343,18 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays of `Unit` types. */
- final class ofUnit(override val repr: Array[Unit]) extends AnyVal with ArrayOps[Unit] with ArrayLike[Unit, Array[Unit]] {
+ final class ofUnit(override val repr: Array[Unit]) extends AnyVal with ArrayOpsImpl[Unit] with ArrayLike[Unit, Array[Unit]] {
override protected[this] def thisCollection: WrappedArray[Unit] = new WrappedArray.ofUnit(repr)
override protected[this] def toCollection(repr: Array[Unit]): WrappedArray[Unit] = new WrappedArray.ofUnit(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofUnit
+ protected override def emptyImpl = emptyUnitArray
+ protected override def sliceImpl(from: Int, until: Int) = {
+ // cant use util.Arrays.copyOfRange[Unit](repr, from, until) - Unit is special and doesnt compile
+ val res = new Array[Unit](until-from)
+ System.arraycopy(repr, from, res, 0, res.size)
+ res
+ }
def length: Int = repr.length
def apply(index: Int): Unit = repr(index)
diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala
index 0b5ebe7e9a..d0919c4357 100644
--- a/src/library/scala/collection/mutable/WrappedArray.scala
+++ b/src/library/scala/collection/mutable/WrappedArray.scala
@@ -85,12 +85,26 @@ extends AbstractSeq[T]
*/
override protected[this] def newBuilder: Builder[T, WrappedArray[T]] =
new WrappedArrayBuilder[T](elemTag)
+}
+
+private[mutable] abstract class WrappedArrayImpl[T] extends WrappedArray[T] {
+ override def slice(from: Int, until: Int): WrappedArray[T] = {
+ val start = if (from < 0) 0 else from
+ if (until <= start || start >= repr.length)
+ return emptyImpl
+ val end = if (until > length) length else until
+ sliceImpl(start, end)
+ }
+ protected def emptyImpl: WrappedArray[T]
+
+ protected def sliceImpl(from: Int, until: Int): WrappedArray[T]
}
/** A companion object used to create instances of `WrappedArray`.
*/
object WrappedArray {
+ import java.util
// This is reused for all calls to empty.
private val EmptyWrappedArray = new ofRef[AnyRef](new Array[AnyRef](0))
def empty[T <: AnyRef]: WrappedArray[T] = EmptyWrappedArray.asInstanceOf[WrappedArray[T]]
@@ -124,7 +138,17 @@ object WrappedArray {
def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer
- final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable {
+ private val emptyWrappedByte = new ofByte(new Array[Byte](0))
+ private val emptyWrappedShort = new ofShort(new Array[Short](0))
+ private val emptyWrappedInt = new ofInt(new Array[Int](0))
+ private val emptyWrappedLong = new ofLong(new Array[Long](0))
+ private val emptyWrappedFloat = new ofFloat(new Array[Float](0))
+ private val emptyWrappedDouble = new ofDouble(new Array[Double](0))
+ private val emptyWrappedUnit = new ofUnit(new Array[Unit](0))
+ private val emptyWrappedChar = new ofChar(new Array[Char](0))
+ private val emptyWrappedBoolean = new ofBoolean(new Array[Boolean](0))
+
+ final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArrayImpl[T] with Serializable {
lazy val elemTag = ClassTag[T](array.getClass.getComponentType)
def length: Int = array.length
def apply(index: Int): T = array(index).asInstanceOf[T]
@@ -134,9 +158,11 @@ object WrappedArray {
case that: ofRef[_] => Arrays.equals(array.asInstanceOf[Array[AnyRef]], that.array.asInstanceOf[Array[AnyRef]])
case _ => super.equals(that)
}
+ protected override def emptyImpl = new ofRef(util.Arrays.copyOf[T](array,0))
+ protected override def sliceImpl(from: Int, until: Int) = new ofRef[T](util.Arrays.copyOfRange[T](array, from, until))
}
- final class ofByte(val array: Array[Byte]) extends WrappedArray[Byte] with Serializable {
+ final class ofByte(val array: Array[Byte]) extends WrappedArrayImpl[Byte] with Serializable {
def elemTag = ClassTag.Byte
def length: Int = array.length
def apply(index: Int): Byte = array(index)
@@ -146,9 +172,11 @@ object WrappedArray {
case that: ofByte => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedByte
+ protected override def sliceImpl(from: Int, until: Int) = new ofByte(util.Arrays.copyOfRange(array, from, until))
}
- final class ofShort(val array: Array[Short]) extends WrappedArray[Short] with Serializable {
+ final class ofShort(val array: Array[Short]) extends WrappedArrayImpl[Short] with Serializable {
def elemTag = ClassTag.Short
def length: Int = array.length
def apply(index: Int): Short = array(index)
@@ -158,9 +186,11 @@ object WrappedArray {
case that: ofShort => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedShort
+ protected override def sliceImpl(from: Int, until: Int) = new ofShort(util.Arrays.copyOfRange(array, from, until))
}
- final class ofChar(val array: Array[Char]) extends WrappedArray[Char] with Serializable {
+ final class ofChar(val array: Array[Char]) extends WrappedArrayImpl[Char] with Serializable {
def elemTag = ClassTag.Char
def length: Int = array.length
def apply(index: Int): Char = array(index)
@@ -170,9 +200,11 @@ object WrappedArray {
case that: ofChar => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedChar
+ protected override def sliceImpl(from: Int, until: Int) = new ofChar(util.Arrays.copyOfRange(array, from, until))
}
- final class ofInt(val array: Array[Int]) extends WrappedArray[Int] with Serializable {
+ final class ofInt(val array: Array[Int]) extends WrappedArrayImpl[Int] with Serializable {
def elemTag = ClassTag.Int
def length: Int = array.length
def apply(index: Int): Int = array(index)
@@ -182,9 +214,11 @@ object WrappedArray {
case that: ofInt => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedInt
+ protected override def sliceImpl(from: Int, until: Int) = new ofInt(util.Arrays.copyOfRange(array, from, until))
}
- final class ofLong(val array: Array[Long]) extends WrappedArray[Long] with Serializable {
+ final class ofLong(val array: Array[Long]) extends WrappedArrayImpl[Long] with Serializable {
def elemTag = ClassTag.Long
def length: Int = array.length
def apply(index: Int): Long = array(index)
@@ -194,9 +228,11 @@ object WrappedArray {
case that: ofLong => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedLong
+ protected override def sliceImpl(from: Int, until: Int) = new ofLong(util.Arrays.copyOfRange(array, from, until))
}
- final class ofFloat(val array: Array[Float]) extends WrappedArray[Float] with Serializable {
+ final class ofFloat(val array: Array[Float]) extends WrappedArrayImpl[Float] with Serializable {
def elemTag = ClassTag.Float
def length: Int = array.length
def apply(index: Int): Float = array(index)
@@ -206,9 +242,11 @@ object WrappedArray {
case that: ofFloat => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedFloat
+ protected override def sliceImpl(from: Int, until: Int) = new ofFloat(util.Arrays.copyOfRange(array, from, until))
}
- final class ofDouble(val array: Array[Double]) extends WrappedArray[Double] with Serializable {
+ final class ofDouble(val array: Array[Double]) extends WrappedArrayImpl[Double] with Serializable {
def elemTag = ClassTag.Double
def length: Int = array.length
def apply(index: Int): Double = array(index)
@@ -218,9 +256,11 @@ object WrappedArray {
case that: ofDouble => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedDouble
+ protected override def sliceImpl(from: Int, until: Int) = new ofDouble(util.Arrays.copyOfRange(array, from, until))
}
- final class ofBoolean(val array: Array[Boolean]) extends WrappedArray[Boolean] with Serializable {
+ final class ofBoolean(val array: Array[Boolean]) extends WrappedArrayImpl[Boolean] with Serializable {
def elemTag = ClassTag.Boolean
def length: Int = array.length
def apply(index: Int): Boolean = array(index)
@@ -230,9 +270,11 @@ object WrappedArray {
case that: ofBoolean => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedBoolean
+ protected override def sliceImpl(from: Int, until: Int) = new ofBoolean(util.Arrays.copyOfRange(array, from, until))
}
- final class ofUnit(val array: Array[Unit]) extends WrappedArray[Unit] with Serializable {
+ final class ofUnit(val array: Array[Unit]) extends WrappedArrayImpl[Unit] with Serializable {
def elemTag = ClassTag.Unit
def length: Int = array.length
def apply(index: Int): Unit = array(index)
@@ -242,5 +284,14 @@ object WrappedArray {
case that: ofUnit => array.length == that.array.length
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedUnit
+ protected override def sliceImpl(from: Int, until: Int) = {
+ // cant use
+ // new ofUnit(util.Arrays.copyOfRange[Unit](array, from, until)) - Unit is special and doesnt compile
+ // cant use util.Arrays.copyOfRange[Unit](repr, from, until) - Unit is special and doesnt compile
+ val res = new Array[Unit](until-from)
+ System.arraycopy(repr, from, res, 0, until-from)
+ new ofUnit(res)
+ }
}
}
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index 0ef52213e5..1cdefff2e9 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -33,6 +33,9 @@ trait BaseTypeSeqs {
protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) =
new BaseTypeSeq(parents, elems)
+ protected def newMappedBaseTypeSeq(orig: BaseTypeSeq, f: Type => Type) =
+ new MappedBaseTypeSeq(orig, f)
+
/** Note: constructor is protected to force everyone to use the factory method newBaseTypeSeq instead.
* This is necessary because when run from reflection every base type sequence needs to have a
* SynchronizedBaseTypeSeq as mixin.
@@ -125,7 +128,7 @@ trait BaseTypeSeqs {
newBaseTypeSeq(parents, arr)
}
- def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f)
+ def lateMap(f: Type => Type): BaseTypeSeq = newMappedBaseTypeSeq(this, f)
def exists(p: Type => Boolean): Boolean = elems exists p
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 78a75c63d6..315af267bc 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -667,8 +667,8 @@ trait Definitions extends api.StandardDefinitions {
isBundle && isBlackbox
}
- def isListType(tp: Type) = tp <:< classExistentialType(ListClass)
- def isIterableType(tp: Type) = tp <:< classExistentialType(IterableClass)
+ def isListType(tp: Type) = tp.typeSymbol.isNonBottomSubClass(ListClass)
+ def isIterableType(tp: Type) = tp.typeSymbol.isNonBottomSubClass(IterableClass)
// These "direct" calls perform no dealiasing. They are most needed when
// printing types when one wants to preserve the true nature of the type.
@@ -980,14 +980,10 @@ trait Definitions extends api.StandardDefinitions {
*
* C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... En >: LBn <: UBn }.
*/
- // TODO Review the way this is used. I see two potential problems:
- // 1. `existentialAbstraction` here doesn't create fresh existential type symbols, it just
- // uses the class type parameter symbols directly as the list of quantified symbols.
- // See SI-8244 for the trouble that this can cause.
- // Compare with callers of `typeParamsToExistentials` (used in Java raw type handling)
- // 2. Why don't we require a prefix? Could its omission lead to wrong results in CheckabilityChecker?
- def classExistentialType(clazz: Symbol): Type =
- existentialAbstraction(clazz.typeParams, clazz.tpe_*)
+ def classExistentialType(prefix: Type, clazz: Symbol): Type = {
+ val eparams = typeParamsToExistentials(clazz, clazz.unsafeTypeParams)
+ newExistentialType(eparams, typeRef(prefix, clazz, eparams.map(_.tpeHK)))
+ }
// members of class scala.Any
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index 8aa6b16e06..d5bf8b7cef 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -163,7 +163,7 @@ class Flags extends ModifierFlags {
final val LOCKED = 1L << 39 // temporary flag to catch cyclic dependencies
final val SPECIALIZED = 1L << 40 // symbol is a generated specialized member
- final val VBRIDGE = 1L << 42 // symbol is a varargs bridge
+ final val VBRIDGE = 1L << 42 // symbol is a varargs bridge (but not a bridge at the bytecode level)
final val VARARGS = 1L << 43 // symbol is a Java-style varargs method
final val TRIEDCOOKING = 1L << 44 // `Cooking` has been tried on this symbol
diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala
index 9d39ef8b42..055f7c9d5b 100644
--- a/src/reflect/scala/reflect/internal/Names.scala
+++ b/src/reflect/scala/reflect/internal/Names.scala
@@ -296,11 +296,13 @@ trait Names extends api.Names {
*/
final def pos(s: String, start: Int): Int = {
var i = pos(s.charAt(0), start)
- while (i + s.length() <= len) {
+ val sLen = s.length()
+ if (sLen == 1) return i
+ while (i + sLen <= len) {
var j = 1
while (s.charAt(j) == chrs(index + i + j)) {
j += 1
- if (j == s.length()) return i
+ if (j == sLen) return i
}
i = pos(s.charAt(0), i + 1)
}
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index 1b2be64654..21320149a3 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -351,9 +351,13 @@ trait ReificationSupport { self: SymbolTable =>
List[Tree], List[Tree], ValDef, List[Tree])] = tree match {
case ClassDef(mods, name, tparams, impl) =>
val X = if (mods.isCase) UnMkTemplate.asCase else UnMkTemplate
- val X(parents, selfType, ctorMods, vparamss, earlyDefs, body) = impl
- if (ctorMods.isTrait || ctorMods.hasFlag(JAVA)) None
- else Some((mods, name, tparams, ctorMods, vparamss, earlyDefs, parents, selfType, body))
+ impl match {
+ case X(parents, selfType, ctorMods, vparamss, earlyDefs, body)
+ if (!ctorMods.isTrait && !ctorMods.hasFlag(JAVA)) =>
+ Some((mods, name, tparams, ctorMods, vparamss, earlyDefs, parents, selfType, body))
+ case _ =>
+ None
+ }
case _ =>
None
}
diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala
index 51fb31d36d..0435a2c1cf 100644
--- a/src/reflect/scala/reflect/internal/Scopes.scala
+++ b/src/reflect/scala/reflect/internal/Scopes.scala
@@ -291,25 +291,6 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
null
}
- final def lookupCompanion(original: Symbol): Symbol = {
- lookupSymbolEntry(original) match {
- case null =>
- case entry =>
- 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 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))) {
- return if (e.sym.isCoDefinedWith(original)) e.sym else NoSymbol
- }
- e = lookupNextEntry(e)
- }
- }
- NoSymbol
- }
-
/** lookup a symbol entry matching given name.
* @note from Martin: I believe this is a hotspot or will be one
* in future versions of the type system. I have reverted the previous
@@ -345,6 +326,20 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
e
}
+ final def lookupNameInSameScopeAs(original: Symbol, companionName: Name): Symbol = {
+ lookupSymbolEntry(original) match {
+ case null =>
+ case entry =>
+ var e = lookupEntry(companionName)
+ while (e != null) {
+ if (e.owner eq entry.owner) return e.sym
+ e = lookupNextEntry(e)
+ }
+ }
+ NoSymbol
+ }
+
+
/** TODO - we can test this more efficiently than checking isSubScope
* in both directions. However the size test might be enough to quickly
* rule out most failures.
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 2a0fb5298b..b46f071717 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -3974,7 +3974,7 @@ trait Types
* any corresponding non-variant type arguments of bt1 and bt2 are the same
*/
def isPopulated(tp1: Type, tp2: Type): Boolean = {
- def isConsistent(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match {
+ def isConsistent(tp1: Type, tp2: Type): Boolean = (tp1.dealias, tp2.dealias) match {
case (TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) =>
assert(sym1 == sym2, (sym1, sym2))
( pre1 =:= pre2
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index 24f8aa88e6..07ae71538c 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -161,6 +161,11 @@ trait Erasure {
}
if (newParents eq parents) tp
else ClassInfoType(newParents, decls, clazz)
+
+ // can happen while this map is being used before erasure (e.g. when reasoning about sam types)
+ // the regular mapOver will cause a class cast exception because TypeBounds don't erase to TypeBounds
+ case _: BoundedWildcardType => tp // skip
+
case _ =>
mapOver(tp)
}
diff --git a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
index 3cede1b3c5..49ab0cb30e 100644
--- a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
+++ b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
@@ -92,7 +92,7 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader)
}
}
- private val packages = mutable.Map[String, Package]()
+ private[this] val packages = mutable.Map[String, Package]()
override def definePackage(name: String, specTitle: String, specVersion: String, specVendor: String, implTitle: String, implVersion: String, implVendor: String, sealBase: URL): Package = {
throw new UnsupportedOperationException()
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 9138ed3f02..72e21f67fe 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -459,8 +459,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.DoubleTpe
definitions.BooleanTpe
definitions.ScalaNumericValueClasses
- definitions.ScalaValueClassesNoUnit
definitions.ScalaValueClasses
+ definitions.ScalaValueClassesNoUnit
uncurry.VarargsSymbolAttachment
uncurry.DesugaredParameterType
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
index f0d96e0fd6..eadafc8abb 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
@@ -18,6 +18,12 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable
if (elems.exists(_.isInstanceOf[RefinedType])) new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq
else new BaseTypeSeq(parents, elems)
+ override protected def newMappedBaseTypeSeq(orig: BaseTypeSeq, f: Type => Type) =
+ // MappedBaseTypeSeq's are used rarely enough that we unconditionally mixin the synchronized
+ // wrapper, rather than doing this conditionally. A previous attempt to do that broke the "late"
+ // part of the "lateMap" contract in inspecting the mapped elements.
+ new MappedBaseTypeSeq(orig, f) with SynchronizedBaseTypeSeq
+
trait SynchronizedBaseTypeSeq extends BaseTypeSeq {
override def apply(i: Int): Type = gilSynchronized { super.apply(i) }
override def rawElem(i: Int) = gilSynchronized { super.rawElem(i) }
@@ -28,11 +34,6 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable
override def exists(p: Type => Boolean): Boolean = gilSynchronized { super.exists(p) }
override lazy val maxDepth = gilSynchronized { maxDepthOfElems }
override def toString = gilSynchronized { super.toString }
-
- override def lateMap(f: Type => Type): BaseTypeSeq =
- // only need to synchronize BaseTypeSeqs if they contain refined types
- if (map(f).toList.exists(_.isInstanceOf[RefinedType])) new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq
- else new MappedBaseTypeSeq(this, f)
}
// Scopes
diff --git a/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala b/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala
index 01e3a90950..f68705211f 100644
--- a/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala
@@ -13,6 +13,12 @@ trait ExprTyper {
import global.{ reporter => _, Import => _, _ }
import naming.freshInternalVarName
+ private def doInterpret(code: String): IR.Result = {
+ // interpret/interpretSynthetic may change the phase, which would have unintended effects on types.
+ val savedPhase = phase
+ try interpretSynthetic(code) finally phase = savedPhase
+ }
+
def symbolOfLine(code: String): Symbol = {
def asExpr(): Symbol = {
val name = freshInternalVarName()
@@ -21,7 +27,7 @@ trait ExprTyper {
// behind a def and strip the NullaryMethodType which wraps the expr.
val line = "def " + name + " = " + code
- interpretSynthetic(line) match {
+ doInterpret(line) match {
case IR.Success =>
val sym0 = symbolOfTerm(name)
// drop NullaryMethodType
@@ -32,7 +38,7 @@ trait ExprTyper {
def asDefn(): Symbol = {
val old = repl.definedSymbolList.toSet
- interpretSynthetic(code) match {
+ doInterpret(code) match {
case IR.Success =>
repl.definedSymbolList filterNot old match {
case Nil => NoSymbol
@@ -43,7 +49,7 @@ trait ExprTyper {
}
}
def asError(): Symbol = {
- interpretSynthetic(code)
+ doInterpret(code)
NoSymbol
}
beSilentDuring(asExpr()) orElse beSilentDuring(asDefn()) orElse asError()
@@ -72,7 +78,7 @@ trait ExprTyper {
def asProperType(): Option[Type] = {
val name = freshInternalVarName()
val line = "def %s: %s = ???" format (name, typeString)
- interpretSynthetic(line) match {
+ doInterpret(line) match {
case IR.Success =>
val sym0 = symbolOfTerm(name)
Some(sym0.asMethod.returnType)
diff --git a/src/repl/scala/tools/nsc/interpreter/Formatting.scala b/src/repl/scala/tools/nsc/interpreter/Formatting.scala
deleted file mode 100644
index 4a9548730a..0000000000
--- a/src/repl/scala/tools/nsc/interpreter/Formatting.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Paul Phillips
- */
-
-package scala.tools.nsc
-package interpreter
-
-import util.stringFromWriter
-
-class Formatting(indent: Int) {
-
- private val indentation = " " * indent
-
- private def indenting(code: String): Boolean = {
- /** Heuristic to avoid indenting and thereby corrupting """-strings and XML literals. */
- val tokens = List("\"\"\"", "</", "/>")
- val noIndent = (code contains "\n") && (tokens exists code.contains)
-
- !noIndent
- }
- /** Indent some code by the width of the scala> prompt.
- * This way, compiler error messages read better.
- */
- def indentCode(code: String) = stringFromWriter(str =>
- for (line <- code.lines) {
- if (indenting(code)) str print indentation
- str println line
- str.flush()
- }
- )
-}
-object Formatting {
- def forPrompt(prompt: String) = new Formatting(prompt.lines.toList.last.length)
-}
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index a351d2da95..2ae3b207b7 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -111,11 +111,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
try body finally label = saved
}
- // the expanded prompt but without color escapes and without leading newline, for purposes of indenting
- lazy val formatting = Formatting.forPrompt(replProps.promptText)
lazy val reporter: ReplReporter = new ReplReporter(this)
- import formatting.indentCode
import reporter.{ printMessage, printUntruncatedMessage }
// This exists mostly because using the reporter too early leads to deadlock.
@@ -867,8 +864,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
|${preambleHeader format lineRep.readName}
|${envLines mkString (" ", ";\n ", ";\n")}
|$importsPreamble
- |${indentCode(toCompute)}""".stripMargin
- def preambleLength = preamble.length - toCompute.length - 1
+ |${toCompute}""".stripMargin
+ def preambleLength = preamble.length - toCompute.length
val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this
diff --git a/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
index d6c0dafaf2..f455e71476 100644
--- a/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -213,29 +213,40 @@ trait MemberHandlers {
class ImportHandler(imp: Import) extends MemberHandler(imp) {
val Import(expr, selectors) = imp
+
def targetType = intp.global.rootMirror.getModuleIfDefined("" + expr) match {
case NoSymbol => intp.typeOfExpression("" + expr)
- case sym => sym.thisType
+ case sym => sym.tpe
}
- private def importableTargetMembers = importableMembers(targetType).toList
- // wildcard imports, e.g. import foo._
- private def selectorWild = selectors filter (_.name == nme.USCOREkw)
- // renamed imports, e.g. import foo.{ bar => baz }
- private def selectorRenames = selectors map (_.rename) filterNot (_ == null)
+
+ private def isFlattenedSymbol(sym: Symbol) =
+ sym.owner.isPackageClass &&
+ sym.name.containsName(nme.NAME_JOIN_STRING) &&
+ sym.owner.info.member(sym.name.take(sym.name.indexOf(nme.NAME_JOIN_STRING))) != NoSymbol
+
+ private def importableTargetMembers =
+ importableMembers(exitingTyper(targetType)).filterNot(isFlattenedSymbol).toList
+
+ // non-wildcard imports
+ private def individualSelectors = selectors filter analyzer.isIndividualImport
/** Whether this import includes a wildcard import */
- val importsWildcard = selectorWild.nonEmpty
+ val importsWildcard = selectors exists analyzer.isWildcardImport
def implicitSymbols = importedSymbols filter (_.isImplicit)
def importedSymbols = individualSymbols ++ wildcardSymbols
- private val selectorNames = selectorRenames filterNot (_ == nme.USCOREkw) flatMap (_.bothNames) toSet
- lazy val individualSymbols: List[Symbol] = exitingTyper(importableTargetMembers filter (m => selectorNames(m.name)))
- lazy val wildcardSymbols: List[Symbol] = exitingTyper(if (importsWildcard) importableTargetMembers else Nil)
+ lazy val importableSymbolsWithRenames = {
+ val selectorRenameMap = individualSelectors.flatMap(x => x.name.bothNames zip x.rename.bothNames).toMap
+ importableTargetMembers flatMap (m => selectorRenameMap.get(m.name) map (m -> _))
+ }
+
+ lazy val individualSymbols: List[Symbol] = importableSymbolsWithRenames map (_._1)
+ lazy val wildcardSymbols: List[Symbol] = if (importsWildcard) importableTargetMembers else Nil
/** Complete list of names imported by a wildcard */
lazy val wildcardNames: List[Name] = wildcardSymbols map (_.name)
- lazy val individualNames: List[Name] = individualSymbols map (_.name)
+ lazy val individualNames: List[Name] = importableSymbolsWithRenames map (_._2)
/** The names imported by this statement */
override lazy val importedNames: List[Name] = wildcardNames ++ individualNames
diff --git a/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala b/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala
index 3a0b69f41e..b01d242d44 100644
--- a/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala
@@ -9,7 +9,7 @@ package interpreter
import reporters._
import IMain._
-import scala.reflect.internal.util.Position
+import scala.reflect.internal.util.{OffsetPosition, Position}
/** Like ReplGlobal, a layer for ensuring extra functionality.
*/
@@ -40,14 +40,25 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i
case INFO => RESET
}
+ private val promptLength = replProps.promptText.lines.toList.last.length
+ private val indentation = " " * promptLength
+
+ // colorized console labels
+ override protected def clabel(severity: Severity): String = {
+ val label0 = super.clabel(severity)
+ if (replProps.colorOk) s"${severityColor(severity)}${label0}${RESET}" else label0
+ }
+
+ // shift indentation for source text entered at prompt
override def print(pos: Position, msg: String, severity: Severity) {
- val prefix = (
- if (replProps.colorOk)
- severityColor(severity) + clabel(severity) + RESET
- else
- clabel(severity)
- )
- printMessage(pos, prefix + msg)
+ val adjusted =
+ if (pos.source.file.name == "<console>")
+ new OffsetPosition(pos.source, pos.offset.getOrElse(0)) {
+ override def lineContent = s"${indentation}${super.lineContent}"
+ override def lineCaret = s"${indentation}${super.lineCaret}"
+ }
+ else pos
+ super.print(adjusted, msg, severity)
}
override def printMessage(msg: String) {
@@ -63,12 +74,8 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i
else Console.println("[init] " + msg)
}
- override def displayPrompt() {
- if (intp.totalSilence) ()
- else super.displayPrompt()
- }
+ override def displayPrompt() = if (!intp.totalSilence) super.displayPrompt()
override def rerunWithDetails(setting: reflect.internal.settings.MutableSettings#Setting, name: String) =
s"; for details, enable `:setting $name' or `:replay $name'"
-
}
diff --git a/src/repl/scala/tools/nsc/interpreter/Scripted.scala b/src/repl/scala/tools/nsc/interpreter/Scripted.scala
index 6aef486957..8d87d98e53 100644
--- a/src/repl/scala/tools/nsc/interpreter/Scripted.scala
+++ b/src/repl/scala/tools/nsc/interpreter/Scripted.scala
@@ -331,7 +331,7 @@ class WriterOutputStream(writer: Writer) extends OutputStream {
byteBuffer.flip()
val result = decoder.decode(byteBuffer, charBuffer, /*eoi=*/ false)
if (byteBuffer.remaining == 0) byteBuffer.clear()
- if (charBuffer.position > 0) {
+ if (charBuffer.position() > 0) {
charBuffer.flip()
writer write charBuffer.toString
charBuffer.clear()
diff --git a/test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala b/test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala
new file mode 100644
index 0000000000..94844dcae2
--- /dev/null
+++ b/test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala
@@ -0,0 +1,72 @@
+package scala.collection.immutable
+
+import java.util.concurrent.TimeUnit
+
+import org.openjdk.jmh.annotations._
+
+object ListBenchmark {
+ case class Content(value: Int)
+}
+
+@BenchmarkMode(Array(Mode.AverageTime))
+@Fork(2)
+@Threads(1)
+@Warmup(iterations = 10)
+@Measurement(iterations = 10)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+class ListBenchmark {
+ import ListBenchmark._
+ @Param(Array("0", "1", "10", "100", "1000"))
+ var size: Int = _
+
+ var values: List[Content] = _
+ var mid: Content = _
+ var last: Content = _
+
+
+ @Setup(Level.Trial) def initKeys(): Unit = {
+ values = List.tabulate(size)(v => Content(v))
+ mid = Content(size / 2)
+ last = Content(Math.max(0,size -1))
+ }
+
+ @Benchmark def filter_includeAll: Any = {
+ values.filter(v => true)
+ }
+
+ @Benchmark def filter_excludeAll: Any = {
+ values.filter(_ => false)
+ }
+
+ @Benchmark def filter_exc_mid: Any = {
+ values.filter(v => v.value != mid.value)
+ }
+
+ @Benchmark def filter_from_mid: Any = {
+ values.filter(v => v.value <= mid.value)
+ }
+
+ @Benchmark def filter_exc_last: Any = {
+ values.filter(v => v.value != last.value)
+ }
+
+ @Benchmark def filter_only_last: Any = {
+ values.filter(v => v.value == last.value)
+ }
+
+ @Setup(Level.Trial) def initKeys(): Unit = {
+ values = List.tabulate(size)(n => if (n == size / 2) "mid" else "")
+ }
+
+ @Benchmark def mapConserve_identity: Any = {
+ values.mapConserve(x => x)
+ }
+
+ @Benchmark def mapConserve_modifyAll: Any = {
+ values.mapConserve(x => "replace")
+ }
+ @Benchmark def mapConserve_modifyMid: Any = {
+ values.mapConserve(x => if (x == "mid") "replace" else x)
+ }
+}
diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check
index 72d8d39fd0..6b712b93c7 100644
--- a/test/files/jvm/interpreter.check
+++ b/test/files/jvm/interpreter.check
@@ -278,13 +278,13 @@ scala> // both of the following should abort immediately:
scala> def x => y => z
<console>:1: error: '=' expected but '=>' found.
-def x => y => z
- ^
+ def x => y => z
+ ^
scala> [1,2,3]
<console>:1: error: illegal start of definition
-[1,2,3]
-^
+ [1,2,3]
+ ^
scala>
diff --git a/test/files/neg/badtok-1.check b/test/files/neg/badtok-1.check
index b05bc60161..5d5a8e1f35 100644
--- a/test/files/neg/badtok-1.check
+++ b/test/files/neg/badtok-1.check
@@ -4,4 +4,10 @@ badtok-1.scala:2: error: unclosed character literal
badtok-1.scala:2: error: unclosed character literal
'42'
^
-two errors found
+badtok-1.scala:6: error: empty character literal (use '\'' for single quote)
+'''
+^
+badtok-1.scala:9: error: unclosed character literal (or use " for string literal "abc")
+'abc'
+ ^
+four errors found
diff --git a/test/files/neg/badtok-1.scala b/test/files/neg/badtok-1.scala
index 706e794946..cc7dc6cecc 100644
--- a/test/files/neg/badtok-1.scala
+++ b/test/files/neg/badtok-1.scala
@@ -1,2 +1,9 @@
// bug 989
'42'
+
+
+// SI-10133
+'''
+
+// SI-10120
+'abc'
diff --git a/test/files/neg/t5856.check b/test/files/neg/t5856.check
index 08a61bdc07..306cc04177 100644
--- a/test/files/neg/t5856.check
+++ b/test/files/neg/t5856.check
@@ -1,4 +1,4 @@
-t5856.scala:10: error: invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected
+t5856.scala:10: error: invalid string interpolation $", expected: $$, $identifier or ${expression}
val s9 = s"$"
^
t5856.scala:10: error: unclosed string literal
diff --git a/test/files/pos/sam_erasure_boundedwild.scala b/test/files/pos/sam_erasure_boundedwild.scala
new file mode 100644
index 0000000000..1ec27e0ea4
--- /dev/null
+++ b/test/files/pos/sam_erasure_boundedwild.scala
@@ -0,0 +1,11 @@
+class Test {
+ trait Q[T] {
+ def toArray[T](x: Array[T]): Array[T]
+ def toArray(): Array[T]
+ }
+
+ def crashTyper: Array[_] = {
+ val x : Q[_] = ???
+ x.toArray // crashes while doing overload resolution
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t9331.scala b/test/files/pos/t9331.scala
new file mode 100644
index 0000000000..00a667886f
--- /dev/null
+++ b/test/files/pos/t9331.scala
@@ -0,0 +1,6 @@
+import scala.language.higherKinds
+
+trait Proxy[+T]
+case class Stuff[+P[PP] <: Proxy[PP]]() {
+ // canEqual was incorrectly synthetized and started reporting a kind error.
+}
diff --git a/test/files/run/elidable-opt.check b/test/files/run/elidable-opt.check
index 88cf98e0d1..969b9a420a 100644
--- a/test/files/run/elidable-opt.check
+++ b/test/files/run/elidable-opt.check
@@ -11,4 +11,4 @@ false
0
0.0
0.0
-null
+
diff --git a/test/files/run/elidable.check b/test/files/run/elidable.check
index 88cf98e0d1..969b9a420a 100644
--- a/test/files/run/elidable.check
+++ b/test/files/run/elidable.check
@@ -11,4 +11,4 @@ false
0
0.0
0.0
-null
+
diff --git a/test/files/run/elidable.scala b/test/files/run/elidable.scala
index 02785972bb..fed1c7b392 100644
--- a/test/files/run/elidable.scala
+++ b/test/files/run/elidable.scala
@@ -3,31 +3,36 @@ import elidable._
// runs -Xelide-below WARNING or 900
+object Fail {
+ def fail(msg: String): Unit = throw new IllegalStateException(s"Expected failure: $msg")
+}
+import Fail.fail
+
trait T {
@elidable(FINEST) def f1()
@elidable(SEVERE) def f2()
- @elidable(FINEST) def f3() = assert(false, "Should have been elided.")
+ @elidable(FINEST) def f3() = fail("Should have been elided.")
def f4()
}
class C extends T {
def f1() = println("Good for me, I was not elided. C.f1")
def f2() = println("Good for me, I was not elided. C.f2")
- @elidable(FINEST) def f4() = assert(false, "Should have been elided.")
+ @elidable(FINEST) def f4() = fail("Should have been elided.")
}
object O {
- @elidable(FINEST) def f1() = assert(false, "Should have been elided.")
- @elidable(INFO) def f2() = assert(false, "Should have been elided.")
+ @elidable(FINEST) def f1() = fail("Should have been elided.")
+ @elidable(INFO) def f2() = fail("Should have been elided.")
@elidable(SEVERE) def f3() = println("Good for me, I was not elided. O.f3")
- @elidable(INFO) def f4 = assert(false, "Should have been elided (no parens).")
+ @elidable(INFO) def f4 = fail("Should have been elided (no parens).")
}
object Test {
- @elidable(FINEST) def f1() = assert(false, "Should have been elided.")
- @elidable(INFO) def f2() = assert(false, "Should have been elided.")
+ @elidable(FINEST) def f1() = fail("Should have been elided.")
+ @elidable(INFO) def f2() = fail("Should have been elided.")
@elidable(SEVERE) def f3() = println("Good for me, I was not elided. Test.f3")
- @elidable(INFO) def f4 = assert(false, "Should have been elided (no parens).")
+ @elidable(INFO) def f4 = fail("Should have been elided (no parens).")
@elidable(FINEST) def f5() = {}
@elidable(FINEST) def f6() = true
@@ -38,12 +43,12 @@ object Test {
@elidable(FINEST) def fb() = 1l
@elidable(FINEST) def fc() = 1.0f
@elidable(FINEST) def fd() = 1.0
- @elidable(FINEST) def fe() = "s"
+ @elidable(FINEST) def fe() = { fail("Should have been elided to empty string.") ; "hello, world" }
/* variable elisions? see test/files/neg/t10068.scala
- @elidable(INFO) val goner1: Int = { assert(false, "Should have been elided.") ; 42 }
- @elidable(INFO) lazy val goner2: Int = { assert(false, "Should have been elided.") ; 42 }
- @elidable(INFO) var goner3: Int = { assert(false, "Should have been elided.") ; 42 }
+ @elidable(INFO) val goner1: Int = { fail("Should have been elided.") ; 42 }
+ @elidable(INFO) lazy val goner2: Int = { fail("Should have been elided.") ; 42 }
+ @elidable(INFO) var goner3: Int = { fail("Should have been elided.") ; 42 }
@elidable(INFO) var goner4: Nothing = _
*/
@@ -74,6 +79,19 @@ object Test {
println(fc())
println(fd())
println(fe())
+ if (!fe().isEmpty) fail(s"Not empty: [${fe()}]")
+/*
+()
+false
+0
+0
+0
+0
+0
+0.0
+0.0
+ // was: null
+*/
// this one won't show up in the output because a call to f1 is elidable when accessed through T
(c:T).f1()
diff --git a/test/files/run/existentials-in-compiler.check b/test/files/run/existentials-in-compiler.check
index b0d852865d..8800df0823 100644
--- a/test/files/run/existentials-in-compiler.check
+++ b/test/files/run/existentials-in-compiler.check
@@ -2,28 +2,28 @@ abstract trait Bippy[A <: AnyRef, B] extends AnyRef
extest.Bippy[_ <: AnyRef, _]
abstract trait BippyBud[A <: AnyRef, B, C <: List[A]] extends AnyRef
- extest.BippyBud[A,B,C] forSome { A <: AnyRef; B; C <: List[A] }
+ extest.BippyBud[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1; type ?2 <: List[?0] }
abstract trait BippyLike[A <: AnyRef, B <: List[A], This <: extest.BippyLike[A,B,This] with extest.Bippy[A,B]] extends AnyRef
- extest.BippyLike[A,B,This] forSome { A <: AnyRef; B <: List[A]; This <: extest.BippyLike[A,B,This] with extest.Bippy[A,B] }
+ extest.BippyLike[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1 <: List[?0]; type ?2 <: extest.BippyLike[?0,?1,?2] with extest.Bippy[?0,?1] }
abstract trait Contra[-A >: AnyRef, -B] extends AnyRef
- extest.Contra[AnyRef, _]
+ extest.Contra[_ >: AnyRef, _]
abstract trait ContraLike[-A >: AnyRef, -B >: List[A]] extends AnyRef
- extest.ContraLike[A,B] forSome { -A >: AnyRef; -B >: List[A] }
+ extest.ContraLike[?0,?1] forSome { type ?0 >: AnyRef; type ?1 >: List[?0] }
abstract trait Cov01[+A <: AnyRef, +B] extends AnyRef
- extest.Cov01[AnyRef,Any]
+ extest.Cov01[_ <: AnyRef, _]
abstract trait Cov02[+A <: AnyRef, B] extends AnyRef
- extest.Cov02[AnyRef, _]
+ extest.Cov02[_ <: AnyRef, _]
abstract trait Cov03[+A <: AnyRef, -B] extends AnyRef
- extest.Cov03[AnyRef, _]
+ extest.Cov03[_ <: AnyRef, _]
abstract trait Cov04[A <: AnyRef, +B] extends AnyRef
- extest.Cov04[_ <: AnyRef, Any]
+ extest.Cov04[_ <: AnyRef, _]
abstract trait Cov05[A <: AnyRef, B] extends AnyRef
extest.Cov05[_ <: AnyRef, _]
@@ -32,7 +32,7 @@ abstract trait Cov06[A <: AnyRef, -B] extends AnyRef
extest.Cov06[_ <: AnyRef, _]
abstract trait Cov07[-A <: AnyRef, +B] extends AnyRef
- extest.Cov07[_ <: AnyRef, Any]
+ extest.Cov07[_ <: AnyRef, _]
abstract trait Cov08[-A <: AnyRef, B] extends AnyRef
extest.Cov08[_ <: AnyRef, _]
@@ -41,16 +41,16 @@ abstract trait Cov09[-A <: AnyRef, -B] extends AnyRef
extest.Cov09[_ <: AnyRef, _]
abstract trait Cov11[+A <: AnyRef, +B <: List[_]] extends AnyRef
- extest.Cov11[AnyRef,List[_]]
+ extest.Cov11[_ <: AnyRef, _ <: List[_]]
abstract trait Cov12[+A <: AnyRef, B <: List[_]] extends AnyRef
- extest.Cov12[AnyRef, _ <: List[_]]
+ extest.Cov12[_ <: AnyRef, _ <: List[_]]
abstract trait Cov13[+A <: AnyRef, -B <: List[_]] extends AnyRef
- extest.Cov13[AnyRef, _ <: List[_]]
+ extest.Cov13[_ <: AnyRef, _ <: List[_]]
abstract trait Cov14[A <: AnyRef, +B <: List[_]] extends AnyRef
- extest.Cov14[_ <: AnyRef, List[_]]
+ extest.Cov14[_ <: AnyRef, _ <: List[_]]
abstract trait Cov15[A <: AnyRef, B <: List[_]] extends AnyRef
extest.Cov15[_ <: AnyRef, _ <: List[_]]
@@ -59,7 +59,7 @@ abstract trait Cov16[A <: AnyRef, -B <: List[_]] extends AnyRef
extest.Cov16[_ <: AnyRef, _ <: List[_]]
abstract trait Cov17[-A <: AnyRef, +B <: List[_]] extends AnyRef
- extest.Cov17[_ <: AnyRef, List[_]]
+ extest.Cov17[_ <: AnyRef, _ <: List[_]]
abstract trait Cov18[-A <: AnyRef, B <: List[_]] extends AnyRef
extest.Cov18[_ <: AnyRef, _ <: List[_]]
@@ -68,16 +68,16 @@ abstract trait Cov19[-A <: AnyRef, -B <: List[_]] extends AnyRef
extest.Cov19[_ <: AnyRef, _ <: List[_]]
abstract trait Cov21[+A, +B] extends AnyRef
- extest.Cov21[Any,Any]
+ extest.Cov21[_, _]
abstract trait Cov22[+A, B] extends AnyRef
- extest.Cov22[Any, _]
+ extest.Cov22[_, _]
abstract trait Cov23[+A, -B] extends AnyRef
- extest.Cov23[Any, _]
+ extest.Cov23[_, _]
abstract trait Cov24[A, +B] extends AnyRef
- extest.Cov24[_, Any]
+ extest.Cov24[_, _]
abstract trait Cov25[A, B] extends AnyRef
extest.Cov25[_, _]
@@ -86,7 +86,7 @@ abstract trait Cov26[A, -B] extends AnyRef
extest.Cov26[_, _]
abstract trait Cov27[-A, +B] extends AnyRef
- extest.Cov27[_, Any]
+ extest.Cov27[_, _]
abstract trait Cov28[-A, B] extends AnyRef
extest.Cov28[_, _]
@@ -95,43 +95,43 @@ abstract trait Cov29[-A, -B] extends AnyRef
extest.Cov29[_, _]
abstract trait Cov31[+A, +B, C <: (A, B)] extends AnyRef
- extest.Cov31[A,B,C] forSome { +A; +B; C <: (A, B) }
+ extest.Cov31[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
abstract trait Cov32[+A, B, C <: (A, B)] extends AnyRef
- extest.Cov32[A,B,C] forSome { +A; B; C <: (A, B) }
+ extest.Cov32[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
abstract trait Cov33[+A, -B, C <: Tuple2[A, _]] extends AnyRef
- extest.Cov33[A,B,C] forSome { +A; -B; C <: Tuple2[A, _] }
+ extest.Cov33[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[?0, _] }
abstract trait Cov34[A, +B, C <: (A, B)] extends AnyRef
- extest.Cov34[A,B,C] forSome { A; +B; C <: (A, B) }
+ extest.Cov34[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
abstract trait Cov35[A, B, C <: (A, B)] extends AnyRef
- extest.Cov35[A,B,C] forSome { A; B; C <: (A, B) }
+ extest.Cov35[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
abstract trait Cov36[A, -B, C <: Tuple2[A, _]] extends AnyRef
- extest.Cov36[A,B,C] forSome { A; -B; C <: Tuple2[A, _] }
+ extest.Cov36[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[?0, _] }
abstract trait Cov37[-A, +B, C <: Tuple2[_, B]] extends AnyRef
- extest.Cov37[A,B,C] forSome { -A; +B; C <: Tuple2[_, B] }
+ extest.Cov37[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[_, ?1] }
abstract trait Cov38[-A, B, C <: Tuple2[_, B]] extends AnyRef
- extest.Cov38[A,B,C] forSome { -A; B; C <: Tuple2[_, B] }
+ extest.Cov38[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[_, ?1] }
abstract trait Cov39[-A, -B, C <: Tuple2[_, _]] extends AnyRef
extest.Cov39[_, _, _ <: Tuple2[_, _]]
abstract trait Cov41[+A >: Null, +B] extends AnyRef
- extest.Cov41[Any,Any]
+ extest.Cov41[_ >: Null, _]
abstract trait Cov42[+A >: Null, B] extends AnyRef
- extest.Cov42[Any, _]
+ extest.Cov42[_ >: Null, _]
abstract trait Cov43[+A >: Null, -B] extends AnyRef
- extest.Cov43[Any, _]
+ extest.Cov43[_ >: Null, _]
abstract trait Cov44[A >: Null, +B] extends AnyRef
- extest.Cov44[_ >: Null, Any]
+ extest.Cov44[_ >: Null, _]
abstract trait Cov45[A >: Null, B] extends AnyRef
extest.Cov45[_ >: Null, _]
@@ -140,7 +140,7 @@ abstract trait Cov46[A >: Null, -B] extends AnyRef
extest.Cov46[_ >: Null, _]
abstract trait Cov47[-A >: Null, +B] extends AnyRef
- extest.Cov47[_ >: Null, Any]
+ extest.Cov47[_ >: Null, _]
abstract trait Cov48[-A >: Null, B] extends AnyRef
extest.Cov48[_ >: Null, _]
@@ -149,8 +149,8 @@ abstract trait Cov49[-A >: Null, -B] extends AnyRef
extest.Cov49[_ >: Null, _]
abstract trait Covariant[+A <: AnyRef, +B] extends AnyRef
- extest.Covariant[AnyRef,Any]
+ extest.Covariant[_ <: AnyRef, _]
abstract trait CovariantLike[+A <: AnyRef, +B <: List[A], +This <: extest.CovariantLike[A,B,This] with extest.Covariant[A,B]] extends AnyRef
- extest.CovariantLike[A,B,This] forSome { +A <: AnyRef; +B <: List[A]; +This <: extest.CovariantLike[A,B,This] with extest.Covariant[A,B] }
+ extest.CovariantLike[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1 <: List[?0]; type ?2 <: extest.CovariantLike[?0,?1,?2] with extest.Covariant[?0,?1] }
diff --git a/test/files/run/existentials-in-compiler.scala b/test/files/run/existentials-in-compiler.scala
index e516eddf95..e35b7231c2 100644
--- a/test/files/run/existentials-in-compiler.scala
+++ b/test/files/run/existentials-in-compiler.scala
@@ -79,7 +79,7 @@ package extest {
exitingTyper {
clazz.info
println(clazz.defString)
- println(" " + classExistentialType(clazz) + "\n")
+ println(" " + classExistentialType(clazz.owner.typeOfThis, clazz) + "\n")
}
}
}
diff --git a/test/files/run/literals.scala b/test/files/run/literals.scala
index 25501123b5..a7962e5cd9 100644
--- a/test/files/run/literals.scala
+++ b/test/files/run/literals.scala
@@ -6,7 +6,7 @@
object Test {
- /* I add a couple of Unicode identifier tests here temporarily */
+ /* I add a couple of Unicode identifier tests here "temporarily" */
def \u03b1\u03c1\u03b5\u03c4\u03b7 = "alpha rho epsilon tau eta"
@@ -80,6 +80,9 @@ object Test {
check_success("1e1f == 10.0f", 1e1f, 10.0f)
check_success(".3f == 0.3f", .3f, 0.3f)
check_success("0f == 0.0f", 0f, 0.0f)
+ check_success("0f == -0.000000000000000000e+00f", 0f, -0.000000000000000000e+00f)
+ check_success("0f == -0.000000000000000000e+00F", 0f, -0.000000000000000000e+00F)
+ check_success("0f == -0.0000000000000000e14f", 0f, -0.0000000000000000e14f)
check_success("01.23f == 1.23f", 01.23f, 1.23f)
check_success("3.14f == 3.14f", 3.14f, 3.14f)
check_success("6.022e23f == 6.022e23f", 6.022e23f, 6.022e23f)
@@ -96,6 +99,11 @@ object Test {
check_success(".3 == 0.3", .3, 0.3)
check_success("0.0 == 0.0", 0.0, 0.0)
check_success("0d == 0.0", 0d, 0.0)
+ check_success("0d == 0.000000000000000000e+00d", 0d, 0.000000000000000000e+00d)
+ check_success("0d == -0.000000000000000000e+00d", 0d, -0.000000000000000000e+00d)
+ check_success("0d == -0.000000000000000000e+00D", 0d, -0.000000000000000000e+00D)
+ check_success("0.0 == 0.000000000000000000e+00", 0.0, 0.000000000000000000e+00)
+ check_success("0.0 == -0.000000000000000000e+00", 0.0, -0.000000000000000000e+00)
check_success("01.23 == 1.23", 01.23, 1.23)
check_success("01.23d == 1.23d", 01.23d, 1.23d)
check_success("3.14 == 3.14", 3.14, 3.14)
diff --git a/test/files/run/reify_newimpl_22.check b/test/files/run/reify_newimpl_22.check
index 985f646579..b2f4d5624e 100644
--- a/test/files/run/reify_newimpl_22.check
+++ b/test/files/run/reify_newimpl_22.check
@@ -15,7 +15,7 @@ scala> {
}
println(code.eval)
}
-<console>:19: free term: Ident(TermName("x")) defined by res0 in <console>:18:14
+<console>:19: free term: Ident(TermName("x")) defined by res0 in <console>:18:7
val code = reify {
^
2
diff --git a/test/files/run/reify_newimpl_23.check b/test/files/run/reify_newimpl_23.check
index f60113c69f..abf314b26a 100644
--- a/test/files/run/reify_newimpl_23.check
+++ b/test/files/run/reify_newimpl_23.check
@@ -14,7 +14,7 @@ scala> def foo[T]{
}
println(code.eval)
}
-<console>:17: free type: Ident(TypeName("T")) defined by foo in <console>:16:16
+<console>:17: free type: Ident(TypeName("T")) defined by foo in <console>:16:9
val code = reify {
^
foo: [T]=> Unit
diff --git a/test/files/run/reify_newimpl_25.check b/test/files/run/reify_newimpl_25.check
index 9104d8df0b..d446caa91a 100644
--- a/test/files/run/reify_newimpl_25.check
+++ b/test/files/run/reify_newimpl_25.check
@@ -5,7 +5,7 @@ scala> {
val tt = implicitly[TypeTag[x.type]]
println(tt)
}
-<console>:15: free term: Ident(TermName("x")) defined by res0 in <console>:14:14
+<console>:15: free term: Ident(TermName("x")) defined by res0 in <console>:14:7
val tt = implicitly[TypeTag[x.type]]
^
TypeTag[x.type]
diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check
index cbb21854ba..099231bf62 100644
--- a/test/files/run/reify_newimpl_26.check
+++ b/test/files/run/reify_newimpl_26.check
@@ -4,7 +4,7 @@ scala> def foo[T]{
val tt = implicitly[WeakTypeTag[List[T]]]
println(tt)
}
-<console>:13: free type: Ident(TypeName("T")) defined by foo in <console>:11:16
+<console>:13: free type: Ident(TypeName("T")) defined by foo in <console>:11:9
val tt = implicitly[WeakTypeTag[List[T]]]
^
foo: [T]=> Unit
diff --git a/test/files/run/repl-colon-type.check b/test/files/run/repl-colon-type.check
index 1217e8d8c2..3fdd318df6 100644
--- a/test/files/run/repl-colon-type.check
+++ b/test/files/run/repl-colon-type.check
@@ -1,8 +1,8 @@
scala> :type List[1, 2, 3]
<console>:1: error: identifier expected but integer literal found.
-List[1, 2, 3]
- ^
+ List[1, 2, 3]
+ ^
scala> :type List(1, 2, 3)
List[Int]
@@ -38,8 +38,8 @@ scala> :type protected lazy val f = 5
Access to protected lazy value f not permitted because
enclosing object $eval in package $line13 is not a subclass of
object $iw where target is defined
- lazy val $result = f
- ^
+ lazy val $result = f
+ ^
scala> :type def f = 5
=> Int
@@ -75,7 +75,7 @@ TypeRef(
)
TypeRef(
TypeSymbol(
- sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] with Serializable
+ sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] with FilteredTraversableInternal[A,List[A]] with Serializable
)
args = List(
@@ -142,7 +142,7 @@ TypeRef(
args = List(
TypeRef(
TypeSymbol(
- sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] with Serializable
+ sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] with FilteredTraversableInternal[A,List[A]] with Serializable
)
args = List(
@@ -175,7 +175,7 @@ PolyType(
args = List(
TypeRef(
TypeSymbol(
- sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] with Serializable
+ sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] with FilteredTraversableInternal[A,List[A]] with Serializable
)
args = List(TypeParamTypeRef(TypeParam(T <: AnyVal)))
@@ -198,7 +198,7 @@ PolyType(
params = List(TermSymbol(x: T), TermSymbol(y: List[U]))
resultType = TypeRef(
TypeSymbol(
- sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] with Serializable
+ sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] with FilteredTraversableInternal[A,List[A]] with Serializable
)
args = List(TypeParamTypeRef(TypeParam(U >: T)))
diff --git a/test/files/run/t10026.check b/test/files/run/t10026.check
new file mode 100644
index 0000000000..15a62794a9
--- /dev/null
+++ b/test/files/run/t10026.check
@@ -0,0 +1 @@
+List(1, 2, 3)
diff --git a/test/files/run/t10026.scala b/test/files/run/t10026.scala
new file mode 100644
index 0000000000..a56840c8c2
--- /dev/null
+++ b/test/files/run/t10026.scala
@@ -0,0 +1,11 @@
+import scala.reflect.runtime.universe
+import scala.tools.reflect.ToolBox
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val classloader = getClass.getClassLoader
+ val toolbox = universe.runtimeMirror(classloader).mkToolBox()
+ println(toolbox.compile(toolbox.parse("Array(1, 2, 3).toList")).apply())
+ }
+}
+
diff --git a/test/files/run/t1459.check b/test/files/run/t1459.check
new file mode 100644
index 0000000000..93b4c5a810
--- /dev/null
+++ b/test/files/run/t1459.check
@@ -0,0 +1,3 @@
+JavaPrinter: one two three
+InheritingPrinter extends JavaPrinter: one two three
+ScalaPrinter: onetwothree
diff --git a/test/files/run/t1459/InheritingPrinter.scala b/test/files/run/t1459/InheritingPrinter.scala
new file mode 100644
index 0000000000..70301307f5
--- /dev/null
+++ b/test/files/run/t1459/InheritingPrinter.scala
@@ -0,0 +1,6 @@
+class InheritingPrinter extends JavaPrinter {
+ override def doit(s: String*) {
+ print("InheritingPrinter extends ")
+ super.doit(s: _*);
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t1459/JavaPrinter.java b/test/files/run/t1459/JavaPrinter.java
new file mode 100644
index 0000000000..3912ea613a
--- /dev/null
+++ b/test/files/run/t1459/JavaPrinter.java
@@ -0,0 +1,7 @@
+public class JavaPrinter implements VarArg {
+ public void doit(String... s) {
+ System.out.print("JavaPrinter: ");
+ for(String str : s)
+ System.out.print(str + " ");
+ }
+}
diff --git a/test/files/run/t1459/ScalaPrinter.scala b/test/files/run/t1459/ScalaPrinter.scala
new file mode 100644
index 0000000000..46305804c2
--- /dev/null
+++ b/test/files/run/t1459/ScalaPrinter.scala
@@ -0,0 +1,6 @@
+class ScalaPrinter extends VarArg {
+ override def doit(s: String*) = {
+ print("ScalaPrinter: ")
+ s.foreach(print _)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t1459/Test.java b/test/files/run/t1459/Test.java
new file mode 100644
index 0000000000..3cf91e2e8b
--- /dev/null
+++ b/test/files/run/t1459/Test.java
@@ -0,0 +1,15 @@
+public class Test {
+ public static void main(String[] args) {
+ VarArg jp = new JavaPrinter();
+ VarArg ip = new InheritingPrinter();
+ VarArg sp = new ScalaPrinter();
+ doYourThing(jp);
+ doYourThing(ip);
+ doYourThing(sp);
+ }
+
+ public static void doYourThing(VarArg va) {
+ va.doit("one", "two", "three");
+ System.out.println();
+ }
+}
diff --git a/test/files/run/t1459/VarArg.java b/test/files/run/t1459/VarArg.java
new file mode 100644
index 0000000000..7039f99e7b
--- /dev/null
+++ b/test/files/run/t1459/VarArg.java
@@ -0,0 +1,3 @@
+public interface VarArg {
+ void doit(String... s);
+}
diff --git a/test/files/run/t1459generic.check b/test/files/run/t1459generic.check
new file mode 100644
index 0000000000..346fadbc0d
--- /dev/null
+++ b/test/files/run/t1459generic.check
@@ -0,0 +1,4 @@
+Note: t1459generic/Test.java uses unchecked or unsafe operations.
+Note: Recompile with -Xlint:unchecked for details.
+ab
+ab
diff --git a/test/files/run/t1459generic/Impl.scala b/test/files/run/t1459generic/Impl.scala
new file mode 100644
index 0000000000..9234e70456
--- /dev/null
+++ b/test/files/run/t1459generic/Impl.scala
@@ -0,0 +1,4 @@
+class Impl extends VarargGeneric[String] {
+ def genericOne(x: String, arg: String): String = x + arg
+ def genericVar(x: String, args: String*): String = x + args.head
+}
diff --git a/test/files/run/t1459generic/Test.java b/test/files/run/t1459generic/Test.java
new file mode 100644
index 0000000000..a97158796b
--- /dev/null
+++ b/test/files/run/t1459generic/Test.java
@@ -0,0 +1,10 @@
+public class Test {
+ public static void main(String[] args) throws Exception {
+ VarargGeneric vg = new Impl();
+ System.out.println(vg.genericOne("a", "b"));
+ System.out.println(vg.genericVar("a", "b"));
+ // should not result in java.lang.AbstractMethodError: Impl.genericVar(Ljava/lang/Object;[Ljava/lang/String;)Ljava/lang/String;
+ // --> genericVar needs a varargs bridge (scala -> java varargs) and a standard generics bridge
+ // (for comparison, including genericOne, which needs only a generics bridge)
+ }
+}
diff --git a/test/files/run/t1459generic/VarargGeneric.java b/test/files/run/t1459generic/VarargGeneric.java
new file mode 100644
index 0000000000..9b37a0fe3f
--- /dev/null
+++ b/test/files/run/t1459generic/VarargGeneric.java
@@ -0,0 +1,7 @@
+public interface VarargGeneric<T> {
+ String genericOne(T x, String args);
+ // we cannot annotate this with @SafeVarargs, because
+ // it's in an interface. so that's why a warning from
+ // javac appears in the checkfile.
+ String genericVar(T x, String... args);
+}
diff --git a/test/files/run/t8918-unary-ids.check b/test/files/run/t8918-unary-ids.check
index 92f02371c7..b1f16ed56a 100644
--- a/test/files/run/t8918-unary-ids.check
+++ b/test/files/run/t8918-unary-ids.check
@@ -5,3 +5,17 @@ Expected 41 lines, got 39
-Type in expressions to have them evaluated.
-Type :help for more information.
+@@ -14,4 +12,4 @@
+ <console>:1: error: illegal start of simple expression
+-- if (true) 1 else 2
+- ^
++ - if (true) 1 else 2
++ ^
+
+@@ -19,4 +17,4 @@
+ <console>:1: error: ';' expected but integer literal found.
+-- - 1
+- ^
++ - - 1
++ ^
+
diff --git a/test/files/run/t9013/Test.java b/test/files/run/t9013/Test.java
new file mode 100644
index 0000000000..14152b16ac
--- /dev/null
+++ b/test/files/run/t9013/Test.java
@@ -0,0 +1,20 @@
+import java.util.Comparator;
+
+public class Test {
+ public static void main(String[] args) {
+ ClassImplementsClass c = new ClassImplementsClass();
+
+ c.x("a", "b", "c");
+ c.y("a", "b", "c");
+ c.z("a", "b", "c");
+
+ VarargAbstractClass i = new ClassImplementsClass();
+
+ i.x("a", "b", "c");
+ i.y("a", "b", "c");
+ // System.out.println(i.z("a", "b", "c")); // still incurs a LinkageError.
+ // Perhaps due to Uncurry:
+ // > for every repeated Java parameter `x: T...' --> x: Array[T], except:
+ // > if T is an unbounded abstract type, replace --> x: Array[Object]
+ }
+}
diff --git a/test/files/run/t9013/test.scala b/test/files/run/t9013/test.scala
new file mode 100644
index 0000000000..073f8d086f
--- /dev/null
+++ b/test/files/run/t9013/test.scala
@@ -0,0 +1,18 @@
+import scala.annotation.varargs
+
+abstract class VarargAbstractClass[T] {
+ @varargs
+ def x(els: String*): Int
+
+ @varargs
+ def y(els: String*): Int
+
+ @varargs
+ def z(els: T*): Int
+}
+class ClassImplementsClass extends VarargAbstractClass[String] {
+
+ override def x(els: String*): Int = els.length
+ override def y(els: String*): Int = els.length
+ override def z(els: String*): Int = els.length
+}
diff --git a/test/files/run/t9114.scala b/test/files/run/t9114.scala
new file mode 100644
index 0000000000..656a5c7d8d
--- /dev/null
+++ b/test/files/run/t9114.scala
@@ -0,0 +1,31 @@
+import annotation.unchecked
+
+class Test {
+ trait Two[A, B]
+ type One[A] = Two[A,A]
+ class View extends One[Any]
+
+ def checkAny(x: Some[One[Any]]) = x match { // okay
+ case Some(_: View) => true
+ case _ => false
+ }
+ def checkAbstract[A](x: Some[One[A]]) = x match { // okay
+ case Some(_: View) => true
+ case _ => false
+ }
+
+ def checkExistential(x: Some[One[_]]) = x match {
+ case Some(_: View) => true // compiler crash
+ case _ => false
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val t1 = new Test
+ val t2 = new Test
+ assert(t1.checkAny(Some(new t1.View)))
+ assert(t1.checkAbstract(Some(new t1.View)))
+ assert(t1.checkExistential(Some(new t1.View)))
+ }
+}
diff --git a/test/files/run/t9170.scala b/test/files/run/t9170.scala
index 87471fb129..cb7971235f 100644
--- a/test/files/run/t9170.scala
+++ b/test/files/run/t9170.scala
@@ -48,8 +48,8 @@ object Y {
def f[A](a: => A): Int at line 12 and
def f[A](a: => Either[Exception,A]): Int at line 13
have same type after erasure: (a: Function0)Int
- def f[A](a: => Either[Exception, A]) = 2
- ^
+ def f[A](a: => Either[Exception, A]) = 2
+ ^
scala> :quit"""
}
diff --git a/test/files/run/t9880-9881.check b/test/files/run/t9880-9881.check
new file mode 100644
index 0000000000..36513e249a
--- /dev/null
+++ b/test/files/run/t9880-9881.check
@@ -0,0 +1,36 @@
+
+scala> // import in various ways
+
+scala> import java.util.Date
+import java.util.Date
+
+scala> import scala.util._
+import scala.util._
+
+scala> import scala.reflect.runtime.{universe => ru}
+import scala.reflect.runtime.{universe=>ru}
+
+scala> import ru.TypeTag
+import ru.TypeTag
+
+scala>
+
+scala> // show the imports
+
+scala> :imports
+ 1) import java.lang._ (...)
+ 2) import scala._ (...)
+ 3) import scala.Predef._ (...)
+ 4) import java.util.Date (...)
+ 5) import scala.util._ (...)
+ 6) import scala.reflect.runtime.{universe=>ru} (...)
+ 7) import ru.TypeTag (...)
+
+scala>
+
+scala> // should be able to define this class with the imports above
+
+scala> class C[T](date: Date, rand: Random, typeTag: TypeTag[T])
+defined class C
+
+scala> :quit
diff --git a/test/files/run/t9880-9881.scala b/test/files/run/t9880-9881.scala
new file mode 100644
index 0000000000..0268c8c32c
--- /dev/null
+++ b/test/files/run/t9880-9881.scala
@@ -0,0 +1,29 @@
+import scala.tools.partest.ReplTest
+import scala.tools.nsc.Settings
+
+object Test extends ReplTest {
+
+ override def transformSettings(s: Settings): Settings = {
+ s.Yreplclassbased.value = true
+ s
+ }
+
+ lazy val normalizeRegex = """(import\s.*)\(.*\)""".r
+
+ override def normalize(s: String): String = normalizeRegex.replaceFirstIn(s, "$1(...)")
+
+ def code =
+ """
+ |// import in various ways
+ |import java.util.Date
+ |import scala.util._
+ |import scala.reflect.runtime.{universe => ru}
+ |import ru.TypeTag
+ |
+ |// show the imports
+ |:imports
+ |
+ |// should be able to define this class with the imports above
+ |class C[T](date: Date, rand: Random, typeTag: TypeTag[T])
+ """.stripMargin
+}
diff --git a/test/junit/scala/collection/IndexedSeqTest.scala b/test/junit/scala/collection/IndexedSeqTest.scala
new file mode 100644
index 0000000000..a33849e60b
--- /dev/null
+++ b/test/junit/scala/collection/IndexedSeqTest.scala
@@ -0,0 +1,578 @@
+package scala.collection
+
+import org.junit.Test
+import org.junit.Ignore
+import org.junit.Assert.{assertEquals, _}
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+// with the Ant JUnit runner, it's necessary to @Ignore the abstract
+// classes here, or JUnit tries to instantiate them. the annotations
+// can be removed when this is merged forward (TODO 2.12.x)
+
+/**
+ * base class for testing common methods on a various implementations
+ *
+ * @tparam T the collection type
+ * @tparam E the element type
+ */
+@RunWith(classOf[JUnit4])
+@Ignore
+abstract class IndexedTest[T, E] {
+
+ protected def size = 10
+
+ /**
+ * create a new instance of the test data with known values
+ */
+ protected def underTest(size: Int): T
+
+ /**
+ * returns the value of the data that is expected to be present int the original data at index {{{index}}}
+ * This is conceptully the same as the normal apply operation but unavaialbe due to the base types of T not supporting apply
+ *
+ * @param index the index to use for the returned value
+ * @return the value at the specified index
+ */
+ protected def expectedValueAtIndex(index: Int): E
+ /**
+ * check some simple indexed access
+ */
+ @Test def checkIndexedAccess: Unit = {
+ val test = underTest(size)
+ for (i <- 0 until size) {
+ assertEquals(s" at index $i", expectedValueAtIndex(i), get(test, i))
+ }
+ }
+
+ /**
+ * check simple equallity of the initial data.
+ * More a test of the infra that we use in this est than a full test of equallity
+ */
+ @Test def checkEquals: Unit = {
+ val test1 = underTest(size)
+ val test2 = underTest(size)
+ doAssertEquals("", test1, test2)
+ assertNotSame(test1, test2)
+ expectSameContent("basic equallity", false, test1, test2, 0, size)
+ }
+
+ protected def expectSameContent(txt: String, canBeSame:Boolean, orig: T, test: T, offset: Int, len: Int): Unit = {
+ val txtAndState = s"$txt canBeSame $canBeSame isMutableContent $isMutableContent isTakeAllSame $isTakeAllSame offset $offset len $len length(test) ${length(test)}"
+ val isValidSame = canBeSame && !isMutableContent && offset == 0 && len == size
+ if (isValidSame && isTakeAllSame)
+ assertSame(txtAndState, orig, test)
+ else
+ assertNotSame(txtAndState, orig, test)
+ assertSame(txtAndState, len, length(test))
+ for (i <- 0 until len) {
+ assertEquals(s" $txtAndState $i $offset $len", expectedValueAtIndex(i + offset), get(test, i))
+ }
+ }
+
+ /**
+ * check the operation of {{{take}}} when the parameter is less than the size of the test data
+ */
+ @Test def checkTakeNormal: Unit = {
+ val orig = underTest(size)
+ for (len <- 0 until size) {
+ val taken = take(orig, len)
+ expectSameContent(s" len $len", true, orig, taken, 0, len)
+ }
+ }
+
+ /**
+ * check the operation of {{{slice}}} within the bounds of the source
+ */
+ @Test def checkSliceNormal: Unit = {
+ val orig = underTest(size)
+ for (
+ from <- 0 until size;
+ to <- from until size) {
+
+ val sliced = slice(orig, from, to)
+ expectSameContent(s"from $from, to $to", true, orig, sliced, from, to - from)
+ }
+ }
+
+ /**
+ * check the operation of {{{take}}} works for size of 0
+ * There is a special case tha for some implementations empty will be a singleton
+ */
+ @Test def checkTakeEmpty: Unit = {
+ val orig = underTest(size)
+ val empty1 = take(orig, 0)
+ val empty2 = take(orig, 0)
+ assertEquals(0, length(empty1))
+ if (isEmptyConstant) assertSame(empty1, empty2)
+ }
+
+ /**
+ * check the operation of {{{slice}}} works for size of 0
+ * There is a special case tha for some implementations empty will be a singleton
+ */
+ @Test def checkSliceEmpty: Unit = {
+ val orig = underTest(size)
+ for (start <- 0 until size) {
+ val empty1 = slice(orig, start, start)
+ val empty2 = slice(orig, start, start)
+ assertEquals(s"start $start", 0, length(empty1))
+ if (isEmptyConstant) assertSame(s"start $start", empty1, empty2)
+ }
+ }
+
+ /**
+ * check the operation of {{{take}}} works for the entire content
+ * There is a special case that for some immutable implementations they can share the result
+ */
+ @Test def checkTakeAll: Unit = {
+ val orig = underTest(size)
+ val all = take(orig, size)
+ assertEquals(size, length(all))
+ expectSameContent("take all", true, orig, all, 0, size)
+ if (isMutableContent)
+ assertNotSame(orig, all)
+ else if (isTakeAllSame)
+ assertSame(orig, all)
+ }
+
+ /**
+ * check the operation of {{{slice}}} works for the entire content
+ * There is a special case that for some immutable implementations they can share the result
+ */
+ @Test def checkSliceAll: Unit = {
+ val orig = underTest(size)
+ val all = slice(orig, 0, size)
+ assertEquals(size, length(all))
+ expectSameContent("", true, orig, all, 0, size)
+ if (isMutableContent)
+ assertNotSame(orig, all)
+ else if (isTakeAllSame)
+ assertSame(orig, all)
+ }
+
+ /**
+ * check that take operates appropriately for negative values
+ * take and slice should be lenient and silently ignore any data outside valid ranges
+ */
+ @Test def checkTakeNeg: Unit = {
+ val orig = underTest(size)
+ val e = take(orig, 0)
+ for (len <- List(-1, -10, -99, Int.MinValue)) {
+ val empty = take(orig, len)
+ assertEquals(s"len $len", 0, length(empty))
+ if (isEmptyConstant) assertSame(s"len $len", e, empty)
+ }
+ }
+
+ /**
+ * check that take operates appropriately for lengths that exceed the input size
+ * take and slice should be lenient and silently ignore any data outside valid ranges
+ */
+ @Test def checkTakeTooBig: Unit = {
+ val orig = underTest(size)
+ val e = take(orig, 0)
+ for (len <- List(size + 1, size + 10, Int.MaxValue)) {
+ val all = take(orig, len)
+ assertEquals(s"len $len", size, length(all))
+ expectSameContent("", true, orig, all, 0, size)
+ }
+ }
+
+ /**
+ * check that slice operates appropriately for negative start point
+ * take and slice should be lenient and silently ignore any data outside valid ranges
+ */
+ @Test def checkSliceFromNeg: Unit = {
+ val orig = underTest(size)
+ for (
+ from <- List(-1, -10, -99, Int.MinValue);
+ to <- List(-1, 0, 1, 5)) {
+ val start = slice(orig, from, to)
+ expectSameContent(s"from $from, to $to", true, orig, start, 0, Math.max(0, to))
+ }
+ }
+
+ /**
+ * check that slice operates appropriately for out of range end values
+ * take and slice should be lenient and silently ignore any data outside valid ranges
+ */
+ @Test def checkSliceToTooBig: Unit = {
+ val orig = underTest(size)
+ for (
+ from <- List(-1, -10, -99, Int.MinValue, 0, 1, 5);
+ to <- List(size + 1, size + 10, Int.MaxValue)) {
+ val start = slice(orig, from, to)
+ val realStart = Math.max(0, from)
+ val realLen = size - realStart
+ expectSameContent(s"from $from, to $to", true, orig, start, realStart, realLen)
+ }
+ }
+
+ /**
+ * check that slice operates appropriately for negative values start and ends too large
+ * take and slice should be lenient and silently ignore any data outside valid ranges
+ */
+ @Test def checkSliceFromNegAndToTooBig: Unit = {
+ val orig = underTest(size)
+ for (
+ from <- List(-1, -10, -99, Int.MinValue);
+ to <- List(size + 1, size + 10, Int.MaxValue)) {
+ val all = slice(orig, from, to)
+ expectSameContent(s"from $from, to $to", true, orig, all, 0, size)
+ }
+ }
+
+ protected def intercept[EX <: Exception : Manifest](fn: => Any) {
+ try {
+ val res = fn
+ fail(s"expected exception was not thrown: $res")
+ } catch {
+ case failed: AssertionError => throw failed
+ case e: Exception if manifest[EX].runtimeClass.isAssignableFrom(e.getClass) =>
+ }
+ }
+
+ //accessors
+ //the length of underTest
+ def length(underTest: T): Int
+
+ //the value at index i of underTest
+ def get(underTest: T, i: Int): E
+
+ def slice(underTest: T, from: Int, to: Int): T
+
+ def take(underTest: T, size: Int): T
+
+ //behaviour
+ /** is an empty value the same JVM instance */
+ def isEmptyConstant: Boolean
+
+ /** is a take / slice that results in all the data returned return this
+ * This is only relevant if !isMutableContent
+ */
+ def isTakeAllSame: Boolean
+
+ /** is the content of the collection mutable.
+ * If mutable there is not data sharing allowed by take/slice, if immutable then data sharing is possible
+ * and tested based on isTakeAllSame
+ */
+ def isMutableContent: Boolean
+
+ //helpers
+ //delegate equals check for support arrays
+ def doAssertEquals(txt: String, expected: T, actual: T)
+
+}
+package IndexedTestImpl {
+ import java.lang.reflect.{Array => jlArray}
+ import java.lang.{Boolean => jlBoolean}
+ import java.lang.{Byte => jlByte}
+ import java.lang.{Short => jlShort}
+ import java.lang.{Integer => jlInt}
+ import java.lang.{Long => jlLong}
+ import java.lang.{Float => jlFloat}
+ import java.lang.{Double => jlDouble}
+ import java.lang.{Character => jlChar}
+
+ import scala.collection.immutable.{StringLike, StringOps, WrappedString}
+ import scala.collection.mutable
+ import scala.runtime.BoxedUnit
+ trait DataProvider[E] {
+ protected def expectedValueAtIndex(index: Int): E = {
+ val someNumber = index + jlInt.bitCount(index)
+ toType(someNumber)
+ }
+
+ protected def toType(n: Int): E
+ }
+ trait StringTestData extends DataProvider [String] {
+ def toType(n: Int) = n.toString
+ }
+ trait ByteTestData extends DataProvider [Byte] {
+ def toType(n: Int) = n.toByte
+ }
+ trait ShortTestData extends DataProvider [Short] {
+ def toType(n: Int) = n.toShort
+ }
+ trait IntTestData extends DataProvider [Int] {
+ def toType(n: Int) = n
+ }
+ trait LongTestData extends DataProvider [Long] {
+ def toType(n: Int) = n
+ }
+ trait FloatTestData extends DataProvider [Float] {
+ def toType(n: Int) = n
+ }
+ trait DoubleTestData extends DataProvider [Double] {
+ def toType(n: Int) = n
+ }
+ trait CharTestData extends DataProvider [Char] {
+ def toType(n: Int)= (n+64).toChar
+ }
+ trait BooleanTestData extends DataProvider [Boolean] {
+ def toType(n: Int)= (n & 0) == 0
+ }
+ trait UnitTestData extends DataProvider [BoxedUnit] {
+ def toType(n: Int)= if ((n & 0) == 0) null else BoxedUnit.UNIT
+ }
+
+ @Ignore
+ abstract class ArrayTest[E] (
+ //the object or primitive type of the array
+ val TYPE: Class[_]) extends IndexedTest[Array[E], E]{
+ override final def length(underTest: Array[E]) = underTest.length
+
+ override def get(underTest: Array[E], i: Int) = underTest(i)
+
+ override def slice(underTest: Array[E], from: Int, to: Int) = underTest.slice(from, to)
+
+ override def take(underTest: Array[E], size: Int) = underTest.take(size)
+
+ override def isEmptyConstant = false
+
+ override def isMutableContent = true
+
+ override def isTakeAllSame = false
+
+ override def doAssertEquals(txt: String, expected: Array[E], actual: Array[E]): Unit = {
+ assertEquals(txt, expected.mkString("'"), actual.mkString("'"))
+ }
+
+ override def underTest(size: Int): Array[E] = {
+ val res = jlArray.newInstance(TYPE, size)
+ for (i <- 0 until size) {
+ jlArray.set(res, i, expectedValueAtIndex(i))
+ }
+ res.asInstanceOf[Array[E]]
+ }
+ }
+
+
+ @Ignore
+ abstract class WrappedArrayTest[E](
+ //the object or primitive type of the array
+ val TYPE: Class[_]) extends IndexedTest[mutable.WrappedArray[E], E] with DataProvider[E]{
+ import mutable.WrappedArray
+ override final def length(underTest: WrappedArray[E]) = underTest.length
+
+ override def get(underTest: WrappedArray[E], i: Int) = underTest(i)
+
+ override def slice(underTest: WrappedArray[E], from: Int, to: Int) = underTest.slice(from, to)
+
+ override def take(underTest: WrappedArray[E], size: Int) = underTest.take(size)
+
+ override def isEmptyConstant = false
+
+ override def isMutableContent = true
+
+ override def isTakeAllSame = false
+
+ override def doAssertEquals(txt: String, expected: WrappedArray[E], actual: WrappedArray[E]): Unit = {
+ assertEquals(txt, expected.mkString("'"), actual.mkString("'"))
+ }
+
+ override def underTest(size: Int): WrappedArray[E] = {
+ val res = jlArray.newInstance(TYPE, size)
+ for (i <- 0 until size) {
+ jlArray.set(res, i, expectedValueAtIndex(i))
+ }
+ WrappedArray.make(res.asInstanceOf[Array[E]])
+ }
+ }
+
+ //construct the data using java as much as possible to avoid invalidating the test
+
+ @Ignore
+ abstract class MutableIndexedSeqTest[T <: mutable.Seq[E], E] extends IndexedTest[T, E] with DataProvider[E]{
+ override final def length(underTest: T) = underTest.length
+
+ override def get(underTest: T, i: Int) = underTest(i)
+
+ override def slice(underTest: T, from: Int, to: Int) = underTest.slice(from, to).asInstanceOf[T]
+
+ override def take(underTest: T, size: Int) = underTest.take(size).asInstanceOf[T]
+
+ override def isEmptyConstant = false
+
+ override def isMutableContent = true
+
+ override def isTakeAllSame = true
+
+ override def doAssertEquals(txt: String, expected: T, actual: T): Unit = {
+ assertEquals(txt, expected, actual)
+ }
+
+ def createEmpty(size: Int) : T
+
+ override protected def underTest(size: Int): T = {
+ val res:T = createEmpty(size)
+ for (i <- 0 until size)
+ res(i) = expectedValueAtIndex(i)
+ res
+ }
+
+ }
+ @Ignore
+ abstract class ImmutableIndexedSeqTest[T <: SeqLike[E, T], E] extends IndexedTest[T, E] with DataProvider[E] {
+ override final def length(underTest: T) = underTest.length
+
+ override def get(underTest: T, i: Int) = underTest(i)
+
+ override def slice(underTest: T, from: Int, to: Int) = underTest.slice(from, to)
+
+ override def take(underTest: T, size: Int) = underTest.take(size)
+
+ override def isEmptyConstant = false
+
+ override def isMutableContent = false
+
+ override def isTakeAllSame = true
+
+ override def doAssertEquals(txt: String, expected: T, actual: T): Unit = {
+ assertEquals(txt, expected, actual)
+ }
+
+ }
+ @Ignore
+ abstract class StringOpsBaseTest extends IndexedTest[StringOps, Char] with DataProvider[Char] {
+ override final def length(underTest: StringOps) = underTest.length
+
+ override def get(underTest: StringOps, i: Int) = underTest(i)
+
+ override def slice(underTest: StringOps, from: Int, to: Int) = underTest.slice(from, to)
+
+ override def take(underTest: StringOps, size: Int) = underTest.take(size)
+
+ override def isEmptyConstant = false
+
+ override def isMutableContent = false
+
+ override def isTakeAllSame = false
+
+ override def doAssertEquals(txt: String, expected: StringOps, actual: StringOps): Unit = {
+ assertEquals(txt, expected, actual)
+ }
+
+ }
+
+ class BooleanArrayTest extends ArrayTest[Boolean](jlBoolean.TYPE) with BooleanTestData
+ class ByteArrayTest extends ArrayTest[Byte](jlByte.TYPE) with ByteTestData
+ class ShortArrayTest extends ArrayTest[Short](jlShort.TYPE) with ShortTestData
+ class IntArrayTest extends ArrayTest[Int](jlInt.TYPE) with IntTestData
+ class LongArrayTest extends ArrayTest[Long](jlLong.TYPE) with LongTestData
+ class DoubleArrayTest extends ArrayTest[Double](jlDouble.TYPE) with DoubleTestData
+ class FloatArrayTest extends ArrayTest[Float](jlFloat.TYPE) with FloatTestData
+ class CharArrayTest extends ArrayTest[Char](jlChar.TYPE) with CharTestData
+ class UnitArrayTest extends ArrayTest[BoxedUnit](null) with UnitTestData {
+ override def underTest(size: Int): Array[BoxedUnit] = {
+ val res = new Array[Unit](size)
+ for (i <- 0 until size) {
+ jlArray.set(res, i, expectedValueAtIndex(i))
+ }
+ res.asInstanceOf[Array[BoxedUnit]]
+ }
+ }
+ class RefArrayTest extends ArrayTest[String](classOf[String]) with StringTestData
+
+ class BooleanWrappedArrayTest extends WrappedArrayTest[Boolean](jlBoolean.TYPE) with BooleanTestData
+ class ByteWrappedArrayTest extends WrappedArrayTest[Byte](jlByte.TYPE) with ByteTestData
+ class ShortWrappedArrayTest extends WrappedArrayTest[Short](jlShort.TYPE) with ShortTestData
+ class IntWrappedArrayTest extends WrappedArrayTest[Int](jlInt.TYPE) with IntTestData
+ class LongWrappedArrayTest extends WrappedArrayTest[Long](jlLong.TYPE) with LongTestData
+ class DoubleWrappedArrayTest extends WrappedArrayTest[Double](jlDouble.TYPE) with DoubleTestData
+ class FloatWrappedArrayTest extends WrappedArrayTest[Float](jlFloat.TYPE) with FloatTestData
+ class CharWrappedArrayTest extends WrappedArrayTest[Char](jlChar.TYPE) with CharTestData
+ class UnitWrappedArrayTest extends WrappedArrayTest[BoxedUnit](null) with UnitTestData {
+ import mutable.WrappedArray
+ override def underTest(size: Int): WrappedArray[BoxedUnit] = {
+ val res = new Array[Unit](size)
+ for (i <- 0 until size) {
+ jlArray.set(res, i, expectedValueAtIndex(i))
+ }
+ WrappedArray.make(res.asInstanceOf[Array[Unit]])
+ }
+ }
+ class RefWrappedArrayTest extends WrappedArrayTest[String](classOf[String]) with StringTestData
+
+ class ListBufferTest extends MutableIndexedSeqTest[mutable.ListBuffer[String], String] with StringTestData {
+ import mutable.ListBuffer
+ override def createEmpty(size: Int): ListBuffer[String] = {
+ val res = new ListBuffer[String]
+ for (i <- 0 until size)
+ res += expectedValueAtIndex(i)
+ res
+ }
+ }
+ class ArraySeqTest extends MutableIndexedSeqTest[mutable.ArraySeq[String], String] with StringTestData {
+ import mutable.ArraySeq
+ override def createEmpty(size: Int): ArraySeq[String] = {
+ val res = new ArraySeq[String](size)
+ for (i <- 0 until size)
+ res (i) = expectedValueAtIndex(i)
+ res
+ }
+ }
+ class ArrayBufferTest extends MutableIndexedSeqTest[mutable.ArrayBuffer[String], String] with StringTestData {
+ import mutable.ArrayBuffer
+ override def createEmpty(size: Int): ArrayBuffer[String] = {
+ val res = new ArrayBuffer[String](size)
+ for (i <- 0 until size)
+ res += expectedValueAtIndex(i)
+ res
+ }
+ }
+ class ListTest extends ImmutableIndexedSeqTest[List[String], String] with StringTestData {
+
+ override protected def underTest(size: Int): List[String] = {
+ var res:List[String] = Nil
+ var index = size-1
+ while (index >= 0) {
+ res = expectedValueAtIndex(index) :: res
+ index -= 1
+ }
+ res
+ }
+ }
+ class StringBuilderTest extends MutableIndexedSeqTest[StringBuilder, Char] with CharTestData {
+
+ override def createEmpty(size: Int): StringBuilder = new StringBuilder(size)
+
+ override protected def underTest(size: Int): StringBuilder = {
+ var res = createEmpty(size)
+ for (i <- 0 until size)
+ res += expectedValueAtIndex(i)
+ res
+ }
+ }
+ class StringOpsTest extends StringOpsBaseTest with CharTestData {
+
+ override protected def underTest(size: Int): StringOps = {
+ var res = new StringBuilder(size)
+ for (i <- 0 until size)
+ res += expectedValueAtIndex(i)
+ res.toString
+ }
+ }
+ class WrappedStringTest extends ImmutableIndexedSeqTest[WrappedString, Char] with CharTestData {
+
+ override def isTakeAllSame: Boolean = false
+
+ override protected def underTest(size: Int): WrappedString = {
+ var res = new StringBuilder(size)
+ for (i <- 0 until size)
+ res += expectedValueAtIndex(i)
+ new WrappedString(res.toString)
+ }
+ }
+ class VectorTest extends ImmutableIndexedSeqTest[Vector[String], String] with StringTestData {
+
+ override protected def underTest(size: Int): Vector[String] = {
+ var res = Vector.newBuilder[String]
+ for (i <- 0 until size)
+ res += expectedValueAtIndex(i)
+ res.result()
+ }
+ }
+
+}
diff --git a/test/junit/scala/reflect/internal/NamesTest.scala b/test/junit/scala/reflect/internal/NamesTest.scala
index 549c10abed..d6182e7cca 100644
--- a/test/junit/scala/reflect/internal/NamesTest.scala
+++ b/test/junit/scala/reflect/internal/NamesTest.scala
@@ -92,4 +92,29 @@ class NamesTest {
assert(h1 string_== h2)
assert(h1 string_== h1y)
}
+
+ @Test
+ def pos(): Unit = {
+ def check(nameString: String, sub: String) = {
+ val name = TermName(nameString)
+ val javaResult = name.toString.indexOf(sub) match { case -1 => name.length case x => x }
+ val nameResult = name.pos(sub)
+ assertEquals(javaResult, nameResult)
+ if (sub.length == 1) {
+ val nameResultChar = name.pos(sub.head)
+ assertEquals(javaResult, nameResultChar)
+ }
+ }
+
+ check("a", "a") // was "String index out of range: 1
+ check("a", "b")
+ check("a", "ab")
+ check("a", "ba")
+ check("ab", "a")
+ check("ab", "b")
+ check("ab", "ab")
+ check("ab", "ba")
+ check("", "x")
+ check("", "xy")
+ }
}
diff --git a/test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala b/test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala
new file mode 100644
index 0000000000..2c3c5134da
--- /dev/null
+++ b/test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 Contributor. All rights reserved.
+ */
+package scala.tools.nsc.classpath
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.tools.nsc.Settings
+import scala.tools.nsc.backend.jvm.AsmUtils
+import scala.tools.nsc.util.ClassPath
+import scala.tools.util.PathResolver
+
+@RunWith(classOf[JUnit4])
+class JrtClassPathTest {
+
+ @Test def lookupJavaClasses(): Unit = {
+ val specVersion = scala.util.Properties.javaSpecVersion
+ // Run the test using the JDK8 or 9 provider for rt.jar depending on the platform the test is running on.
+ val cp: ClassPath =
+ if (specVersion == "" || specVersion == "1.8") {
+ val settings = new Settings()
+ val resolver = new PathResolver(settings)
+ val elements = new ClassPathFactory(settings).classesInPath(resolver.Calculated.javaBootClassPath)
+ AggregateClassPath(elements)
+ }
+ else JrtClassPath().get
+
+ assertEquals(Nil, cp.classes(""))
+ assertTrue(cp.packages("java").toString, cp.packages("java").exists(_.name == "java.lang"))
+ assertTrue(cp.classes("java.lang").exists(_.name == "Object"))
+ val jl_Object = cp.classes("java.lang").find(_.name == "Object").get
+ assertEquals("java/lang/Object", AsmUtils.classFromBytes(jl_Object.file.toByteArray).name)
+ assertTrue(cp.list("java.lang").packages.exists(_.name == "java.lang.annotation"))
+ assertTrue(cp.list("java.lang").classesAndSources.exists(_.name == "Object"))
+ assertTrue(cp.findClass("java.lang.Object").isDefined)
+ assertTrue(cp.findClassFile("java.lang.Object").isDefined)
+ }
+}
diff --git a/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala b/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala
index 01d17110d6..e9f1336623 100644
--- a/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala
+++ b/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala
@@ -96,7 +96,7 @@ class ScriptedTest {
}
@Test def `on compile error`(): Unit = {
val engine = scripted
- val err = "not found: value foo in def f = foo at line number 11 at column number 16"
+ val err = "not found: value foo in def f = foo at line number 11 at column number 9"
assertThrows[ScriptException](engine.compile("def f = foo"), _ == err)
}
}
diff --git a/test/scalacheck/duration.scala b/test/scalacheck/duration.scala
index 89cb9ff955..fc861b886a 100644
--- a/test/scalacheck/duration.scala
+++ b/test/scalacheck/duration.scala
@@ -32,7 +32,10 @@ object DurationTest extends Properties("Division of Duration by Long") {
val genClose = for {
a <- weightedLong
if a != 0
- b <- choose(Long.MaxValue / a - 10, Long.MaxValue / a + 10)
+ val center = Long.MaxValue / a
+ b <-
+ if (center - 10 < center + 10) choose(center - 10, center + 10)
+ else choose(center + 10, center - 10) // deal with overflow if abs(a) == 1
} yield (a, b)
val genBorderline =
diff --git a/versions.properties b/versions.properties
index 26e8324c44..f767dfab7b 100644
--- a/versions.properties
+++ b/versions.properties
@@ -21,7 +21,7 @@ scala-swing.version.number=2.0.0
scala-swing.version.osgi=2.0.0
jline.version=2.14.3
# this one is shaded and embedded in scala-compiler.jar
-scala-asm.version=5.1.0-scala-1
+scala-asm.version=5.1.0-scala-2
# external modules, used internally (not shipped)
partest.version.number=1.1.0