summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes30
-rw-r--r--.travis.yml5
-rw-r--r--CONTRIBUTING.md91
-rw-r--r--Gemfile2
-rw-r--r--README.md111
-rw-r--r--bincompat-backward.whitelist.conf9
-rw-r--r--bincompat-forward.whitelist.conf9
-rw-r--r--build.sbt10
-rw-r--r--[-rwxr-xr-x]build.xml14
-rw-r--r--doc/LICENSE.md4
-rw-r--r--doc/License.rtf4
-rw-r--r--docs/TODO2
-rw-r--r--project/build.properties2
-rwxr-xr-xscripts/jobs/integrate/bootstrap6
-rw-r--r--spec/01-lexical-syntax.md2
-rw-r--r--spec/05-classes-and-objects.md2
-rw-r--r--spec/06-expressions.md2
-rw-r--r--spec/07-implicits.md2
-rw-r--r--spec/08-pattern-matching.md2
-rw-r--r--spec/12-the-scala-standard-library.md6
-rw-r--r--spec/15-changelog.md4
-rw-r--r--spec/README.md2
-rw-r--r--spec/_config.yml2
-rw-r--r--src/actors/scala/actors/Future.scala2
-rw-r--r--src/compiler/scala/tools/ant/Scalac.scala2
-rwxr-xr-xsrc/compiler/scala/tools/ant/templates/tool-unix.tmpl13
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala5
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala12
-rw-r--r--[-rwxr-xr-x]src/compiler/scala/tools/nsc/ast/DocComments.scala0
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala2
-rw-r--r--[-rwxr-xr-x]src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala0
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala20
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala2
-rw-r--r--[-rwxr-xr-x]src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala0
-rw-r--r--[-rwxr-xr-x]src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala0
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala18
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala34
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala12
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala25
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala9
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala14
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala34
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala24
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala92
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala448
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala71
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/io/Jar.scala2
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala16
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugin.scala4
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala50
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/Logic.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/PatternExpander.scala18
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala50
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Checkable.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala33
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala27
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Tags.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala2
-rw-r--r--[-rwxr-xr-x]src/compiler/scala/tools/nsc/util/DocStrings.scala4
-rw-r--r--src/compiler/scala/tools/reflect/ReflectGlobal.scala16
-rw-r--r--src/eclipse/interactive/.gitignore2
-rw-r--r--src/eclipse/partest/.classpath2
-rw-r--r--src/eclipse/partest/.gitignore2
-rw-r--r--src/eclipse/reflect/.gitignore2
-rw-r--r--src/eclipse/repl/.gitignore2
-rw-r--r--src/eclipse/scala-compiler/.gitignore2
-rw-r--r--src/eclipse/scala-library/.gitignore2
-rw-r--r--src/eclipse/scaladoc/.classpath6
-rw-r--r--src/eclipse/scaladoc/.gitignore2
-rw-r--r--src/eclipse/scalap/.gitignore2
-rw-r--r--src/eclipse/test-junit/.gitignore2
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java2
-rw-r--r--src/intellij/interactive.iml.SAMPLE1
-rw-r--r--src/intellij/repl.iml.SAMPLE1
-rw-r--r--src/intellij/scaladoc.iml.SAMPLE1
-rw-r--r--src/interactive/scala/tools/nsc/interactive/CompilerControl.scala9
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Global.scala125
-rw-r--r--src/library-aux/scala/Any.scala4
-rw-r--r--src/library-aux/scala/AnyRef.scala4
-rw-r--r--src/library/scala/AnyVal.scala4
-rw-r--r--src/library/scala/Equals.scala5
-rw-r--r--src/library/scala/Option.scala2
-rw-r--r--src/library/scala/Predef.scala2
-rw-r--r--src/library/scala/StringContext.scala2
-rw-r--r--src/library/scala/collection/GenSeqLike.scala2
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala23
-rw-r--r--[-rwxr-xr-x]src/library/scala/collection/IndexedSeqOptimized.scala0
-rw-r--r--src/library/scala/collection/Iterator.scala221
-rw-r--r--[-rwxr-xr-x]src/library/scala/collection/JavaConverters.scala0
-rw-r--r--[-rwxr-xr-x]src/library/scala/collection/LinearSeqOptimized.scala8
-rw-r--r--src/library/scala/collection/TraversableLike.scala2
-rw-r--r--src/library/scala/collection/convert/Wrappers.scala41
-rw-r--r--[-rwxr-xr-x]src/library/scala/collection/generic/FilterMonadic.scala0
-rw-r--r--[-rwxr-xr-x]src/library/scala/collection/generic/HasNewBuilder.scala0
-rw-r--r--[-rwxr-xr-x]src/library/scala/collection/immutable/DefaultMap.scala0
-rw-r--r--src/library/scala/collection/immutable/HashSet.scala8
-rw-r--r--src/library/scala/collection/immutable/IntMap.scala2
-rw-r--r--src/library/scala/collection/immutable/List.scala2
-rw-r--r--src/library/scala/collection/immutable/ListSet.scala9
-rw-r--r--src/library/scala/collection/immutable/MapLike.scala5
-rw-r--r--src/library/scala/collection/immutable/NumericRange.scala86
-rw-r--r--src/library/scala/collection/immutable/PagedSeq.scala4
-rw-r--r--src/library/scala/collection/immutable/Range.scala31
-rw-r--r--src/library/scala/collection/immutable/RedBlackTree.scala7
-rw-r--r--src/library/scala/collection/immutable/Set.scala112
-rw-r--r--src/library/scala/collection/immutable/SortedMap.scala6
-rw-r--r--src/library/scala/collection/immutable/Stream.scala6
-rw-r--r--src/library/scala/collection/immutable/StringLike.scala4
-rw-r--r--src/library/scala/collection/immutable/Vector.scala11
-rw-r--r--[-rwxr-xr-x]src/library/scala/collection/mutable/IndexedSeqOptimized.scala0
-rw-r--r--src/library/scala/collection/mutable/PriorityQueue.scala15
-rw-r--r--src/library/scala/collection/mutable/Queue.scala2
-rw-r--r--src/library/scala/collection/package.scala3
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala18
-rw-r--r--[-rwxr-xr-x]src/library/scala/collection/readme-if-you-want-to-add-something.txt0
-rw-r--r--src/library/scala/compat/Platform.scala2
-rw-r--r--src/library/scala/concurrent/Future.scala2
-rw-r--r--src/library/scala/concurrent/SyncVar.scala2
-rw-r--r--src/library/scala/concurrent/impl/AbstractPromise.java37
-rw-r--r--src/library/scala/io/Codec.scala4
-rw-r--r--src/library/scala/math/BigDecimal.scala2
-rw-r--r--src/library/scala/ref/WeakReference.scala5
-rw-r--r--src/library/scala/reflect/ClassManifestDeprecatedApis.scala4
-rw-r--r--src/library/scala/reflect/Manifest.scala4
-rw-r--r--[-rwxr-xr-x]src/library/scala/reflect/NameTransformer.scala0
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala2
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/TraitSetter.java0
-rw-r--r--src/library/scala/runtime/Tuple2Zipped.scala8
-rw-r--r--src/library/scala/runtime/Tuple3Zipped.scala8
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileBooleanRef.java0
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileByteRef.java0
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileCharRef.java0
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileDoubleRef.java0
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileFloatRef.java0
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileIntRef.java0
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileLongRef.java0
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileObjectRef.java0
-rw-r--r--[-rwxr-xr-x]src/library/scala/runtime/VolatileShortRef.java0
-rw-r--r--src/library/scala/sys/process/Process.scala8
-rw-r--r--src/library/scala/sys/process/package.scala3
-rw-r--r--src/library/scala/util/Either.scala12
-rw-r--r--src/library/scala/util/Properties.scala4
-rw-r--r--src/library/scala/util/Sorting.scala2
-rw-r--r--src/library/scala/util/control/Exception.scala2
-rw-r--r--src/manual/scala/man1/Command.scala2
-rw-r--r--src/partest-extras/scala/tools/partest/ASMConverters.scala78
-rw-r--r--src/partest-extras/scala/tools/partest/IcodeComparison.scala9
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala2
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala2
-rw-r--r--src/reflect/scala/reflect/api/Types.scala2
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala2
-rw-r--r--src/reflect/scala/reflect/internal/ClassfileConstants.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala2
-rw-r--r--src/reflect/scala/reflect/internal/FlagSets.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala155
-rw-r--r--src/reflect/scala/reflect/internal/HasFlags.scala83
-rw-r--r--src/reflect/scala/reflect/internal/Kinds.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala9
-rw-r--r--src/reflect/scala/reflect/internal/SymbolPairs.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala24
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala7
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala9
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala6
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala4
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala2
-rw-r--r--src/reflect/scala/reflect/internal/transform/UnCurry.scala22
-rw-r--r--src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala2
-rw-r--r--src/reflect/scala/reflect/io/Streamable.scala8
-rw-r--r--src/reflect/scala/reflect/macros/blackbox/Context.scala2
-rw-r--r--src/reflect/scala/reflect/macros/package.scala4
-rw-r--r--src/reflect/scala/reflect/macros/whitebox/Context.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala7
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala3
-rw-r--r--src/reflect/scala/reflect/runtime/TwoWayCache.scala3
-rw-r--r--src/reflect/scala/reflect/runtime/TwoWayCaches.scala3
-rw-r--r--src/repl-jline/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala2
-rw-r--r--src/repl-jline/scala/tools/nsc/interpreter/jline/JLineReader.scala64
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala115
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala55
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Imports.scala39
-rw-r--r--src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala11
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Pasted.scala56
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Power.scala41
-rw-r--r--src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala110
-rw-r--r--src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala139
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala0
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala0
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala0
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala0
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala0
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala0
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala5
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js12
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js0
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css0
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala2
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala0
-rw-r--r--[-rwxr-xr-x]src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala0
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala2
-rw-r--r--src/scalap/decoder.properties2
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala6
-rw-r--r--[-rwxr-xr-x]test/disabled/pos/t1545.scala0
-rw-r--r--[-rwxr-xr-x]test/files/bench/equality/eq.scala0
-rw-r--r--[-rwxr-xr-x]test/files/bench/equality/eqeq.scala0
-rw-r--r--test/files/filters1
-rw-r--r--test/files/jvm/innerClassAttribute/Test.scala4
-rw-r--r--test/files/jvm/interpreter.check6
-rw-r--r--test/files/jvm/throws-annot-from-java.check8
-rw-r--r--test/files/neg/name-lookup-stable.check2
-rw-r--r--test/files/neg/name-lookup-stable.scala2
-rw-r--r--[-rwxr-xr-x]test/files/neg/override.scala0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t2336.scala0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t2494.scala0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t2773.scala0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t2779.scala0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t2870.scala0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t2918.scala0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t3006.scala0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t3224.scala0
-rw-r--r--test/files/neg/t4425b.check22
-rw-r--r--test/files/neg/t5376.scala2
-rw-r--r--test/files/neg/t6013/Base.java2
-rw-r--r--[-rwxr-xr-x]test/files/neg/t6446-additional.check0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t6446-list.check0
-rw-r--r--[-rwxr-xr-x]test/files/neg/t6446-missing.check0
-rw-r--r--test/files/neg/t6666d.check4
-rw-r--r--test/files/neg/t7214neg.scala2
-rw-r--r--[-rwxr-xr-x]test/files/neg/t771.scala0
-rw-r--r--test/files/neg/t8127a.check4
-rw-r--r--test/files/neg/t8127a.scala12
-rw-r--r--test/files/neg/t8597b.scala2
-rw-r--r--test/files/neg/t8675b.scala2
-rw-r--r--test/files/neg/t8989.check4
-rw-r--r--test/files/neg/t8989.scala14
-rw-r--r--test/files/neg/t9401.check4
-rw-r--r--test/files/neg/t9401.scala4
-rw-r--r--test/files/neg/virtpatmat_exhaust_compound.scala2
-rw-r--r--[-rwxr-xr-x]test/files/pos/lexical.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/packageobjs.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/spec-t6286.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t1459/AbstractBase.java0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t1459/App.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t1459/Caller.java0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t1722/Test.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t1722/Top.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t1756.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2060.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2082.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2179.scala0
-rw-r--r--test/files/pos/t2405.scala4
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2425.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2429.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2433/A.java0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2433/B.java0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2433/Test.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2484.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2504.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2545.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2635.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2683.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2913.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t2956/t2956.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t3174.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t3174b.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t3568.scala0
-rw-r--r--[-rwxr-xr-x]test/files/pos/t4553.scala0
-rw-r--r--test/files/pos/t6089b.scala2
-rw-r--r--test/files/pos/t6666d.scala (renamed from test/files/neg/t6666d.scala)0
-rw-r--r--test/files/pos/t7689.scala2
-rw-r--r--test/files/pos/t8002-nested-scope.scala2
-rw-r--r--test/files/pos/t9369.flags1
-rw-r--r--test/files/pos/t9369.scala24
-rw-r--r--test/files/pos/t9370/ThePlugin.scala31
-rw-r--r--test/files/pos/t9370/sample_2.flags1
-rw-r--r--test/files/pos/t9370/sample_2.scala6
-rw-r--r--test/files/pos/t9370/scalac-plugin.xml5
-rw-r--r--test/files/pos/t9392/client_2.scala4
-rw-r--r--test/files/pos/t9392/macro_1.scala16
-rw-r--r--test/files/pos/t9393/NamedImpl_1.java15
-rw-r--r--test/files/pos/t9393/NamedImpl_2.java15
-rw-r--r--test/files/pos/t9393/Named_1.java3
-rw-r--r--test/files/pos/t9393/Named_2.java3
-rw-r--r--test/files/pos/t9393/test_2.scala4
-rw-r--r--test/files/pos/t9442.scala14
-rw-r--r--test/files/pos/t9475.scala19
-rw-r--r--test/files/presentation/callcc-interpreter.check11
-rw-r--r--[-rwxr-xr-x]test/files/presentation/doc/doc.scala0
-rw-r--r--[-rwxr-xr-x]test/files/presentation/doc/src/Class.scala0
-rw-r--r--[-rwxr-xr-x]test/files/presentation/doc/src/p/Base.scala0
-rw-r--r--[-rwxr-xr-x]test/files/presentation/doc/src/p/Derived.scala0
-rw-r--r--test/files/run/class-symbol-contravariant.check8
-rw-r--r--test/files/run/constant-type.check8
-rw-r--r--test/files/run/constrained-types.check8
-rw-r--r--test/files/run/dead-code-elimination.scala2
-rw-r--r--test/files/run/idempotency-case-classes.check3
-rw-r--r--test/files/run/kind-repl-command.check2
-rw-r--r--[-rwxr-xr-x]test/files/run/list_map.scala0
-rw-r--r--test/files/run/names-defaults.scala2
-rw-r--r--test/files/run/nothingTypeNoOpt.scala2
-rw-r--r--test/files/run/reflection-fieldmirror-ctorparam.check6
-rw-r--r--test/files/run/reify-repl-fail-gracefully.check2
-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-bare-expr.check12
-rw-r--r--test/files/run/repl-parens.check12
-rw-r--r--test/files/run/repl-paste-2.check4
-rw-r--r--test/files/run/repl-power.check11
-rw-r--r--test/files/run/repl-power.scala5
-rw-r--r--test/files/run/repl-reset.check8
-rw-r--r--test/files/run/repl-serialization.check1
-rw-r--r--test/files/run/repl-transcript.check2
-rw-r--r--test/files/run/repl-trim-stack-trace.scala6
-rw-r--r--test/files/run/scalapInvokedynamic.check5
-rw-r--r--test/files/run/scalapInvokedynamic.scala11
-rw-r--r--test/files/run/t1931.scala43
-rw-r--r--[-rwxr-xr-x]test/files/run/t2127.scala2
-rw-r--r--[-rwxr-xr-x]test/files/run/t2503.scala0
-rw-r--r--[-rwxr-xr-x]test/files/run/t3026.scala0
-rw-r--r--test/files/run/t4542.check2
-rw-r--r--test/files/run/t4594-repl-settings.scala2
-rw-r--r--test/files/run/t4658.check7
-rw-r--r--test/files/run/t4658.scala11
-rw-r--r--test/files/run/t5655.check4
-rw-r--r--[-rwxr-xr-x]test/files/run/t5699.check0
-rw-r--r--[-rwxr-xr-x]test/files/run/t5699.scala0
-rw-r--r--[-rwxr-xr-x]test/files/run/t5717.scala0
-rw-r--r--test/files/run/t6146b.check8
-rw-r--r--test/files/run/t6439.check8
-rw-r--r--test/files/run/t720.scala48
-rw-r--r--test/files/run/t7214.scala2
-rw-r--r--[-rwxr-xr-x]test/files/run/t7246.check0
-rw-r--r--[-rwxr-xr-x]test/files/run/t7246/Outer.java0
-rw-r--r--[-rwxr-xr-x]test/files/run/t7246/Test.scala0
-rw-r--r--[-rwxr-xr-x]test/files/run/t7246b.check0
-rw-r--r--[-rwxr-xr-x]test/files/run/t7246b/Base.scala0
-rw-r--r--[-rwxr-xr-x]test/files/run/t7246b/Outer.java0
-rw-r--r--[-rwxr-xr-x]test/files/run/t7246b/Test.scala0
-rw-r--r--test/files/run/t7319.check6
-rw-r--r--[-rwxr-xr-x]test/files/run/t7341.flags0
-rw-r--r--[-rwxr-xr-x]test/files/run/t7341.scala0
-rw-r--r--test/files/run/t7747-repl.check40
-rw-r--r--test/files/run/t7850c.scala11
-rw-r--r--test/files/run/t7850d.scala17
-rw-r--r--test/files/run/t8047.scala2
-rw-r--r--test/files/run/t8346.check6
-rw-r--r--test/files/run/t8346.scala34
-rw-r--r--test/files/run/t8502b.scala46
-rw-r--r--test/files/run/t9029.flags1
-rw-r--r--test/files/run/t9029.scala15
-rw-r--r--test/files/run/t9029b.check1
-rw-r--r--test/files/run/t9029b.scala31
-rw-r--r--test/files/run/t9029c.scala21
-rw-r--r--test/files/run/t9170.scala24
-rw-r--r--test/files/run/t9206.scala4
-rw-r--r--test/files/run/t9365.check2
-rw-r--r--test/files/run/t9365.scala18
-rw-r--r--test/files/run/t9375.check60
-rw-r--r--test/files/run/t9375.scala279
-rw-r--r--test/files/run/t9387.scala20
-rw-r--r--test/files/run/t9387b.check1
-rw-r--r--test/files/run/t9387b.scala16
-rw-r--r--test/files/run/t9388-bin-compat.scala16
-rw-r--r--test/files/run/t9403.flags1
-rw-r--r--test/files/run/t9403/C_1.scala5
-rw-r--r--test/files/run/t9403/Test_2.scala29
-rw-r--r--test/files/run/t9422.scala11
-rw-r--r--test/files/run/t9425.scala8
-rw-r--r--test/files/run/test-cpp.scala2
-rw-r--r--test/files/run/toolbox_expand_macro.check1
-rw-r--r--test/files/run/toolbox_expand_macro.scala23
-rw-r--r--test/files/run/tpeCache-tyconCache.check8
-rw-r--r--[-rwxr-xr-x]test/files/run/viewtest.scala0
-rw-r--r--[-rwxr-xr-x]test/files/run/weakconform.scala0
-rw-r--r--test/files/run/xMigration.check6
-rw-r--r--test/files/scalacheck/range.scala17
-rw-r--r--test/junit/scala/collection/immutable/PagedSeqTest.scala6
-rw-r--r--test/junit/scala/collection/immutable/RangeConsistencyTest.scala24
-rw-r--r--test/junit/scala/collection/immutable/SetTests.scala81
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala44
-rw-r--r--test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala2
-rw-r--r--test/junit/scala/tools/nsc/interpreter/CompletionTest.scala180
-rw-r--r--test/junit/scala/tools/nsc/symtab/FlagsTest.scala89
-rwxr-xr-xtest/partest1
-rwxr-xr-xtest/partest.bat104
-rw-r--r--[-rwxr-xr-x]test/pending/run/t3609.scala0
-rw-r--r--test/scaladoc/filters1
-rw-r--r--test/scaladoc/resources/doc-root/AnyRef.scala4
-rw-r--r--[-rwxr-xr-x]test/scaladoc/run/SI-191.check0
-rw-r--r--[-rwxr-xr-x]test/scaladoc/run/SI-191.scala0
-rw-r--r--[-rwxr-xr-x]test/scaladoc/run/SI-7367.check0
-rw-r--r--[-rwxr-xr-x]test/scaladoc/run/SI-7367.scala0
-rw-r--r--[-rwxr-xr-x]test/scaladoc/run/SI-8479.scala0
-rw-r--r--[-rwxr-xr-x]test/script-tests/README0
-rw-r--r--versions.properties6
429 files changed, 3955 insertions, 1526 deletions
diff --git a/.gitattributes b/.gitattributes
index ac98781b3d..da4421cb78 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2,20 +2,24 @@
# this must be first so later entries will override it
* text=auto
+# check out text files with lf, not crlf, on Windows. (especially
+# important for Scala source files, since """ preserves line endings)
+text eol=lf
+
# These files are text and should be normalized (convert crlf => lf)
-*.c text
-*.check text
-*.css text
-*.flags text
-*.html text
-*.java text
-*.js text
-*.policy text
-*.sbt text
-*.scala text
-*.sh text
-*.txt text
-*.xml text
+*.c eol=lf
+*.check eol=lf
+*.css eol=lf
+*.flags eol=lf
+*.html eol=lf
+*.java eol=lf
+*.js eol=lf
+*.policy eol=lf
+*.sbt eol=lf
+*.scala eol=lf
+*.sh eol=lf
+*.txt eol=lf
+*.xml eol=lf
# Windows-specific files get windows endings
*.bat eol=crlf
diff --git a/.travis.yml b/.travis.yml
index 6a7ac45e3d..236e002a5e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,6 @@
+# opt-in to Travis's newer/faster container-based infrastructure
+sudo: false
+
# this builds the spec using jekyll
# based on http://www.paperplanes.de/2013/8/13/deploying-your-jekyll-blog-to-s3-with-travis-ci.html
language: ruby
@@ -17,4 +20,4 @@ after_success:
- openssl aes-256-cbc -pass "pass:$PRIV_KEY_SECRET" -in spec/id_dsa_travis.enc -out spec/id_dsa_travis -d -a
- chmod 600 spec/id_dsa_travis
- eval "$(ssh-agent)"
- - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && ssh-add -D && ssh-add spec/id_dsa_travis && rsync -e "ssh -o StrictHostKeyChecking=no" -rzv build/spec/ scalatest@chara.epfl.ch:/home/linuxsoft/archives/scala/spec/2.11/' \ No newline at end of file
+ - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && ssh-add -D && ssh-add spec/id_dsa_travis && rsync -e "ssh -o StrictHostKeyChecking=no" -rzv build/spec/ scalatest@chara.epfl.ch:/home/linuxsoft/archives/scala/spec/2.11/'
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 54334aea48..d01a71b9bd 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -38,18 +38,93 @@ Please make sure the JIRA ticket's fix version corresponds to the upcoming miles
#### Enhancement or New Feature
-For longer-running development, likely required for this category of code contributions, we suggest you include "topic" or "wip" in your branch name, to indicate that this is work in progress, and that others should be prepared to rebase if they branch off your branch.
+For longer-running development, likely required for this category of code contributions, we suggest you include "topic/" or "wip/" in your branch name, to indicate that this is work in progress, and that others should be prepared to rebase if they branch off your branch.
Any language change (including bug fixes) must be accompanied by the relevant updates to the spec, which lives in the same repository for this reason.
A new language feature requires a SIP (Scala Improvement Process) proposal. For more details on submitting SIPs, see [how to submit a SIP](http://docs.scala-lang.org/sips/sip-submission.html).
-#### Summary
+## Guidelines
-1. We require regression tests for bug fixes. New features and enhancements must be supported by a respectable test suite.
-2. Documentation. Yep! Also required :-)
-3. Please follow these standard code standards, though in moderation (scouts quickly learn to let sleeping dogs lie):
- - Not violate [DRY](http://programmer.97things.oreilly.com/wiki/index.php/Don%27t_Repeat_Yourself).
- - [Boy Scout Rule](http://programmer.97things.oreilly.com/wiki/index.php/The_Boy_Scout_Rule) should be applied.
+Here is some advice on how to craft a pull request with the best possible
+chance of being accepted.
-Please also have a look at our [Pull Request Policy](https://github.com/scala/scala/wiki/Pull-Request-Policy), as well as the [Scala Hacker Guide](http://www.scala-lang.org/contribute/hacker-guide.html) by @xeno-by.
+### Tests
+
+Bug fixes should include regression tests -- in the same commit as the fix.
+
+If testing isn't feasible, the commit message should explain why.
+
+New features and enhancements must be supported by a respectable test suite.
+
+Some characteristics of good tests:
+
+* includes comments: what is being tested and why?
+* be minimal, deterministic, stable (unaffected by irrelevant changes), easy to understand and review
+* have minimal dependencies: a compiler bug test should not depend on, e.g., the Scala library
+
+### Documentation
+
+This is of course required for new features and enhancements.
+
+Any API additions should include Scaladoc.
+
+Consider updating the package-level doc (in the package object), if appropriate.
+
+### Coding standards
+
+Please follow these standard code standards, though in moderation (scouts quickly learn to let sleeping dogs lie):
+
+* Don't violate [DRY](http://programmer.97things.oreilly.com/wiki/index.php/Don%27t_Repeat_Yourself).
+* Follow the [Boy Scout Rule](http://programmer.97things.oreilly.com/wiki/index.php/The_Boy_Scout_Rule).
+
+Please also have a look at the [Scala Hacker Guide](http://www.scala-lang.org/contribute/hacker-guide.html) by @xeno-by.
+
+### Clean commits, clean history
+
+A pull request should consist of commits with messages that clearly state what problem the commit resolves and how.
+
+Commit logs should be stated in the active, present tense.
+
+A commit's subject should be 72 characters or less. Overall, think of
+the first line of the commit as a description of the action performed
+by the commit on the code base, so use the active voice and the
+present tense. That also makes the commit subjects easy to reuse in
+release notes.
+
+For a bugfix, the title must look like "SI-NNNN - don't crash when
+moon is in wrong phase".
+
+If a commit purely refactors and is not intended to change behaviour,
+say so.
+
+Backports should be tagged as "[backport]".
+
+When working on maintenance branches (e.g., 2.11.x), include "[nomerge]"
+if this commit should not be merged forward into the next release
+branch.
+
+Here is standard advice on good commit messages:
+http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+
+### Pass Scabot
+
+Our pull request bot, Scabot, automatically builds all the commits in a PR individually. (All, so we can `git bisect` later.)
+
+Click on the little x next to a commit sha to go to the overview of the PR validation job. To diagnose a failure, consult the console output of the job that failed.
+
+See the [scala-jenkins-infra repo](https://github.com/scala/scala-jenkins-infra) and [Scabot repo](https://github.com/scala/scabot) for full details on PR validation. One tip you should know is that commenting `/rebuild` on a PR asks validation to be run again on the same commits. This is only necessary when a spurious failure occurred.
+
+### Pass code review
+
+Your PR will need to be assigned to one or more reviewers. You can suggest reviewers yourself; if you're not sure, see the list in [README.md](README.md) or ask on scala-internals.
+
+To assign a reviewer, add a "review by @reviewer" to your PR description.
+
+NOTE: it's best not to @mention in commit messages, as github pings you every time a commit with your @name on it shuffles through the system (even in other repos, on merges,...).
+
+A reviewer gives the green light by commenting "LGTM" (looks good to me).
+
+A review feedback may be addressed by pushing new commits to the request, if these commits stand on their own.
+
+Once all these conditions are met, and we agree with the change (we are available on scala-internals to discuss this beforehand, before you put in the coding work!), we will merge your changes.
diff --git a/Gemfile b/Gemfile
index b74696e550..c8c926dfde 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,4 +4,4 @@ source "https://rubygems.org"
gem "jekyll", "2.5.3"
gem "rouge"
# gem 's3_website'
-gem "redcarpet", "3.2.3"
+gem "redcarpet", "3.3.2"
diff --git a/README.md b/README.md
index e722c88e41..c8f3f206c4 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,18 @@
# Welcome!
This is the official repository for the [Scala Programming Language](http://www.scala-lang.org).
+# How to contribute
+
To contribute to the Scala Standard Library, Scala Compiler and Scala Language Specification, please send us a [pull request](https://help.github.com/articles/using-pull-requests/#fork--pull) from your fork of this repository! We do have to ask you to sign the [Scala CLA](http://typesafe.com/contribute/cla/scala) before we can merge any of your work into our code base, to protect its open source nature.
-For more information on building and developing the core of Scala, read on! Please also check out our [guidelines for contributing](CONTRIBUTING.md).
+For more information on building and developing the core of Scala, read on!
+
+Please also check out:
+
+* our [guidelines for contributing](CONTRIBUTING.md).
+* the ["Scala Hacker Guide"](http://scala-lang.org/contribute/hacker-guide.html) covers some of the same ground as this README, but in greater detail and in a more tutorial style, using a running example.
+
+# Reporting issues
We're still using Jira for issue reporting, so please [report any issues](https://issues.scala-lang.org) over there.
(We would love to start using GitHub Issues, but we're too resource-constrained to take on this migration right now.)
@@ -13,23 +22,26 @@ If you need some help with your PR at any time, please feel free to @-mention an
| username | talk to me about... |
--------------------------------------------------------------------------------------------------|----------------------------------------------------------------|---------------------------------------------------|
- <img src="https://avatars.githubusercontent.com/adriaanm" height="50px" title="Adriaan Moors"/> | [`@adriaanm`](https://github.com/adriaanm) | how we can help // type checker, pattern matcher, infrastructure |
- <img src="https://avatars.githubusercontent.com/SethTisue" height="50px" title="Seth Tisue"/> | [`@SethTisue`](https://github.com/SethTisue) | back-end, library, improving the *welcome to Scala* experience |
- <img src="https://avatars.githubusercontent.com/retronym" height="50px" title="Jason Zaugg"/> | [`@retronym`](https://github.com/retronym) | Java 8 lambdas, tricky bug detective work |
- <img src="https://avatars.githubusercontent.com/Ichoran" height="50px" title="Rex Kerr"/> | [`@Ichoran`](https://github.com/Ichoran) | the collections library, performance |
+ <img src="https://avatars.githubusercontent.com/adriaanm" height="50px" title="Adriaan Moors"/> | [`@adriaanm`](https://github.com/adriaanm) | type checker, pattern matcher, infrastructure, language spec |
+ <img src="https://avatars.githubusercontent.com/SethTisue" height="50px" title="Seth Tisue"/> | [`@SethTisue`](https://github.com/SethTisue) | back-end, library, the welcome-to-Scala experience, build |
+ <img src="https://avatars.githubusercontent.com/retronym" height="50px" title="Jason Zaugg"/> | [`@retronym`](https://github.com/retronym) | compiler performance, weird compiler bugs, Java 8 lambdas, REPL |
+ <img src="https://avatars.githubusercontent.com/Ichoran" height="50px" title="Rex Kerr"/> | [`@Ichoran`](https://github.com/Ichoran) | collections library, performance |
<img src="https://avatars.githubusercontent.com/lrytz" height="50px" title="Lukas Rytz"/> | [`@lrytz`](https://github.com/lrytz) | optimizer, named & default arguments |
- <img src="https://avatars.githubusercontent.com/VladUreche" height="50px" title="Vlad Ureche"/> | [`@VladUreche`](https://github.com/VladUreche) | specialization & the scaladoc tool |
+ <img src="https://avatars.githubusercontent.com/VladUreche" height="50px" title="Vlad Ureche"/> | [`@VladUreche`](https://github.com/VladUreche) | specialization, Scaladoc tool |
<img src="https://avatars.githubusercontent.com/densh" height="50px" title="Denys Shabalin"/> | [`@densh`](https://github.com/densh) | quasiquotes, parser, string interpolators, macros in standard library |
<img src="https://avatars.githubusercontent.com/xeno-by" height="50px" title="Eugene Burmako"/> | [`@xeno-by`](https://github.com/xeno-by) | macros and reflection |
- <img src="https://avatars.githubusercontent.com/dickwall" height="50px" title="Dick Wall"/> | [`@dickwall`](https://github.com/dickwall) | process & community |
+ <img src="https://avatars.githubusercontent.com/heathermiller" height="50px" title="Heather Miller"/> | [`@heathermiller`](https://github.com/heathermiller) | documentation |
+ <img src="https://avatars.githubusercontent.com/dickwall" height="50px" title="Dick Wall"/> | [`@dickwall`](https://github.com/dickwall) | process & community, documentation |
+ <img src="https://avatars.githubusercontent.com/dragos" height="50px" title="Iulian Dragos"/> | [`@dragos`](https://github.com/dragos) | specialization, back end |
+ <img src="https://avatars.githubusercontent.com/axel22" height="50px" title="Aleksandr Prokopec"/> | [`@axel22`](https://github.com/axel22) | collections, concurrency, specialization |
+ <img src="https://avatars.githubusercontent.com/janekdb" height="50px" title="Janek Bogucki"/> | [`@janekdb`](https://github.com/janekdb) | documentation |
-
-PS: If you have some spare time to help out around here, we would be delighted to add your name to this list!
+P.S.: If you have some spare time to help out around here, we would be delighted to add your name to this list!
# Handy Links
- [A wealth of documentation](http://docs.scala-lang.org)
- [Scala CI](https://scala-ci.typesafe.com/)
- - [Download the latest nightly](http://www.scala-lang.org/files/archive/nightly/2.11.x/);
+ - [Download the latest nightly](http://www.scala-lang.org/files/archive/nightly/2.11.x/)
- [(Deprecated) Scala CI at EPFL](https://scala-webapps.epfl.ch/jenkins/)
- Scala mailing lists:
- [Compiler and standard library development](https://groups.google.com/group/scala-internals)
@@ -62,7 +74,7 @@ scala/
## Requirements
-You'll need a Java SDK (6 or newer), Apache Ant (version 1.8.0 or above), and curl (for `./pull-binary-libs.sh`).
+You'll need a Java SDK (6 or newer), Apache Ant (version 1.9.0 or above), and curl (for `./pull-binary-libs.sh`).
## Git Hygiene
@@ -76,7 +88,7 @@ To pinpoint bugs, we often use git bisect, which is only effective when we can c
This facilitates reviewing: a commit that reformats code can be judged quickly not to affect anything, so we can focus on the meat of the PR. It also helps when merging between long-running branches, reducing conflicts (or providing at least a limited scope for each one).
-Please do not @mention anyone in the commit message -- that's what the PR description and comments are for. Every time a commit is shuffled through github (in a merge in some fork, say), every @mention results in an email to that person (the core team treats them as personal email, straight to their inbox, so please don't flood us :-)).
+Please do not @-mention anyone in the commit message -- that's what the PR description and comments are for. Every time a commit is shuffled through github (in a merge in some fork, say), every @-mention results in an email to that person (the core team treats them as personal email, straight to their inbox, so please don't flood us :-)).
## Reviews
@@ -89,13 +101,18 @@ To help you plan your contributions, we communicate our plans on a regular basis
## Reviewing
-Once you've gained some experience with the code base and the process, the logical next step is to offers reviews for others's contributions. The main goal of this whole process, in the end, is to ensure the health of the Scala project by improving the quality of the code base, the documentation, as well as this process itself. Thank you for doing your part!
+Once you've gained some experience with the code base and the process, the next step is to review the contributions of others.
+
+The main goal of this whole process is to ensure the health of the Scala project by improving the quality of the code base, the documentation, as well as this process itself. Thank you for doing your part!
## [Labels](https://github.com/scala/scala/labels)
- - `reviewed` automatically added by scabot when a comment prefixed with LGTM is posted
- - `welcome` reviewer / queue curator adds to welcome someone's first PR (for highlighting in the release notes)
- - `release-notes` reviewer / queue curator adds to make sure this PR is highlighted in the release notes
- - `on-hold` added when this PR should not yet be merged, even though CI is green
+
+Label | Description
+--------------- | -----------
+`reviewed` | automatically added by scabot when a comment prefixed with LGTM is posted
+`welcome` | reviewer / queue curator adds to welcome someone's first PR (for highlighting in the release notes)
+`release-notes` | reviewer / queue curator adds to make sure this PR is highlighted in the release notes
+`on-hold` | added when this PR should not yet be merged, even though CI is green
### Tips & Tricks
Once the `publish-core` task has completed on a commit, you can try it out in sbt as follows:
@@ -124,43 +141,50 @@ Use the latest IntelliJ IDEA release and install the Scala plugin from within th
The following steps are required to use IntelliJ IDEA on Scala trunk
- Run `ant init`. This will download some JARs to `./build/deps`, which are included in IntelliJ's classpath.
- - Run src/intellij/setup.sh
- - Open ./src/intellij/scala.ipr in IntelliJ
- - File, Project Settings, Project, SDK. Create an SDK entry named "1.6" containing the Java 1.6 SDK.
+ - Run `./src/intellij/setup.sh`.
+ - Open `./src/intellij/scala.ipr` in IntelliJ.
+ - `File` → `Project Structure` → `Project` → `Project SDK`. Create an SDK entry named "1.6" containing the Java 1.6 SDK.
(You may use a later SDK for local development, but the CI will verify against Java 6.)
-Compilation within IDEA is performed in "-Dlocker.skip=1" mode: the sources are built
-directly using the STARR compiler (which is downloaded from maven, according to `starr.version` in `versions.properties`).
+Compilation within IDEA is performed in `-Dlocker.skip=1` mode: the sources are built
+directly using the STARR compiler (which is downloaded from [the Central Repository](http://central.sonatype.org/), according to `starr.version` in `versions.properties`).
+## Building with sbt (EXPERIMENTAL)
+
+The experimental sbt-based build definition has arrived! Run `sbt package`
+to build the compiler. You can run `sbt test` to run unit (JUnit) tests.
+Use `sbt test/it:test` to run integration (partest) tests.
+
+We would like to migrate to sbt build as quickly as possible. If you would
+like to help please use the scala-internals mailing list to discuss your
+ideas and coordinate your effort with others.
## Building with Ant
NOTE: we are working on migrating the build to sbt.
+If you are behind a HTTP proxy, include
+[`ANT_ARGS=-autoproxy`](https://ant.apache.org/manual/proxy.html) in
+your environment.
+
Run `ant build-opt` to build an optimized version of the compiler.
Verify your build using `ant test-opt`.
The Scala build system is based on Apache Ant. Most required pre-compiled
libraries are part of the repository (in 'lib/'). The following however is
-assumed to be installed on the build machine:
-
-## Building with Sbt (EXPERIMENTAL)
-
-The experimental sbt-based build definition has arrived! Run `sbt package`
-to build the compiler. You can run `sbt test` to run unit (JUnit) tests.
-Use `sbt test/it:test` to run integration (partest) tests.
-
-We would like to migrate to sbt build as quickly as possible. If you would
-like to help please contact scala-internals@ mailing list to discuss your
-ideas and coordinate your effort with others.
+assumed to be installed on the build machine: TODO
-### Tips and tricks
+### Ant Tips and tricks
Here are some common commands. Most ant targets offer a `-opt` variant that runs under `-optimise` (CI runs the -optimize variant).
- - `./pull-binary-libs.sh` [downloads](http://typesafe.artifactoryonline.com/typesafe) all binary artifacts associated with this commit.
- - `ant -p` prints out information about the commonly used ant targets.
- - `ant` or `ant build`: A quick compilation (to build/quick) of your changes using the locker compiler.
+Command | Description
+----------------------- | -----------
+`./pull-binary-libs.sh` | downloads all binary artifacts associated with this commit.
+`ant -p` | prints out information about the commonly used ant targets.
+`ant` or `ant build` | A quick compilation (to `build/quick`) of your changes using the locker compiler.
+`ant dist` | builds a distribution in 'dists/latest'.
+`ant all.clean` | removes all build files and all distributions.
A typical debug cycle incrementally builds quick, then uses it to compile and run the file
`sandbox/test.scala` as follows:
@@ -172,17 +196,14 @@ We typically alias `build/quick/bin/scalac -d sandbox` to `qsc` and `build/quick
`ant test-opt` tests that your code is working and fit to be committed:
- Runs the test suite and bootstrapping test on quick.
- - You can run the suite only (skipping strap) with 'ant test.suite'.
+ - You can run the suite only (skipping strap) with `ant test.suite`.
`ant docs` generates the HTML documentation for the library from the sources using the scaladoc tool in quick.
-Note: on most machines this requires more heap than is allocate by default. You can adjust the parameters with ANT_OPTS. Example command line:
+Note: on most machines this requires more heap than is allocated by default. You can adjust the parameters with `ANT_OPTS`. Example command line:
+```sh
+ANT_OPTS="-Xms512M -Xmx2048M -Xss1M -XX:MaxPermSize=128M" ant docs
```
-ANT_OPTS = "-Xms512M -Xmx2048M -Xss1M -XX:MaxPermSize=128M" ant docs
-```
-
- - `ant dist` builds a distribution in 'dists/latest'.
- - `ant all.clean` Removes all build files and all distributions.
### Bootstrapping concepts
NOTE: This is somewhat outdated, but the ideas still hold.
@@ -192,7 +213,7 @@ compiles Scala in layers. Each layer is a complete compiled Scala compiler and l
A superior layer is always compiled by the layer just below it. Here is a short
description of the four layers that the build uses, from bottom to top:
- - `starr`: the stable reference Scala release. We use an official version of Scala (specified by `starr.version` in `versions.properties`), downloaded from maven central.
+ - `starr`: the stable reference Scala release. We use an official version of Scala (specified by `starr.version` in `versions.properties`), downloaded from the Central Repository.
- `locker`: the local reference which is compiled by starr and is the work compiler in a typical development cycle. Add `locker.skip=true` to `build.properties` to skip this step and speed up development when you're not changing code generation. In any case, after it has been built once, it is “frozen” in this state. Updating it to fit the current source code must be explicitly requested (`ant locker.unlock`).
- `quick`: the layer which is incrementally built when testing changes in the compiler or library. This is considered an actual new version when locker is up-to-date in relation to the source code.
- `strap`: a test layer used to check stability of the build.
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf
index a1706d103d..0d85590b41 100644
--- a/bincompat-backward.whitelist.conf
+++ b/bincompat-backward.whitelist.conf
@@ -208,6 +208,15 @@ filter {
{
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
}
]
}
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 8fadb65f39..a9fbaa7b87 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -372,6 +372,15 @@ filter {
{
matchName="scala.util.Sorting.scala$util$Sorting$$booleanSort"
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
}
]
}
diff --git a/build.sbt b/build.sbt
index 1e3bef2541..8e79e1019f 100644
--- a/build.sbt
+++ b/build.sbt
@@ -50,7 +50,7 @@
* https://groups.google.com/d/topic/scala-internals/gp5JsM1E0Fo/discussion
*/
-val bootstrapScalaVersion = "2.11.5"
+val bootstrapScalaVersion = versionProps("starr.version")
def withoutScalaLang(moduleId: ModuleID): ModuleID = moduleId exclude("org.scala-lang", "*")
@@ -64,11 +64,11 @@ val junitIntefaceDep = "com.novocode" % "junit-interface" % "0.11" % "test"
val asmDep = "org.scala-lang.modules" % "scala-asm" % versionProps("scala-asm.version")
val jlineDep = "jline" % "jline" % versionProps("jline.version")
val antDep = "org.apache.ant" % "ant" % "1.9.4"
-val scalacheckDep = withoutScalaLang("org.scalacheck" %% "scalacheck" % "1.11.4")
+val scalacheckDep = withoutScalaLang("org.scalacheck" %% "scalacheck" % versionNumber("scalacheck") % "it")
lazy val commonSettings = clearSourceAndResourceDirectories ++ Seq[Setting[_]](
organization := "org.scala-lang",
- version := "2.11.6-SNAPSHOT",
+ version := "2.11.8-SNAPSHOT",
scalaVersion := bootstrapScalaVersion,
// we don't cross build Scala itself
crossPaths := false,
@@ -131,7 +131,7 @@ lazy val setJarLocation: Setting[_] =
lazy val scalaSubprojectSettings: Seq[Setting[_]] = commonSettings :+ setJarLocation
lazy val generatePropertiesFileSettings = Seq[Setting[_]](
- copyrightString := "Copyright 2002-2013, LAMP/EPFL",
+ copyrightString := "Copyright 2002-2015, LAMP/EPFL",
resourceGenerators in Compile += generateVersionPropertiesFile.map(file => Seq(file)).taskValue,
generateVersionPropertiesFile := generateVersionPropertiesFileImpl.value
)
@@ -200,7 +200,7 @@ lazy val repl = configureAsSubproject(project)
run <<= (run in Compile).partialInput(" -usejavacp") // Automatically add this so that `repl/run` works without additional arguments.
)
.settings(disableDocsAndPublishingTasks: _*)
- .dependsOn(compiler)
+ .dependsOn(compiler, interactive)
lazy val scaladoc = configureAsSubproject(project)
.settings(
diff --git a/build.xml b/build.xml
index 589e1931b8..7f8c91b47b 100755..100644
--- a/build.xml
+++ b/build.xml
@@ -184,7 +184,7 @@ TODO:
<property name="dists.dir" value="${basedir}/dists"/>
- <property name="copyright.string" value="Copyright 2002-2013, LAMP/EPFL"/>
+ <property name="copyright.string" value="Copyright 2002-2015, LAMP/EPFL"/>
<!-- These are NOT the flags used to run SuperSabbus, but the ones written
into the script runners created with scala.tools.ant.ScalaTool -->
@@ -506,6 +506,11 @@ TODO:
</condition>
<fail if="has.unsupported.jdk" message="JDK ${ant.java.version} is not supported by this build!"/>
+ <fail message="Ant 1.9+ required">
+ <condition>
+ <not><antversion atleast="1.9" /></not>
+ </condition>
+ </fail>
<!-- Allow this to be overridden simply -->
<property name="sbt.latest.version" value="0.12.4"/>
@@ -802,6 +807,7 @@ TODO:
<path id="quick.repl.build.path">
<path refid="quick.compiler.build.path"/>
+ <path refid="quick.interactive.build.path"/>
<pathelement location="${build-quick.dir}/classes/repl"/>
</path>
@@ -842,7 +848,7 @@ TODO:
</path>
<path id="quick.bin.tool.path">
- <path refid="quick.repl.build.path"/>
+ <path refid="quick.repl-jline.build.path"/>
<path refid="quick.actors.build.path"/>
<pathelement location="${build-quick.dir}/classes/scalap"/>
<pathelement location="${build-quick.dir}/classes/scaladoc"/>
@@ -1168,7 +1174,7 @@ TODO:
<target name="quick.comp" depends="quick.reflect">
<staged-build with="locker" stage="quick" project="compiler"/> </target>
- <target name="quick.repl" depends="quick.comp">
+ <target name="quick.repl" depends="quick.comp, quick.interactive">
<staged-build with="locker" stage="quick" project="repl"/>
<staged-build with="locker" stage="quick" project="repl-jline"/>
@@ -1196,7 +1202,7 @@ TODO:
</target>
<target name="quick.scaladoc" depends="quick.comp">
- <staged-build with="locker" stage="quick" project="scaladoc" version="scaladoc"/> </target>
+ <staged-build with="locker" stage="quick" project="scaladoc"/> </target>
<target name="quick.interactive" depends="quick.comp, quick.scaladoc">
<staged-build with="locker" stage="quick" project="interactive"/> </target>
diff --git a/doc/LICENSE.md b/doc/LICENSE.md
index 6b039afd68..55e82f64ba 100644
--- a/doc/LICENSE.md
+++ b/doc/LICENSE.md
@@ -2,9 +2,9 @@ Scala is licensed under the [BSD 3-Clause License](http://opensource.org/license
## Scala License
-Copyright (c) 2002-2013 EPFL
+Copyright (c) 2002-2015 EPFL
-Copyright (c) 2011-2013 Typesafe, Inc.
+Copyright (c) 2011-2015 Typesafe, Inc.
All rights reserved.
diff --git a/doc/License.rtf b/doc/License.rtf
index 62ec2d023c..c475bda3ef 100644
--- a/doc/License.rtf
+++ b/doc/License.rtf
@@ -10,8 +10,8 @@
\fs48 Scala License
\fs40 \
-\fs26 Copyright (c) 2002-2013 EPFL\
-Copyright (c) 2011-2013 Typesafe, Inc.\
+\fs26 Copyright (c) 2002-2015 EPFL\
+Copyright (c) 2011-2015 Typesafe, Inc.\
All rights reserved.\
\
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\
diff --git a/docs/TODO b/docs/TODO
index 094202f53e..558aa87205 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -53,7 +53,7 @@
The process is about the same for symbols in PolyTypes. The main
difference is that type parameters may be referenced and thus we
- need something like De Bruijn indicies to represent these
+ need something like De Bruijn indices to represent these
references.
diff --git a/project/build.properties b/project/build.properties
index 748703f770..817bc38df8 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=0.13.7
+sbt.version=0.13.9
diff --git a/scripts/jobs/integrate/bootstrap b/scripts/jobs/integrate/bootstrap
index 5048f3fdb9..8d04e7fc79 100755
--- a/scripts/jobs/integrate/bootstrap
+++ b/scripts/jobs/integrate/bootstrap
@@ -33,7 +33,7 @@
# - Set <MODULE>_VER to override the default, e.g. XML_VER="1.0.4".
# - The git revision is set to <MODULE>_REF="v$<MODULE>_VER". Make sure the tag exists (you can't override <MODULE>_REF).
#
-# - Otherwise (moduleVersioning has some other value): in this mode we use nightly version nubmers for modules.
+# - Otherwise (moduleVersioning has some other value): in this mode we use nightly version numbers for modules.
# - By default the script sets all <MODULE>_REF to "HEAD", override to build a specific revision.
# - The <MODULE>_VER is set to a nightly version, for example "1.0.3-7-g14888a2-nightly" (you can't override <MODULE>_VER)
@@ -348,7 +348,7 @@ scalaVerToBinary() {
# - the suffix starts with "-bin": 2.12.0-bin-M1
# - the patch version is > 0 : 2.12.1-M1, 1.12.3-RC2, 2.12.1-sha-nightly, 2.12.2-SNAPSHOT
#
- # Othwersise, the binary version is the full version: 2.12.0-M1, 2.12.0-RC2, 2.12.0-sha-nightly, 2.12.0-SNAPSHOT
+ # Otherwise, the binary version is the full version: 2.12.0-M1, 2.12.0-RC2, 2.12.0-sha-nightly, 2.12.0-SNAPSHOT
#
# Adapted from sbt: https://github.com/sbt/sbt/blob/0.13.8/util/cross/src/main/input_sources/CrossVersionUtil.scala#L39
#
@@ -564,7 +564,7 @@ bootstrap() {
echo "### Bootstrapping Scala using locker"
- # # TODO: close all open staging repos so that we can be reaonably sure the only open one we see after publishing below is ours
+ # # TODO: close all open staging repos so that we can be reasonably sure the only open one we see after publishing below is ours
# # the ant call will create a new one
#
# Rebuild Scala with these modules so that all binary versions are consistent.
diff --git a/spec/01-lexical-syntax.md b/spec/01-lexical-syntax.md
index e26cb796c8..b26e5b2328 100644
--- a/spec/01-lexical-syntax.md
+++ b/spec/01-lexical-syntax.md
@@ -443,7 +443,7 @@ multiLineChars ::= {[‘"’] [‘"’] charNoDoubleQuote} {‘"’}
A multi-line string literal is a sequence of characters enclosed in
triple quotes `""" ... """`. The sequence of characters is
-arbitrary, except that it may contain three or more consuctive quote characters
+arbitrary, except that it may contain three or more consecutive quote characters
only at the very end. Characters
must not necessarily be printable; newlines or other
control characters are also permitted. Unicode escapes work as everywhere else, but none
diff --git a/spec/05-classes-and-objects.md b/spec/05-classes-and-objects.md
index 3a70f2a137..69828ec7fe 100644
--- a/spec/05-classes-and-objects.md
+++ b/spec/05-classes-and-objects.md
@@ -631,7 +631,7 @@ class Outer {
```
Here, accesses to the method `f` can appear anywhere within
-`OuterClass`, but not outside it. Accesses to method
+`Outer`, but not outside it. Accesses to method
`g` can appear anywhere within the package
`outerpkg.innerpkg`, as would be the case for
package-private methods in Java. Finally, accesses to method
diff --git a/spec/06-expressions.md b/spec/06-expressions.md
index 85e288bf5f..9cd58ea346 100644
--- a/spec/06-expressions.md
+++ b/spec/06-expressions.md
@@ -1736,7 +1736,7 @@ so `scala.Any` is the type inferred for `a`.
_Eta-expansion_ converts an expression of method type to an
equivalent expression of function type. It proceeds in two steps.
-First, one identifes the maximal sub-expressions of $e$; let's
+First, one identifies the maximal sub-expressions of $e$; let's
say these are $e_1 , \ldots , e_m$. For each of these, one creates a
fresh name $x_i$. Let $e'$ be the expression resulting from
replacing every maximal subexpression $e_i$ in $e$ by the
diff --git a/spec/07-implicits.md b/spec/07-implicits.md
index 784de969a8..28f6dfe5a8 100644
--- a/spec/07-implicits.md
+++ b/spec/07-implicits.md
@@ -84,7 +84,7 @@ The _parts_ of a type $T$ are:
- if $T$ is an abstract type, the parts of its upper bound;
- if $T$ denotes an implicit conversion to a type with a method with argument types $T_1 , \ldots , T_n$ and result type $U$,
the union of the parts of $T_1 , \ldots , T_n$ and $U$;
-- the parts of quantified (existential or univeral) and annotated types are defined as the parts of the underlying types (e.g., the parts of `T forSome { ... }` are the parts of `T`);
+- the parts of quantified (existential or universal) and annotated types are defined as the parts of the underlying types (e.g., the parts of `T forSome { ... }` are the parts of `T`);
- in all other cases, just $T$ itself.
Note that packages are internally represented as classes with companion modules to hold the package members.
diff --git a/spec/08-pattern-matching.md b/spec/08-pattern-matching.md
index c494fbcef5..d496388a91 100644
--- a/spec/08-pattern-matching.md
+++ b/spec/08-pattern-matching.md
@@ -507,7 +507,7 @@ def f[B](t: Term[B]): B = t match {
The expected type of the pattern `y: Number` is
`Term[B]`. The type `Number` does not conform to
`Term[B]`; hence Case 2 of the rules above
-applies. This means that `b` is treated as another type
+applies. This means that `B` is treated as another type
variable for which subtype constraints are inferred. In our case the
applicable constraint is `Number <: Term[B]`, which
entails `B = Int`. Hence, `B` is treated in
diff --git a/spec/12-the-scala-standard-library.md b/spec/12-the-scala-standard-library.md
index e76035f458..8f65191312 100644
--- a/spec/12-the-scala-standard-library.md
+++ b/spec/12-the-scala-standard-library.md
@@ -171,7 +171,7 @@ Any numeric value type $T$ supports the following methods.
evaluated by converting the receiver and its argument to their
operation type and performing the given arithmetic operation of that
type.
- * Parameterless arithmethic methods identity (`+`) and negation
+ * Parameterless arithmetic methods identity (`+`) and negation
(`-`), with result type $T$. The first of these returns the
receiver unchanged, whereas the second returns its negation.
* Conversion methods `toByte`, `toShort`, `toChar`,
@@ -194,7 +194,7 @@ Integer numeric value types support in addition the following operations:
operation of that type.
* A parameterless bit-negation method (`~`). Its result type is
- the reciver type $T$ or `Int`, whichever is larger.
+ the receiver type $T$ or `Int`, whichever is larger.
The operation is evaluated by converting the receiver to the result
type and negating every bit in its value.
* Bit-shift methods left-shift (`<<`), arithmetic right-shift
@@ -745,7 +745,7 @@ object Predef {
def readf2(format: String) = Console.readf2(format)
def readf3(format: String) = Console.readf3(format)
- // Implict conversions ------------------------------------------------
+ // Implicit conversions ------------------------------------------------
...
}
diff --git a/spec/15-changelog.md b/spec/15-changelog.md
index 3c8739359a..751a571ecc 100644
--- a/spec/15-changelog.md
+++ b/spec/15-changelog.md
@@ -31,7 +31,7 @@ formal parameter types. Added section on
[numeric widening](06-expressions.html#numeric-widening) to support
weak conformance.
-Tightened rules to avoid accidential [overrides](05-classes-and-objects.html#overriding).
+Tightened rules to avoid accidental [overrides](05-classes-and-objects.html#overriding).
Removed class literals.
@@ -53,7 +53,7 @@ has been brought in line with. From now on `+=`, has the same precedence as `=`.
#### Wildcards as function parameters
-A formal parameter to an anonymous fucntion may now be a
+A formal parameter to an anonymous function may now be a
[wildcard represented by an underscore](06-expressions.html#placeholder-syntax-for-anonymous-functions).
> _ => 7 // The function that ignores its argument
diff --git a/spec/README.md b/spec/README.md
index 2f582dec5c..1a201fc97c 100644
--- a/spec/README.md
+++ b/spec/README.md
@@ -8,7 +8,7 @@ Third, we'd like to support different output formats. An html page per chapter w
## Editing
-We use redcarpet 3.1 and jekyll 2 to generate the html. Essentially, this is what github pages use.
+We use Jekyll 2 and [Redcarpet](https://github.com/vmg/redcarpet) to generate the html. Essentially, this is what github pages use.
## Building
diff --git a/spec/_config.yml b/spec/_config.yml
index 1052ddedb0..74ec602f8f 100644
--- a/spec/_config.yml
+++ b/spec/_config.yml
@@ -6,5 +6,3 @@ markdown: redcarpet
encoding: utf-8
redcarpet:
extensions: ["no_intra_emphasis", "fenced_code_blocks", "autolink", "tables", "with_toc_data", "strikethrough", "lax_spacing", "space_after_headers", "superscript", "footnotes"]
-# with_toc_data requires redcarpet 3.1 to get
-# pretty ID attributes for Hn headers (https://github.com/vmg/redcarpet/pull/186)
diff --git a/src/actors/scala/actors/Future.scala b/src/actors/scala/actors/Future.scala
index 4421c7a07a..11602f52a2 100644
--- a/src/actors/scala/actors/Future.scala
+++ b/src/actors/scala/actors/Future.scala
@@ -12,7 +12,7 @@ package scala.actors
import scala.actors.scheduler.DaemonScheduler
import scala.concurrent.SyncVar
-/** A function of arity 0, returing a value of type `T` that,
+/** A function of arity 0, returning a value of type `T` that,
* when applied, blocks the current actor (`Actor.self`)
* until the future's value is available.
*
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala
index 13bf0ef4c6..f46f014096 100644
--- a/src/compiler/scala/tools/ant/Scalac.scala
+++ b/src/compiler/scala/tools/ant/Scalac.scala
@@ -131,7 +131,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
/** The character encoding of the files to compile. */
protected var encoding: Option[String] = None
- // the targetted backend
+ // the targeted backend
protected var backend: Option[String] = None
/** Whether to force compilation of all files or not. */
diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
index 6e91a2a202..5e6b3c041e 100755
--- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
+++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
@@ -67,6 +67,11 @@ if uname | grep -q ^MINGW; then
mingw="$(uname)"
fi
+unset msys
+if uname | grep -q ^MSYS; then
+ msys="$(uname)"
+fi
+
# Finding the root folder for this Scala distribution
SCALA_HOME="$(findScalaHome)"
SEP=":"
@@ -111,9 +116,9 @@ if [[ -n "$cygwin" ]]; then
TOOL_CLASSPATH="$(cygpath --path --$format "$TOOL_CLASSPATH")"
fi
-if [[ -n "$cygwin$mingw" ]]; then
+if [[ -n "$cygwin$mingw$msys" ]]; then
case "$TERM" in
- rxvt* | xterm*)
+ rxvt* | xterm* | cygwin*)
stty -icanon min 1 -echo
WINDOWS_OPT="-Djline.terminal=unix"
;;
@@ -182,10 +187,10 @@ fi
declare -a classpath_args
-# default to the boot classpath for speed, except on cygwin/mingw because
+# default to the boot classpath for speed, except on cygwin/mingw/msys because
# JLine on Windows requires a custom DLL to be loaded.
unset usebootcp
-if [[ -z "$cygwin$mingw" ]]; then
+if [[ -z "$cygwin$mingw$msys" ]]; then
usebootcp="true"
fi
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 3469726455..936bed7c8f 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1686,7 +1686,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
try {
val stream = new FileOutputStream(file)
printer.setWriter(new PrintWriter(stream, true))
- printer.printClass(cls)
+ try
+ printer.printClass(cls)
+ finally
+ stream.close()
informProgress(s"wrote $file")
} catch {
case e: IOException =>
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index 6d24b31531..bf93ad30bc 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -16,16 +16,16 @@ import util.Exceptional.unwrap
/** An object that runs Scala code in script files.
*
- * <p>For example, here is a complete Scala script on Unix:</pre>
- * <pre>
+ * For example, here is a complete Scala script on Unix:
+ * {{{
* #!/bin/sh
* exec scala "$0" "$@"
* !#
* Console.println("Hello, world!")
* args.toList foreach Console.println
- * </pre>
- * <p>And here is a batch file example on Windows XP:</p>
- * <pre>
+ * }}}
+ * And here is a batch file example on Windows XP:
+ * {{{
* ::#!
* @echo off
* call scala %0 %*
@@ -33,7 +33,7 @@ import util.Exceptional.unwrap
* ::!#
* Console.println("Hello, world!")
* args.toList foreach Console.println
- * </pre>
+ * }}}
*
* @author Lex Spoon
* @version 1.0, 15/05/2006
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index 6442ef2d54..6442ef2d54 100755..100644
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index bf53c47e9a..332acf4a26 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -261,7 +261,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
* Create a method based on a Function
*
* Used both to under `-Ydelambdafy:method` create a lifted function and
- * under `-Ydelamdafy:inline` to create the apply method on the anonymous
+ * under `-Ydelambdafy:inline` to create the apply method on the anonymous
* class.
*
* It creates a method definition with value params cloned from the
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
index 52b8a51a79..52b8a51a79 100755..100644
--- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 4f195c2985..4494a8ac8d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -2031,11 +2031,11 @@ self =>
/** Drop `private` modifier when followed by a qualifier.
* Contract `abstract` and `override` to ABSOVERRIDE
*/
- private def normalizeModifers(mods: Modifiers): Modifiers =
+ private def normalizeModifiers(mods: Modifiers): Modifiers =
if (mods.isPrivate && mods.hasAccessBoundary)
- normalizeModifers(mods &~ Flags.PRIVATE)
+ normalizeModifiers(mods &~ Flags.PRIVATE)
else if (mods hasAllFlags (Flags.ABSTRACT | Flags.OVERRIDE))
- normalizeModifers(mods &~ (Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE)
+ normalizeModifiers(mods &~ (Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE)
else
mods
@@ -2080,7 +2080,7 @@ self =>
* AccessModifier ::= (private | protected) [AccessQualifier]
* }}}
*/
- def accessModifierOpt(): Modifiers = normalizeModifers {
+ def accessModifierOpt(): Modifiers = normalizeModifiers {
in.token match {
case m @ (PRIVATE | PROTECTED) => in.nextToken() ; accessQualifierOpt(Modifiers(flagTokens(m)))
case _ => NoMods
@@ -2094,7 +2094,7 @@ self =>
* | override
* }}}
*/
- def modifiers(): Modifiers = normalizeModifers {
+ def modifiers(): Modifiers = normalizeModifiers {
def loop(mods: Modifiers): Modifiers = in.token match {
case PRIVATE | PROTECTED =>
loop(accessQualifierOpt(addMod(mods, flagTokens(in.token), tokenRange(in))))
@@ -2680,7 +2680,10 @@ self =>
case t if t == SUPERTYPE || t == SUBTYPE || t == COMMA || t == RBRACE || isStatSep(t) =>
TypeDef(mods | Flags.DEFERRED, name, tparams, typeBounds())
case _ =>
- syntaxErrorOrIncompleteAnd("`=', `>:', or `<:' expected", skipIt = true)(EmptyTree)
+ syntaxErrorOrIncompleteAnd("`=', `>:', or `<:' expected", skipIt = true)(
+ // assume a dummy type def so as to have somewhere to stash the annotations
+ TypeDef(mods, tpnme.ERROR, Nil, EmptyTree)
+ )
}
}
}
@@ -2713,7 +2716,10 @@ self =>
case CASEOBJECT =>
objectDef(pos, (mods | Flags.CASE) withPosition (Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'object', thus take prev*/)))
case _ =>
- syntaxErrorOrIncompleteAnd("expected start of definition", skipIt = true)(EmptyTree)
+ syntaxErrorOrIncompleteAnd("expected start of definition", skipIt = true)(
+ // assume a class definition so as to have somewhere to stash the annotations
+ atPos(pos)(gen.mkClassDef(mods, tpnme.ERROR, Nil, Template(Nil, noSelfType, Nil)))
+ )
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 92833d647b..cd41c75298 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -226,7 +226,7 @@ trait Scanners extends ScannersCommon {
* RPAREN if region starts with '('
* RBRACKET if region starts with '['
* RBRACE if region starts with '{'
- * ARROW if region starts with `case'
+ * ARROW if region starts with 'case'
* STRINGLIT if region is a string interpolation expression starting with '${'
* (the STRINGLIT appears twice in succession on the stack iff the
* expression is a multiline string literal).
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index 67241ef639..67241ef639 100755..100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
diff --git a/src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala b/src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala
index 6dcfa173df..6dcfa173df 100755..100644
--- a/src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 3e23291e92..b6f9bcc9ab 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -2016,7 +2016,7 @@ abstract class GenICode extends SubComponent {
*
* This could result in unreachable code which has to be cleaned up later, e.g. if the try and all the exception
* handlers always end in RETURN then there will be no "normal" flow out of the try/catch/finally.
- * Later reachability analysis will remove unreacahble code.
+ * Later reachability analysis will remove unreachable code.
*/
def Try(body: Context => Context,
handlers: List[(Symbol, TypeKind, Context => Context)],
@@ -2060,7 +2060,7 @@ abstract class GenICode extends SubComponent {
if (settings.YdisableUnreachablePrevention || !outerCtx.bb.ignore) {
if (finalizer != EmptyTree) {
val exh = outerCtx.newExceptionHandler(NoSymbol, finalizer.pos) // finalizer covers exception handlers
- this.addActiveHandler(exh) // .. and body aswell
+ this.addActiveHandler(exh) // .. and body as well
val exhStartCtx = finalizerCtx.enterExceptionHandler(exh)
exhStartCtx.bb killIf outerCtx.bb.ignore
val exception = exhStartCtx.makeLocal(finalizer.pos, ThrowableTpe, "exc")
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala
index 843648282b..0f17b5d694 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala
@@ -20,7 +20,7 @@ abstract class ICodeCheckers {
* </p>
* <ul>
* <li>
- * for primitive operations: the type and numer of operands match
+ * for primitive operations: the type and number of operands match
* the type of the operation
* </li>
* <li>
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala
index 0df1b2029d..cd7e0b83e8 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala
@@ -10,6 +10,7 @@ import java.io.{StringWriter, PrintWriter}
import scala.tools.asm.util.{CheckClassAdapter, TraceClassVisitor, TraceMethodVisitor, Textifier}
import scala.tools.asm.{ClassWriter, Attribute, ClassReader}
import scala.collection.convert.decorateAsScala._
+import scala.tools.nsc.backend.jvm.analysis.InitialProducer
import scala.tools.nsc.backend.jvm.opt.InlineInfoAttributePrototype
object AsmUtils {
@@ -81,13 +82,16 @@ object AsmUtils {
/**
* Returns a human-readable representation of the given instruction.
*/
- def textify(insn: AbstractInsnNode): String = {
- val trace = new TraceMethodVisitor(new Textifier)
- insn.accept(trace)
- val sw = new StringWriter
- val pw = new PrintWriter(sw)
- trace.p.print(pw)
- sw.toString.trim
+ def textify(insn: AbstractInsnNode): String = insn match {
+ case _: InitialProducer =>
+ insn.toString
+ case _ =>
+ val trace = new TraceMethodVisitor(new Textifier)
+ insn.accept(trace)
+ val sw = new StringWriter
+ val pw = new PrintWriter(sw)
+ trace.p.print(pw)
+ sw.toString.trim
}
/**
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
index dec5adc9aa..93f5159f89 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
@@ -256,14 +256,17 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
if (hasAbstractMethod) ACC_ABSTRACT else 0
}
GenBCode.mkFlags(
- if (classSym.isPublic) ACC_PUBLIC else 0,
- if (classSym.isFinal) ACC_FINAL else 0,
+ // SI-9393: the classfile / java source parser make java annotation symbols look like classes.
+ // here we recover the actual classfile flags.
+ if (classSym.hasJavaAnnotationFlag) ACC_ANNOTATION | ACC_INTERFACE | ACC_ABSTRACT else 0,
+ if (classSym.isPublic) ACC_PUBLIC else 0,
+ if (classSym.isFinal) ACC_FINAL else 0,
// see the link above. javac does the same: ACC_SUPER for all classes, but not interfaces.
- if (classSym.isInterface) ACC_INTERFACE else ACC_SUPER,
+ if (classSym.isInterface) ACC_INTERFACE else ACC_SUPER,
// for Java enums, we cannot trust `hasAbstractFlag` (see comment in enumFlags)
- if (!classSym.hasEnumFlag && classSym.hasAbstractFlag) ACC_ABSTRACT else 0,
- if (classSym.isArtifact) ACC_SYNTHETIC else 0,
- if (classSym.hasEnumFlag) enumFlags else 0
+ if (!classSym.hasJavaEnumFlag && classSym.hasAbstractFlag) ACC_ABSTRACT else 0,
+ if (classSym.isArtifact) ACC_SYNTHETIC else 0,
+ if (classSym.hasJavaEnumFlag) enumFlags else 0
)
}
@@ -289,7 +292,7 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
lazy val AnnotationRetentionPolicyRuntimeValue = AnnotationRetentionPolicyModule.tpe.member(TermName("RUNTIME"))
/** Whether an annotation should be emitted as a Java annotation
- * .initialize: if 'annot' is read from pickle, atp might be un-initialized
+ * .initialize: if 'annot' is read from pickle, atp might be uninitialized
*/
def shouldEmitAnnotation(annot: AnnotationInfo) = {
annot.symbol.initialize.isJavaDefined &&
@@ -310,10 +313,10 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
}
private def retentionPolicyOf(annot: AnnotationInfo): Symbol =
- annot.atp.typeSymbol.getAnnotation(AnnotationRetentionAttr).map(_.assocs).map(assoc =>
+ annot.atp.typeSymbol.getAnnotation(AnnotationRetentionAttr).map(_.assocs).flatMap(assoc =>
assoc.collectFirst {
case (`nme`.value, LiteralAnnotArg(Constant(value: Symbol))) => value
- }).flatten.getOrElse(AnnotationRetentionPolicyClassValue)
+ }).getOrElse(AnnotationRetentionPolicyClassValue)
def implementedInterfaces(classSym: Symbol): List[Symbol] = {
// Additional interface parents based on annotations and other cues
@@ -322,9 +325,18 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
case _ => None
}
- def isInterfaceOrTrait(sym: Symbol) = sym.isInterface || sym.isTrait
+ // SI-9393: java annotations are interfaces, but the classfile / java source parsers make them look like classes.
+ def isInterfaceOrTrait(sym: Symbol) = sym.isInterface || sym.isTrait || sym.hasJavaAnnotationFlag
- val allParents = classSym.info.parents ++ classSym.annotations.flatMap(newParentForAnnotation)
+ val classParents = {
+ val parents = classSym.info.parents
+ // SI-9393: the classfile / java source parsers add Annotation and ClassfileAnnotation to the
+ // parents of a java annotations. undo this for the backend (where we need classfile-level information).
+ if (classSym.hasJavaAnnotationFlag) parents.filterNot(c => c.typeSymbol == ClassfileAnnotationClass || c.typeSymbol == AnnotationClass)
+ else parents
+ }
+
+ val allParents = classParents ++ classSym.annotations.flatMap(newParentForAnnotation)
// We keep the superClass when computing minimizeParents to eliminate more interfaces.
// Example: T can be eliminated from D
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 40ba0c010b..416628d5ba 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -92,8 +92,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
def genThrow(expr: Tree): BType = {
val thrownKind = tpeTK(expr)
- // `throw null` is valid although scala.Null (as defined in src/libray-aux) isn't a subtype of Throwable.
- // Similarly for scala.Nothing (again, as defined in src/libray-aux).
+ // `throw null` is valid although scala.Null (as defined in src/library-aux) isn't a subtype of Throwable.
+ // Similarly for scala.Nothing (again, as defined in src/library-aux).
assert(thrownKind.isNullType || thrownKind.isNothingType || thrownKind.asClassBType.isSubtypeOf(ThrowableReference).get)
genLoad(expr, thrownKind)
lineNumber(expr)
@@ -632,10 +632,11 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
case _ =>
abort(s"Cannot instantiate $tpt of kind: $generatedType")
}
- case Apply(_, args) if app.hasAttachment[delambdafy.LambdaMetaFactoryCapable] =>
+ case Apply(fun, args) if app.hasAttachment[delambdafy.LambdaMetaFactoryCapable] =>
val attachment = app.attachments.get[delambdafy.LambdaMetaFactoryCapable].get
genLoadArguments(args, paramTKs(app))
genInvokeDynamicLambda(attachment.target, attachment.arity, attachment.functionalInterface)
+ generatedType = asmMethodType(fun.symbol).returnType
case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isBox(fun.symbol) =>
val nativeKind = tpeTK(expr)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index 6aa3a62295..65a6b82570 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -329,7 +329,8 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
// If the `sym` is a java module class, we use the java class instead. This ensures that we
// register the class (instead of the module class) in innerClassBufferASM.
// The two symbols have the same name, so the resulting internalName is the same.
- val classSym = if (sym.isJavaDefined && sym.isModuleClass) sym.linkedClassOfClass else sym
+ // Phase travel (exitingPickler) required for SI-6613 - linkedCoC is only reliable in early phases (nesting)
+ val classSym = if (sym.isJavaDefined && sym.isModuleClass) exitingPickler(sym.linkedClassOfClass) else sym
getClassBTypeAndRegisterInnerClass(classSym).internalName
}
@@ -714,7 +715,8 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
{
val mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$deserializeLambda$", "(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", null, null)
mv.visitCode()
- mv.visitFieldInsn(GETSTATIC, clazz.javaBinaryName.encoded, "$deserializeLambdaCache$", "Ljava/util/Map;")
+ // javaBinaryName returns the internal name of a class. Also used in BTypesFromsymbols.classBTypeFromSymbol.
+ mv.visitFieldInsn(GETSTATIC, clazz.javaBinaryName.toString, "$deserializeLambdaCache$", "Ljava/util/Map;")
mv.visitVarInsn(ASTORE, 1)
mv.visitVarInsn(ALOAD, 1)
val l0 = new asm.Label()
@@ -724,13 +726,13 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false)
mv.visitVarInsn(ASTORE, 1)
mv.visitVarInsn(ALOAD, 1)
- mv.visitFieldInsn(PUTSTATIC, clazz.javaBinaryName.encoded, "$deserializeLambdaCache$", "Ljava/util/Map;")
+ mv.visitFieldInsn(PUTSTATIC, clazz.javaBinaryName.toString, "$deserializeLambdaCache$", "Ljava/util/Map;")
mv.visitLabel(l0)
- mv.visitFrame(asm.Opcodes.F_APPEND,1, Array("java/util/Map"), 0, null)
+ mv.visitFieldInsn(GETSTATIC, "scala/compat/java8/runtime/LambdaDeserializer$", "MODULE$", "Lscala/compat/java8/runtime/LambdaDeserializer$;")
mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false)
mv.visitVarInsn(ALOAD, 1)
mv.visitVarInsn(ALOAD, 0)
- mv.visitMethodInsn(INVOKESTATIC, "scala/compat/java8/runtime/LambdaDeserializer", "deserializeLambda", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/util/Map;Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", false)
+ mv.visitMethodInsn(INVOKEVIRTUAL, "scala/compat/java8/runtime/LambdaDeserializer$", "deserializeLambda", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/util/Map;Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", false)
mv.visitInsn(ARETURN)
mv.visitEnd()
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
index d2d510e8a9..a9b6a312e9 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
@@ -153,9 +153,9 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
*/
private def initJClass(jclass: asm.ClassVisitor) {
- val ps = claszSymbol.info.parents
- val superClass: String = if (ps.isEmpty) ObjectReference.internalName else internalName(ps.head.typeSymbol)
- val interfaceNames = classBTypeFromSymbol(claszSymbol).info.get.interfaces map {
+ val bType = classBTypeFromSymbol(claszSymbol)
+ val superClass = bType.info.get.superClass.getOrElse(ObjectReference).internalName
+ val interfaceNames = bType.info.get.interfaces map {
case classBType =>
if (classBType.isNestedClass.get) { innerClassBufferASM += classBType }
classBType.internalName
@@ -443,7 +443,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
* which rethrows the caught exception once it's done with the cleanup code.
*
* A particular cleanup may in general contain LabelDefs. Care is needed when duplicating such jump-targets,
- * so as to preserve agreement wit the (also duplicated) jump-sources.
+ * so as to preserve agreement with the (also duplicated) jump-sources.
* This is achieved based on the bookkeeping provided by two maps:
* - `labelDefsAtOrUnder` lists all LabelDefs enclosed by a given Tree node (the key)
* - `labelDef` provides the LabelDef node whose symbol is used as key.
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
index 8720da84e8..0c26e01322 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
@@ -1126,7 +1126,7 @@ object BTypes {
* The map is indexed by the string s"$name$descriptor" (to
* disambiguate overloads).
*
- * @param warning Contains an warning message if an error occured when building this
+ * @param warning Contains an warning message if an error occurred when building this
* InlineInfo, for example if some classfile could not be found on
* the classpath. This warning can be reported later by the inliner.
*/
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
index cf29c8090b..45d9cc3ff3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
@@ -216,7 +216,18 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
}
private def setClassInfo(classSym: Symbol, classBType: ClassBType): ClassBType = {
- val superClassSym = if (classSym.isImplClass) ObjectClass else classSym.superClass
+ // Check for isImplClass: trait implementation classes have NoSymbol as superClass
+ // Check for hasAnnotationFlag for SI-9393: the classfile / java source parsers add
+ // scala.annotation.Annotation as superclass to java annotations. In reality, java
+ // annotation classfiles have superclass Object (like any interface classfile).
+ val superClassSym = if (classSym.isImplClass || classSym.hasJavaAnnotationFlag) ObjectClass else {
+ val sc = classSym.superClass
+ // SI-9393: Java annotation classes don't have the ABSTRACT/INTERFACE flag, so they appear
+ // (wrongly) as superclasses. Fix this for BTypes: the java annotation will appear as interface
+ // (handled by method implementedInterfaces), the superclass is set to Object.
+ if (sc.hasJavaAnnotationFlag) ObjectClass
+ else sc
+ }
assert(
if (classSym == ObjectClass)
superClassSym == NoSymbol
@@ -351,7 +362,15 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
val isTopLevel = innerClassSym.rawowner.isPackageClass
// impl classes are considered top-level, see comment in BTypes
if (isTopLevel || considerAsTopLevelImplementationArtifact(innerClassSym)) None
- else {
+ else if (innerClassSym.rawowner.isTerm) {
+ // This case should never be reached: the lambdalift phase mutates the rawowner field of all
+ // classes to be the enclosing class. SI-9392 shows an errant macro that leaves a reference
+ // to a local class symbol that no longer exists, which is not updated by lambdalift.
+ devWarning(innerClassSym.pos,
+ s"""The class symbol $innerClassSym with the term symbol ${innerClassSym.rawowner} as `rawowner` reached the backend.
+ |Most likely this indicates a stale reference to a non-existing class introduced by a macro, see SI-9392.""".stripMargin)
+ None
+ } else {
// See comment in BTypes, when is a class marked static in the InnerClass table.
val isStaticNestedClass = isOriginallyStaticOwner(innerClassSym.originalOwner)
@@ -559,7 +578,7 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0,
if (sym.isArtifact) ACC_SYNTHETIC else 0,
if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
- if (sym.hasEnumFlag) ACC_ENUM else 0,
+ if (sym.hasJavaEnumFlag) ACC_ENUM else 0,
if (sym.isVarargsMethod) ACC_VARARGS else 0,
if (sym.hasFlag(symtab.Flags.SYNCHRONIZED)) ACC_SYNCHRONIZED else 0,
if (sym.isDeprecated) asm.Opcodes.ACC_DEPRECATED else 0
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala b/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
index 4fc05cafdc..b41d0de92f 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
@@ -1,7 +1,7 @@
package scala.tools.nsc
package backend.jvm
-import scala.tools.asm.tree.{AbstractInsnNode, MethodNode}
+import scala.tools.asm.tree.{InvokeDynamicInsnNode, AbstractInsnNode, MethodNode}
import scala.tools.nsc.backend.jvm.BTypes.InternalName
import scala.reflect.internal.util.Position
import scala.tools.nsc.settings.ScalaSettings
@@ -246,11 +246,16 @@ object BackendReporting {
case class ResultingMethodTooLarge(calleeDeclarationClass: InternalName, name: String, descriptor: String,
callsiteClass: InternalName, callsiteName: String, callsiteDesc: String) extends CannotInlineWarning
+ case object UnknownInvokeDynamicInstruction extends OptimizerWarning {
+ override def toString = "The callee contains an InvokeDynamic instruction with an unknown bootstrap method (not a LambdaMetaFactory)."
+ def emitWarning(settings: ScalaSettings): Boolean = settings.YoptWarningEmitAtInlineFailed
+ }
+
/**
* Used in `rewriteClosureApplyInvocations` when a closure apply callsite cannot be rewritten
* to the closure body method.
*/
- trait RewriteClosureApplyToClosureBodyFailed extends OptimizerWarning {
+ sealed trait RewriteClosureApplyToClosureBodyFailed extends OptimizerWarning {
def pos: Position
override def emitWarning(settings: ScalaSettings): Boolean = this match {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 71686fd9d7..4768417c67 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -307,7 +307,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0,
if (sym.isArtifact) ACC_SYNTHETIC else 0,
if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
- if (sym.hasEnumFlag) ACC_ENUM else 0,
+ if (sym.hasJavaEnumFlag) ACC_ENUM else 0,
if (sym.isVarargsMethod) ACC_VARARGS else 0,
if (sym.hasFlag(Flags.SYNCHRONIZED)) ACC_SYNCHRONIZED else 0
)
@@ -495,8 +495,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
* generic classes or interfaces.
*
* @param superName the internal of name of the super class. For interfaces,
- * the super class is {@link Object}. May be <tt>null</tt>, but
- * only for the {@link Object} class.
+ * the super class is [[Object]]. May be <tt>null</tt>, but
+ * only for the [[Object]] class.
*
* @param interfaces the internal names of the class's interfaces (see
* {@link Type#getInternalName() getInternalName}). May be
@@ -532,6 +532,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
case e: java.lang.RuntimeException if e.getMessage != null && (e.getMessage contains "too large!") =>
reporter.error(sym.pos,
s"Could not write class $jclassName because it exceeds JVM code size limits. ${e.getMessage}")
+ case e: java.io.IOException if e.getMessage != null && (e.getMessage contains "File name too long") =>
+ reporter.error(sym.pos, e.getMessage + "\n" +
+ "This can happen on some encrypted or legacy file systems. Please see SI-3623 for more details.")
+
}
}
@@ -2696,7 +2700,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
case CMPG =>
(kind: @unchecked) match {
case FLOAT => emit(Opcodes.FCMPG)
- case DOUBLE => emit(Opcodes.DCMPL) // TODO bug? why not DCMPG? http://docs.oracle.com/javase/specs/jvms/se5.0/html/Instructions2.doc3.html
+ case DOUBLE => emit(Opcodes.DCMPL) // TODO bug? why not DCMPG? http://docs.oracle.com/javase/specs/jvms/se6/html/Instructions2.doc3.html
}
}
@@ -3031,7 +3035,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
*
* Rationale for this normalization:
* test/files/run/private-inline.scala after -optimize is chock full of
- * BasicBlocks containing just JUMP(whereTo), where no exception handler straddles them.
+ * BasicBlocks containing just JUMP(whereto), where no exception handler straddles them.
* They should be collapsed by IMethod.normalize() but aren't.
* That was fine in FJBG times when by the time the exception table was emitted,
* it already contained "anchored" labels (ie instruction offsets were known)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala
index 31710dcbee..31b62f747e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala
@@ -12,7 +12,7 @@ import scala.tools.nsc.backend.jvm.opt.BytecodeUtils
import BytecodeUtils._
/**
- * Some notes on the ASM ananlyzer framework.
+ * Some notes on the ASM analyzer framework.
*
* Value
* - Abstract, needs to be implemented for each analysis.
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala
index 40f91cbed4..594fd8923c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala
@@ -57,8 +57,20 @@ import scala.collection.convert.decorateAsScala._
* copying operations.
*/
class ProdConsAnalyzer(methodNode: MethodNode, classInternalName: InternalName) {
+
+ /* Timers for benchmarking ProdCons
+ import scala.reflect.internal.util.Statistics._
+ import ProdConsAnalyzer._
+ val analyzerTimer = newSubTimer(classInternalName + "#" + methodNode.name + " - analysis", prodConsAnalyzerTimer)
+ val consumersTimer = newSubTimer(classInternalName + "#" + methodNode.name + " - consumers", prodConsAnalyzerTimer)
+ */
+
val analyzer = new Analyzer(new InitialProducerSourceInterpreter)
+
+// val start = analyzerTimer.start()
analyzer.analyze(classInternalName, methodNode)
+// analyzerTimer.stop(start)
+// println(analyzerTimer.line)
def frameAt(insn: AbstractInsnNode) = analyzer.frameAt(insn, methodNode)
@@ -103,7 +115,11 @@ class ProdConsAnalyzer(methodNode: MethodNode, classInternalName: InternalName)
def initialProducersForValueAt(insn: AbstractInsnNode, slot: Int): Set[AbstractInsnNode] = {
def initialProducers(insn: AbstractInsnNode, producedSlot: Int): Set[AbstractInsnNode] = {
if (isCopyOperation(insn)) {
- _initialProducersCache.getOrElseUpdate((insn, producedSlot), {
+ val key = (insn, producedSlot)
+ _initialProducersCache.getOrElseUpdate(key, {
+ // prevent infinite recursion if an instruction is its own producer or consumer
+ // see cyclicProdCons in ProdConsAnalyzerTest
+ _initialProducersCache(key) = Set.empty
val (sourceValue, sourceValueSlot) = copyOperationSourceValue(insn, producedSlot)
sourceValue.insns.iterator.asScala.flatMap(initialProducers(_, sourceValueSlot)).toSet
})
@@ -121,7 +137,11 @@ class ProdConsAnalyzer(methodNode: MethodNode, classInternalName: InternalName)
def ultimateConsumersOfValueAt(insn: AbstractInsnNode, slot: Int): Set[AbstractInsnNode] = {
def ultimateConsumers(insn: AbstractInsnNode, consumedSlot: Int): Set[AbstractInsnNode] = {
if (isCopyOperation(insn)) {
- _ultimateConsumersCache.getOrElseUpdate((insn, consumedSlot), {
+ val key = (insn, consumedSlot)
+ _ultimateConsumersCache.getOrElseUpdate(key, {
+ // prevent infinite recursion if an instruction is its own producer or consumer
+ // see cyclicProdCons in ProdConsAnalyzerTest
+ _ultimateConsumersCache(key) = Set.empty
for {
producedSlot <- copyOperationProducedValueSlots(insn, consumedSlot)
consumer <- consumersOfValueAt(insn.getNext, producedSlot)
@@ -384,6 +404,7 @@ class ProdConsAnalyzer(methodNode: MethodNode, classInternalName: InternalName)
/** For each instruction, a set of potential consumers of the produced values. */
private lazy val _consumersOfOutputsFrom: Map[AbstractInsnNode, Vector[Set[AbstractInsnNode]]] = {
+// val start = consumersTimer.start()
var res = Map.empty[AbstractInsnNode, Vector[Set[AbstractInsnNode]]]
for {
insn <- methodNode.instructions.iterator.asScala
@@ -396,6 +417,8 @@ class ProdConsAnalyzer(methodNode: MethodNode, classInternalName: InternalName)
val outputIndex = producedSlots.indexOf(i)
res = res.updated(producer, currentConsumers.updated(outputIndex, currentConsumers(outputIndex) + insn))
}
+// consumersTimer.stop(start)
+// println(consumersTimer.line)
res
}
@@ -403,6 +426,11 @@ class ProdConsAnalyzer(methodNode: MethodNode, classInternalName: InternalName)
private val _ultimateConsumersCache: mutable.AnyRefMap[(AbstractInsnNode, Int), Set[AbstractInsnNode]] = mutable.AnyRefMap.empty
}
+object ProdConsAnalyzer {
+ import scala.reflect.internal.util.Statistics._
+ val prodConsAnalyzerTimer = newTimer("Time in ProdConsAnalyzer", "jvm")
+}
+
/**
* A class for pseudo-instructions representing the initial producers of local values that have
* no producer instruction in the method:
@@ -447,4 +475,4 @@ class InitialProducerSourceInterpreter extends SourceInterpreter {
override def newExceptionValue(tryCatchBlockNode: TryCatchBlockNode, handlerFrame: Frame[_ <: Value], exceptionType: Type): SourceValue = {
new SourceValue(1, ExceptionProducer(handlerFrame))
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
index 0ec550981a..df8dcc690a 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
@@ -12,7 +12,7 @@ import scala.collection.mutable
import scala.reflect.internal.util.Collections._
import scala.tools.asm.commons.CodeSizeEvaluator
import scala.tools.asm.tree.analysis._
-import scala.tools.asm.{MethodWriter, ClassWriter, Label, Opcodes}
+import scala.tools.asm.{MethodWriter, ClassWriter, Label, Opcodes, Type}
import scala.tools.asm.tree._
import GenBCode._
import scala.collection.convert.decorateAsScala._
@@ -104,6 +104,8 @@ object BytecodeUtils {
def isStrictfpMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_STRICT) != 0
+ def isReference(t: Type) = t.getSort == Type.OBJECT || t.getSort == Type.ARRAY
+
def nextExecutableInstruction(instruction: AbstractInsnNode, alsoKeep: AbstractInsnNode => Boolean = Set()): Option[AbstractInsnNode] = {
var result = instruction
do { result = result.getNext }
@@ -331,6 +333,26 @@ object BytecodeUtils {
}
/**
+ * This method is used by optimizer components to eliminate phantom values of instruction
+ * that load a value of type `Nothing$` or `Null$`. Such values on the stack don't interact well
+ * with stack map frames.
+ *
+ * For example, `opt.getOrElse(throw e)` is re-written to an invocation of the lambda body, a
+ * method with return type `Nothing$`. Similarly for `opt.getOrElse(null)` and `Null$`.
+ *
+ * During bytecode generation this is handled by BCodeBodyBuilder.adapt. See the comment in that
+ * method which explains the issue with such phantom values.
+ */
+ def fixLoadedNothingOrNullValue(loadedType: Type, loadInstr: AbstractInsnNode, methodNode: MethodNode, bTypes: BTypes): Unit = {
+ if (loadedType == bTypes.coreBTypes.RT_NOTHING.toASMType) {
+ methodNode.instructions.insert(loadInstr, new InsnNode(Opcodes.ATHROW))
+ } else if (loadedType == bTypes.coreBTypes.RT_NULL.toASMType) {
+ methodNode.instructions.insert(loadInstr, new InsnNode(Opcodes.ACONST_NULL))
+ methodNode.instructions.insert(loadInstr, new InsnNode(Opcodes.POP))
+ }
+ }
+
+ /**
* A wrapper to make ASM's Analyzer a bit easier to use.
*/
class AsmAnalyzer[V <: Value](methodNode: MethodNode, classInternalName: InternalName, interpreter: Interpreter[V] = new BasicInterpreter) {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
index 8abecdb261..96455c0e38 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
@@ -9,7 +9,7 @@ package opt
import scala.reflect.internal.util.{NoPosition, Position}
import scala.tools.asm.tree.analysis.{Value, Analyzer, BasicInterpreter}
-import scala.tools.asm.{Opcodes, Type}
+import scala.tools.asm.{Opcodes, Type, Handle}
import scala.tools.asm.tree._
import scala.collection.concurrent
import scala.collection.convert.decorateAsScala._
@@ -24,7 +24,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
val callsites: concurrent.Map[MethodInsnNode, Callsite] = recordPerRunCache(concurrent.TrieMap.empty)
- val closureInstantiations: concurrent.Map[InvokeDynamicInsnNode, (MethodNode, ClassBType)] = recordPerRunCache(concurrent.TrieMap.empty)
+ val closureInstantiations: concurrent.Map[InvokeDynamicInsnNode, ClosureInstantiation] = recordPerRunCache(concurrent.TrieMap.empty)
def addClass(classNode: ClassNode): Unit = {
val classType = classBTypeFromClassNode(classNode)
@@ -33,14 +33,14 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
(calls, closureInits) = analyzeCallsites(m, classType)
} {
calls foreach (callsite => callsites(callsite.callsiteInstruction) = callsite)
- closureInits foreach (indy => closureInstantiations(indy) = (m, classType))
+ closureInits foreach (lmf => closureInstantiations(lmf.indy) = ClosureInstantiation(lmf, m, classType))
}
}
/**
* Returns a list of callsites in the method, plus a list of closure instantiation indy instructions.
*/
- def analyzeCallsites(methodNode: MethodNode, definingClass: ClassBType): (List[Callsite], List[InvokeDynamicInsnNode]) = {
+ def analyzeCallsites(methodNode: MethodNode, definingClass: ClassBType): (List[Callsite], List[LambdaMetaFactoryCall]) = {
case class CallsiteInfo(safeToInline: Boolean, safeToRewrite: Boolean,
annotatedInline: Boolean, annotatedNoInline: Boolean,
@@ -129,7 +129,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
}
val callsites = new collection.mutable.ListBuffer[Callsite]
- val closureInstantiations = new collection.mutable.ListBuffer[InvokeDynamicInsnNode]
+ val closureInstantiations = new collection.mutable.ListBuffer[LambdaMetaFactoryCall]
methodNode.instructions.iterator.asScala foreach {
case call: MethodInsnNode =>
@@ -173,8 +173,8 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
callsitePosition = callsitePositions.getOrElse(call, NoPosition)
)
- case indy: InvokeDynamicInsnNode =>
- if (closureOptimizer.isClosureInstantiation(indy)) closureInstantiations += indy
+ case LambdaMetaFactoryCall(indy, samMethodType, implMethod, instantiatedMethodType) =>
+ closureInstantiations += LambdaMetaFactoryCall(indy, samMethodType, implMethod, instantiatedMethodType)
case _ =>
}
@@ -236,4 +236,82 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
calleeInfoWarning: Option[CalleeInfoWarning]) {
assert(!(safeToInline && safeToRewrite), s"A callee of ${callee.name} can be either safeToInline or safeToRewrite, but not both.")
}
+
+ final case class ClosureInstantiation(lambdaMetaFactoryCall: LambdaMetaFactoryCall, ownerMethod: MethodNode, ownerClass: ClassBType) {
+ override def toString = s"ClosureInstantiation($lambdaMetaFactoryCall, ${ownerMethod.name + ownerMethod.desc}, $ownerClass)"
+ }
+ final case class LambdaMetaFactoryCall(indy: InvokeDynamicInsnNode, samMethodType: Type, implMethod: Handle, instantiatedMethodType: Type)
+
+ object LambdaMetaFactoryCall {
+ private val lambdaMetaFactoryInternalName: InternalName = "java/lang/invoke/LambdaMetafactory"
+
+ private val metafactoryHandle = {
+ val metafactoryMethodName: String = "metafactory"
+ val metafactoryDesc: String = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"
+ new Handle(Opcodes.H_INVOKESTATIC, lambdaMetaFactoryInternalName, metafactoryMethodName, metafactoryDesc)
+ }
+
+ private val altMetafactoryHandle = {
+ val altMetafactoryMethodName: String = "altMetafactory"
+ val altMetafactoryDesc: String = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"
+ new Handle(Opcodes.H_INVOKESTATIC, lambdaMetaFactoryInternalName, altMetafactoryMethodName, altMetafactoryDesc)
+ }
+
+ def unapply(insn: AbstractInsnNode): Option[(InvokeDynamicInsnNode, Type, Handle, Type)] = insn match {
+ case indy: InvokeDynamicInsnNode if indy.bsm == metafactoryHandle || indy.bsm == altMetafactoryHandle =>
+ indy.bsmArgs match {
+ case Array(samMethodType: Type, implMethod: Handle, instantiatedMethodType: Type, xs@_*) => // xs binding because IntelliJ gets confused about _@_*
+ // LambdaMetaFactory performs a number of automatic adaptations when invoking the lambda
+ // implementation method (casting, boxing, unboxing, and primitive widening, see Javadoc).
+ //
+ // The closure optimizer supports only one of those adaptations: it will cast arguments
+ // to the correct type when re-writing a closure call to the body method. Example:
+ //
+ // val fun: String => String = l => l
+ // val l = List("")
+ // fun(l.head)
+ //
+ // The samMethodType of Function1 is `(Object)Object`, while the instantiatedMethodType
+ // is `(String)String`. The return type of `List.head` is `Object`.
+ //
+ // The implMethod has the signature `C$anonfun(String)String`.
+ //
+ // At the closure callsite, we have an `INVOKEINTERFACE Function1.apply (Object)Object`,
+ // so the object returned by `List.head` can be directly passed into the call (no cast).
+ //
+ // The closure object will cast the object to String before passing it to the implMethod.
+ //
+ // When re-writing the closure callsite to the implMethod, we have to insert a cast.
+ //
+ // The check below ensures that
+ // (1) the implMethod type has the expected singature (captured types plus argument types
+ // from instantiatedMethodType)
+ // (2) the receiver of the implMethod matches the first captured type
+ // (3) all parameters that are not the same in samMethodType and instantiatedMethodType
+ // are reference types, so that we can insert casts to perform the same adaptation
+ // that the closure object would.
+
+ val isStatic = implMethod.getTag == Opcodes.H_INVOKESTATIC
+ val indyParamTypes = Type.getArgumentTypes(indy.desc)
+ val instantiatedMethodArgTypes = instantiatedMethodType.getArgumentTypes
+ val expectedImplMethodType = {
+ val paramTypes = (if (isStatic) indyParamTypes else indyParamTypes.tail) ++ instantiatedMethodArgTypes
+ Type.getMethodType(instantiatedMethodType.getReturnType, paramTypes: _*)
+ }
+
+ val isIndyLambda = (
+ Type.getType(implMethod.getDesc) == expectedImplMethodType // (1)
+ && (isStatic || implMethod.getOwner == indyParamTypes(0).getInternalName) // (2)
+ && samMethodType.getArgumentTypes.corresponds(instantiatedMethodArgTypes)((samArgType, instArgType) =>
+ samArgType == instArgType || isReference(samArgType) && isReference(instArgType)) // (3)
+ )
+
+ if (isIndyLambda) Some((indy, samMethodType, implMethod, instantiatedMethodType))
+ else None
+
+ case _ => None
+ }
+ case _ => None
+ }
+ }
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala
index 1648a53ed8..b0dc6ead1b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala
@@ -8,8 +8,9 @@ package backend.jvm
package opt
import scala.annotation.switch
+import scala.collection.immutable
import scala.reflect.internal.util.NoPosition
-import scala.tools.asm.{Handle, Type, Opcodes}
+import scala.tools.asm.{Type, Opcodes}
import scala.tools.asm.tree._
import scala.tools.nsc.backend.jvm.BTypes.InternalName
import scala.tools.nsc.backend.jvm.analysis.ProdConsAnalyzer
@@ -23,90 +24,157 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
import btypes._
import callGraph._
+ /**
+ * If a closure is allocated and invoked within the same method, re-write the invocation to the
+ * closure body method.
+ *
+ * Note that the closure body method (generated by delambdafy:method) takes additional parameters
+ * for the values captured by the closure. The bytecode is transformed from
+ *
+ * [generate captured values]
+ * [closure init, capturing values]
+ * [...]
+ * [load closure object]
+ * [generate closure invocation arguments]
+ * [invoke closure.apply]
+ *
+ * to
+ *
+ * [generate captured values]
+ * [store captured values into new locals]
+ * [load the captured values from locals] // a future optimization will eliminate the closure
+ * [closure init, capturing values] // instantiation if the closure object becomes unused
+ * [...]
+ * [load closure object]
+ * [generate closure invocation arguments]
+ * [store argument values into new locals]
+ * [drop the closure object]
+ * [load captured values from locals]
+ * [load argument values from locals]
+ * [invoke the closure body method]
+ */
def rewriteClosureApplyInvocations(): Unit = {
- closureInstantiations foreach {
- case (indy, (methodNode, ownerClass)) =>
- val warnings = rewriteClosureApplyInvocations(indy, methodNode, ownerClass)
- warnings.foreach(w => backendReporting.inlinerWarning(w.pos, w.toString))
+ implicit object closureInitOrdering extends Ordering[ClosureInstantiation] {
+ override def compare(x: ClosureInstantiation, y: ClosureInstantiation): Int = {
+ val cls = x.ownerClass.internalName compareTo y.ownerClass.internalName
+ if (cls != 0) return cls
+
+ val mName = x.ownerMethod.name compareTo y.ownerMethod.name
+ if (mName != 0) return mName
+
+ val mDesc = x.ownerMethod.desc compareTo y.ownerMethod.desc
+ if (mDesc != 0) return mDesc
+
+ def pos(inst: ClosureInstantiation) = inst.ownerMethod.instructions.indexOf(inst.lambdaMetaFactoryCall.indy)
+ pos(x) - pos(y)
+ }
}
- }
- private val lambdaMetaFactoryInternalName: InternalName = "java/lang/invoke/LambdaMetafactory"
+ // Grouping the closure instantiations by method allows running the ProdConsAnalyzer only once per
+ // method. Also sort the instantiations: If there are multiple closure instantiations in a method,
+ // closure invocations need to be re-written in a consistent order for bytecode stability. The local
+ // variable slots for storing captured values depends on the order of rewriting.
+ val closureInstantiationsByMethod: Map[MethodNode, immutable.TreeSet[ClosureInstantiation]] = {
+ closureInstantiations.values.groupBy(_.ownerMethod).mapValues(immutable.TreeSet.empty ++ _)
+ }
- private val metafactoryHandle = {
- val metafactoryMethodName: String = "metafactory"
- val metafactoryDesc: String = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"
- new Handle(H_INVOKESTATIC, lambdaMetaFactoryInternalName, metafactoryMethodName, metafactoryDesc)
- }
+ // For each closure instantiation, a list of callsites of the closure that can be re-written
+ // If a callsite cannot be rewritten, for example because the lambda body method is not accessible,
+ // a warning is returned instead.
+ val callsitesToRewrite: List[(ClosureInstantiation, List[Either[RewriteClosureApplyToClosureBodyFailed, (MethodInsnNode, Int)]])] = {
+ closureInstantiationsByMethod.iterator.flatMap({
+ case (methodNode, closureInits) =>
+ // A lazy val to ensure the analysis only runs if necessary (the value is passed by name to `closureCallsites`)
+ lazy val prodCons = new ProdConsAnalyzer(methodNode, closureInits.head.ownerClass.internalName)
+ closureInits.iterator.map(init => (init, closureCallsites(init, prodCons)))
+ }).toList // mapping to a list (not a map) to keep the sorting of closureInstantiationsByMethod
+ }
- private val altMetafactoryHandle = {
- val altMetafactoryMethodName: String = "altMetafactory"
- val altMetafactoryDesc: String = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"
- new Handle(H_INVOKESTATIC, lambdaMetaFactoryInternalName, altMetafactoryMethodName, altMetafactoryDesc)
+ // Rewrite all closure callsites (or issue inliner warnings for those that cannot be rewritten)
+ for ((closureInit, callsites) <- callsitesToRewrite) {
+ // Local variables that hold the captured values and the closure invocation arguments.
+ // They are lazy vals to ensure that locals for captured values are only allocated if there's
+ // actually a callsite to rewrite (an not only warnings to be issued).
+ lazy val (localsForCapturedValues, argumentLocalsList) = localsForClosureRewrite(closureInit)
+ for (callsite <- callsites) callsite match {
+ case Left(warning) =>
+ backendReporting.inlinerWarning(warning.pos, warning.toString)
+
+ case Right((invocation, stackHeight)) =>
+ rewriteClosureApplyInvocation(closureInit, invocation, stackHeight, localsForCapturedValues, argumentLocalsList)
+ }
+ }
}
- def isClosureInstantiation(indy: InvokeDynamicInsnNode): Boolean = {
- (indy.bsm == metafactoryHandle || indy.bsm == altMetafactoryHandle) &&
- {
- indy.bsmArgs match {
- case Array(samMethodType: Type, implMethod: Handle, instantiatedMethodType: Type, xs @ _*) =>
- // LambdaMetaFactory performs a number of automatic adaptations when invoking the lambda
- // implementation method (casting, boxing, unboxing, and primitive widening, see Javadoc).
- //
- // The closure optimizer supports only one of those adaptations: it will cast arguments
- // to the correct type when re-writing a closure call to the body method. Example:
- //
- // val fun: String => String = l => l
- // val l = List("")
- // fun(l.head)
- //
- // The samMethodType of Function1 is `(Object)Object`, while the instantiatedMethodType
- // is `(String)String`. The return type of `List.head` is `Object`.
- //
- // The implMethod has the signature `C$anonfun(String)String`.
- //
- // At the closure callsite, we have an `INVOKEINTERFACE Function1.apply (Object)Object`,
- // so the object returned by `List.head` can be directly passed into the call (no cast).
- //
- // The closure object will cast the object to String before passing it to the implMethod.
- //
- // When re-writing the closure callsite to the implMethod, we have to insert a cast.
- //
- // The check below ensures that
- // (1) the implMethod type has the expected singature (captured types plus argument types
- // from instantiatedMethodType)
- // (2) the receiver of the implMethod matches the first captured type
- // (3) all parameters that are not the same in samMethodType and instantiatedMethodType
- // are reference types, so that we can insert casts to perform the same adaptation
- // that the closure object would.
-
- val isStatic = implMethod.getTag == H_INVOKESTATIC
- val indyParamTypes = Type.getArgumentTypes(indy.desc)
- val instantiatedMethodArgTypes = instantiatedMethodType.getArgumentTypes
- val expectedImplMethodType = {
- val paramTypes = (if (isStatic) indyParamTypes else indyParamTypes.tail) ++ instantiatedMethodArgTypes
- Type.getMethodType(instantiatedMethodType.getReturnType, paramTypes: _*)
- }
-
- {
- Type.getType(implMethod.getDesc) == expectedImplMethodType // (1)
- } && {
- isStatic || implMethod.getOwner == indyParamTypes(0).getInternalName // (2)
- } && {
- def isReference(t: Type) = t.getSort == Type.OBJECT || t.getSort == Type.ARRAY
- (samMethodType.getArgumentTypes, instantiatedMethodArgTypes).zipped forall {
- case (samArgType, instArgType) =>
- samArgType == instArgType || isReference(samArgType) && isReference(instArgType) // (3)
- }
- }
-
+ /**
+ * Insert instructions to store the values captured by a closure instantiation into local variables,
+ * and load the values back to the stack.
+ *
+ * Returns the list of locals holding those captured values, and a list of locals that should be
+ * used at the closure invocation callsite to store the arguments passed to the closure invocation.
+ */
+ private def localsForClosureRewrite(closureInit: ClosureInstantiation): (LocalsList, LocalsList) = {
+ val ownerMethod = closureInit.ownerMethod
+ val captureLocals = storeCaptures(closureInit)
+
+ // allocate locals for storing the arguments of the closure apply callsites.
+ // if there are multiple callsites, the same locals are re-used.
+ val argTypes = closureInit.lambdaMetaFactoryCall.samMethodType.getArgumentTypes
+ val firstArgLocal = ownerMethod.maxLocals
+
+ // The comment in the unapply method of `LambdaMetaFactoryCall` explains why we have to introduce
+ // casts for arguments that have different types in samMethodType and instantiatedMethodType.
+ val castLoadTypes = {
+ val instantiatedMethodType = closureInit.lambdaMetaFactoryCall.instantiatedMethodType
+ (argTypes, instantiatedMethodType.getArgumentTypes).zipped map {
+ case (samArgType, instantiatedArgType) if samArgType != instantiatedArgType =>
+ // the LambdaMetaFactoryCall extractor ensures that the two types are reference types,
+ // so we don't end up casting primitive values.
+ Some(instantiatedArgType)
case _ =>
- false
+ None
}
}
+ val argLocals = LocalsList.fromTypes(firstArgLocal, argTypes, castLoadTypes)
+ ownerMethod.maxLocals = firstArgLocal + argLocals.size
+
+ (captureLocals, argLocals)
+ }
+
+ /**
+ * Find all callsites of a closure within the method where the closure is allocated.
+ */
+ private def closureCallsites(closureInit: ClosureInstantiation, prodCons: => ProdConsAnalyzer): List[Either[RewriteClosureApplyToClosureBodyFailed, (MethodInsnNode, Int)]] = {
+ val ownerMethod = closureInit.ownerMethod
+ val ownerClass = closureInit.ownerClass
+ val lambdaBodyHandle = closureInit.lambdaMetaFactoryCall.implMethod
+
+ ownerMethod.instructions.iterator.asScala.collect({
+ case invocation: MethodInsnNode if isSamInvocation(invocation, closureInit, prodCons) =>
+ // TODO: This is maybe over-cautious.
+ // We are checking if the closure body method is accessible at the closure callsite.
+ // If the closure allocation has access to the body method, then the callsite (in the same
+ // method as the alloction) should have access too.
+ val bodyAccessible: Either[OptimizerWarning, Boolean] = for {
+ (bodyMethodNode, declClass) <- byteCodeRepository.methodNode(lambdaBodyHandle.getOwner, lambdaBodyHandle.getName, lambdaBodyHandle.getDesc): Either[OptimizerWarning, (MethodNode, InternalName)]
+ isAccessible <- inliner.memberIsAccessible(bodyMethodNode.access, classBTypeFromParsedClassfile(declClass), classBTypeFromParsedClassfile(lambdaBodyHandle.getOwner), ownerClass)
+ } yield {
+ isAccessible
+ }
+
+ def pos = callGraph.callsites.get(invocation).map(_.callsitePosition).getOrElse(NoPosition)
+ val stackSize: Either[RewriteClosureApplyToClosureBodyFailed, Int] = bodyAccessible match {
+ case Left(w) => Left(RewriteClosureAccessCheckFailed(pos, w))
+ case Right(false) => Left(RewriteClosureIllegalAccess(pos, ownerClass.internalName))
+ case _ => Right(prodCons.frameAt(invocation).getStackSize)
+ }
+
+ stackSize.right.map((invocation, _))
+ }).toList
}
- def isSamInvocation(invocation: MethodInsnNode, indy: InvokeDynamicInsnNode, prodCons: => ProdConsAnalyzer): Boolean = {
+ private def isSamInvocation(invocation: MethodInsnNode, closureInit: ClosureInstantiation, prodCons: => ProdConsAnalyzer): Boolean = {
+ val indy = closureInit.lambdaMetaFactoryCall.indy
if (invocation.getOpcode == INVOKESTATIC) false
else {
def closureIsReceiver = {
@@ -120,20 +188,95 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
}
invocation.name == indy.name && {
- val indySamMethodDesc = indy.bsmArgs(0).asInstanceOf[Type].getDescriptor // safe, checked in isClosureInstantiation
+ val indySamMethodDesc = closureInit.lambdaMetaFactoryCall.samMethodType.getDescriptor
indySamMethodDesc == invocation.desc
} &&
- closureIsReceiver // most expensive check last
+ closureIsReceiver // most expensive check last
+ }
+ }
+
+ private def rewriteClosureApplyInvocation(closureInit: ClosureInstantiation, invocation: MethodInsnNode, stackHeight: Int, localsForCapturedValues: LocalsList, argumentLocalsList: LocalsList): Unit = {
+ val ownerMethod = closureInit.ownerMethod
+ val lambdaBodyHandle = closureInit.lambdaMetaFactoryCall.implMethod
+
+ // store arguments
+ insertStoreOps(invocation, ownerMethod, argumentLocalsList)
+
+ // drop the closure from the stack
+ ownerMethod.instructions.insertBefore(invocation, new InsnNode(POP))
+
+ // load captured values and arguments
+ insertLoadOps(invocation, ownerMethod, localsForCapturedValues)
+ insertLoadOps(invocation, ownerMethod, argumentLocalsList)
+
+ // update maxStack
+ val capturesStackSize = localsForCapturedValues.size
+ val invocationStackHeight = stackHeight + capturesStackSize - 1 // -1 because the closure is gone
+ if (invocationStackHeight > ownerMethod.maxStack)
+ ownerMethod.maxStack = invocationStackHeight
+
+ // replace the callsite with a new call to the body method
+ val bodyOpcode = (lambdaBodyHandle.getTag: @switch) match {
+ case H_INVOKEVIRTUAL => INVOKEVIRTUAL
+ case H_INVOKESTATIC => INVOKESTATIC
+ case H_INVOKESPECIAL => INVOKESPECIAL
+ case H_INVOKEINTERFACE => INVOKEINTERFACE
+ case H_NEWINVOKESPECIAL =>
+ val insns = ownerMethod.instructions
+ insns.insertBefore(invocation, new TypeInsnNode(NEW, lambdaBodyHandle.getOwner))
+ insns.insertBefore(invocation, new InsnNode(DUP))
+ INVOKESPECIAL
}
+ val isInterface = bodyOpcode == INVOKEINTERFACE
+ val bodyInvocation = new MethodInsnNode(bodyOpcode, lambdaBodyHandle.getOwner, lambdaBodyHandle.getName, lambdaBodyHandle.getDesc, isInterface)
+ ownerMethod.instructions.insertBefore(invocation, bodyInvocation)
+
+ val returnType = Type.getReturnType(lambdaBodyHandle.getDesc)
+ fixLoadedNothingOrNullValue(returnType, bodyInvocation, ownerMethod, btypes) // see comment of that method
+
+ ownerMethod.instructions.remove(invocation)
+
+ // update the call graph
+ val originalCallsite = callGraph.callsites.remove(invocation)
+
+ // the method node is needed for building the call graph entry
+ val bodyMethod = byteCodeRepository.methodNode(lambdaBodyHandle.getOwner, lambdaBodyHandle.getName, lambdaBodyHandle.getDesc)
+ def bodyMethodIsBeingCompiled = byteCodeRepository.classNodeAndSource(lambdaBodyHandle.getOwner).map(_._2 == CompilationUnit).getOrElse(false)
+ val bodyMethodCallsite = Callsite(
+ callsiteInstruction = bodyInvocation,
+ callsiteMethod = ownerMethod,
+ callsiteClass = closureInit.ownerClass,
+ callee = bodyMethod.map({
+ case (bodyMethodNode, bodyMethodDeclClass) => Callee(
+ callee = bodyMethodNode,
+ calleeDeclarationClass = classBTypeFromParsedClassfile(bodyMethodDeclClass),
+ safeToInline = compilerSettings.YoptInlineGlobal || bodyMethodIsBeingCompiled,
+ safeToRewrite = false, // the lambda body method is not a trait interface method
+ annotatedInline = false,
+ annotatedNoInline = false,
+ calleeInfoWarning = None)
+ }),
+ argInfos = Nil,
+ callsiteStackHeight = invocationStackHeight,
+ receiverKnownNotNull = true, // see below (*)
+ callsitePosition = originalCallsite.map(_.callsitePosition).getOrElse(NoPosition)
+ )
+ // (*) The documentation in class LambdaMetafactory says:
+ // "if implMethod corresponds to an instance method, the first capture argument
+ // (corresponding to the receiver) must be non-null"
+ // Explanation: If the lambda body method is non-static, the receiver is a captured
+ // value. It can only be captured within some instance method, so we know it's non-null.
+ callGraph.callsites(bodyInvocation) = bodyMethodCallsite
}
/**
- * Stores the values captured by a closure creation into fresh local variables.
- * Returns the list of locals holding the captured values.
+ * Stores the values captured by a closure creation into fresh local variables, and loads the
+ * values back onto the stack. Returns the list of locals holding the captured values.
*/
- private def storeCaptures(indy: InvokeDynamicInsnNode, methodNode: MethodNode): LocalsList = {
+ private def storeCaptures(closureInit: ClosureInstantiation): LocalsList = {
+ val indy = closureInit.lambdaMetaFactoryCall.indy
val capturedTypes = Type.getArgumentTypes(indy.desc)
- val firstCaptureLocal = methodNode.maxLocals
+ val firstCaptureLocal = closureInit.ownerMethod.maxLocals
// This could be optimized: in many cases the captured values are produced by LOAD instructions.
// If the variable is not modified within the method, we could avoid introducing yet another
@@ -144,10 +287,10 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
// This is checked in `isClosureInstantiation`: the types of the captured variables in the indy
// instruction match exactly the corresponding parameter types in the body method.
val localsForCaptures = LocalsList.fromTypes(firstCaptureLocal, capturedTypes, castLoadTypes = _ => None)
- methodNode.maxLocals = firstCaptureLocal + localsForCaptures.size
+ closureInit.ownerMethod.maxLocals = firstCaptureLocal + localsForCaptures.size
- insertStoreOps(indy, methodNode, localsForCaptures)
- insertLoadOps(indy, methodNode, localsForCaptures)
+ insertStoreOps(indy, closureInit.ownerMethod, localsForCaptures)
+ insertLoadOps(indy, closureInit.ownerMethod, localsForCaptures)
localsForCaptures
}
@@ -184,145 +327,6 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
}
}
- def rewriteClosureApplyInvocations(indy: InvokeDynamicInsnNode, methodNode: MethodNode, ownerClass: ClassBType): List[RewriteClosureApplyToClosureBodyFailed] = {
- val lambdaBodyHandle = indy.bsmArgs(1).asInstanceOf[Handle] // safe, checked in isClosureInstantiation
-
- // Kept as a lazy val to make sure the analysis is only computed if it's actually needed.
- // ProdCons is used to identify closure body invocations (see isSamInvocation), but only if the
- // callsite has the right name and signature. If the method has no invcation instruction with
- // the right name and signature, the analysis is not executed.
- lazy val prodCons = new ProdConsAnalyzer(methodNode, ownerClass.internalName)
-
- // First collect all callsites without modifying the instructions list yet.
- // Once we start modifying the instruction list, prodCons becomes unusable.
-
- // A list of callsites and stack heights. If the invocation cannot be rewritten, a warning
- // message is stored in the stack height value.
- val invocationsToRewrite: List[(MethodInsnNode, Either[RewriteClosureApplyToClosureBodyFailed, Int])] = methodNode.instructions.iterator.asScala.collect({
- case invocation: MethodInsnNode if isSamInvocation(invocation, indy, prodCons) =>
- val bodyAccessible: Either[OptimizerWarning, Boolean] = for {
- (bodyMethodNode, declClass) <- byteCodeRepository.methodNode(lambdaBodyHandle.getOwner, lambdaBodyHandle.getName, lambdaBodyHandle.getDesc): Either[OptimizerWarning, (MethodNode, InternalName)]
- isAccessible <- inliner.memberIsAccessible(bodyMethodNode.access, classBTypeFromParsedClassfile(declClass), classBTypeFromParsedClassfile(lambdaBodyHandle.getOwner), ownerClass)
- } yield {
- isAccessible
- }
-
- def pos = callGraph.callsites.get(invocation).map(_.callsitePosition).getOrElse(NoPosition)
- val stackSize: Either[RewriteClosureApplyToClosureBodyFailed, Int] = bodyAccessible match {
- case Left(w) => Left(RewriteClosureAccessCheckFailed(pos, w))
- case Right(false) => Left(RewriteClosureIllegalAccess(pos, ownerClass.internalName))
- case _ => Right(prodCons.frameAt(invocation).getStackSize)
- }
-
- (invocation, stackSize)
- }).toList
-
- if (invocationsToRewrite.isEmpty) Nil
- else {
- // lazy val to make sure locals for captures and arguments are only allocated if there's
- // effectively a callsite to rewrite.
- lazy val (localsForCapturedValues, argumentLocalsList) = {
- val captureLocals = storeCaptures(indy, methodNode)
-
- // allocate locals for storing the arguments of the closure apply callsites.
- // if there are multiple callsites, the same locals are re-used.
- val argTypes = indy.bsmArgs(0).asInstanceOf[Type].getArgumentTypes // safe, checked in isClosureInstantiation
- val firstArgLocal = methodNode.maxLocals
-
- // The comment in `isClosureInstantiation` explains why we have to introduce casts for
- // arguments that have different types in samMethodType and instantiatedMethodType.
- val castLoadTypes = {
- val instantiatedMethodType = indy.bsmArgs(2).asInstanceOf[Type]
- (argTypes, instantiatedMethodType.getArgumentTypes).zipped map {
- case (samArgType, instantiatedArgType) if samArgType != instantiatedArgType =>
- // isClosureInstantiation ensures that the two types are reference types, so we don't
- // end up casting primitive values.
- Some(instantiatedArgType)
- case _ =>
- None
- }
- }
- val argLocals = LocalsList.fromTypes(firstArgLocal, argTypes, castLoadTypes)
- methodNode.maxLocals = firstArgLocal + argLocals.size
-
- (captureLocals, argLocals)
- }
-
- val warnings = invocationsToRewrite flatMap {
- case (invocation, Left(warning)) => Some(warning)
-
- case (invocation, Right(stackHeight)) =>
- // store arguments
- insertStoreOps(invocation, methodNode, argumentLocalsList)
-
- // drop the closure from the stack
- methodNode.instructions.insertBefore(invocation, new InsnNode(POP))
-
- // load captured values and arguments
- insertLoadOps(invocation, methodNode, localsForCapturedValues)
- insertLoadOps(invocation, methodNode, argumentLocalsList)
-
- // update maxStack
- val capturesStackSize = localsForCapturedValues.size
- val invocationStackHeight = stackHeight + capturesStackSize - 1 // -1 because the closure is gone
- if (invocationStackHeight > methodNode.maxStack)
- methodNode.maxStack = invocationStackHeight
-
- // replace the callsite with a new call to the body method
- val bodyOpcode = (lambdaBodyHandle.getTag: @switch) match {
- case H_INVOKEVIRTUAL => INVOKEVIRTUAL
- case H_INVOKESTATIC => INVOKESTATIC
- case H_INVOKESPECIAL => INVOKESPECIAL
- case H_INVOKEINTERFACE => INVOKEINTERFACE
- case H_NEWINVOKESPECIAL =>
- val insns = methodNode.instructions
- insns.insertBefore(invocation, new TypeInsnNode(NEW, lambdaBodyHandle.getOwner))
- insns.insertBefore(invocation, new InsnNode(DUP))
- INVOKESPECIAL
- }
- val isInterface = bodyOpcode == INVOKEINTERFACE
- val bodyInvocation = new MethodInsnNode(bodyOpcode, lambdaBodyHandle.getOwner, lambdaBodyHandle.getName, lambdaBodyHandle.getDesc, isInterface)
- methodNode.instructions.insertBefore(invocation, bodyInvocation)
- methodNode.instructions.remove(invocation)
-
- // update the call graph
- val originalCallsite = callGraph.callsites.remove(invocation)
-
- // the method node is needed for building the call graph entry
- val bodyMethod = byteCodeRepository.methodNode(lambdaBodyHandle.getOwner, lambdaBodyHandle.getName, lambdaBodyHandle.getDesc)
- def bodyMethodIsBeingCompiled = byteCodeRepository.classNodeAndSource(lambdaBodyHandle.getOwner).map(_._2 == CompilationUnit).getOrElse(false)
- val bodyMethodCallsite = Callsite(
- callsiteInstruction = bodyInvocation,
- callsiteMethod = methodNode,
- callsiteClass = ownerClass,
- callee = bodyMethod.map({
- case (bodyMethodNode, bodyMethodDeclClass) => Callee(
- callee = bodyMethodNode,
- calleeDeclarationClass = classBTypeFromParsedClassfile(bodyMethodDeclClass),
- safeToInline = compilerSettings.YoptInlineGlobal || bodyMethodIsBeingCompiled,
- safeToRewrite = false, // the lambda body method is not a trait interface method
- annotatedInline = false,
- annotatedNoInline = false,
- calleeInfoWarning = None)
- }),
- argInfos = Nil,
- callsiteStackHeight = invocationStackHeight,
- receiverKnownNotNull = true, // see below (*)
- callsitePosition = originalCallsite.map(_.callsitePosition).getOrElse(NoPosition)
- )
- // (*) The documentation in class LambdaMetafactory says:
- // "if implMethod corresponds to an instance method, the first capture argument
- // (corresponding to the receiver) must be non-null"
- // Explanation: If the lambda body method is non-static, the receiver is a captured
- // value. It can only be captured within some instance method, so we know it's non-null.
- callGraph.callsites(bodyInvocation) = bodyMethodCallsite
- None
- }
-
- warnings.toList
- }
- }
-
/**
* A list of local variables. Each local stores information about its type, see class [[Local]].
*/
@@ -355,7 +359,7 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
}
/**
- * Stores a local varaible index the opcode offset required for operating on that variable.
+ * Stores a local variable index the opcode offset required for operating on that variable.
*
* The xLOAD / xSTORE opcodes are in the following sequence: I, L, F, D, A, so the offset for
* a local variable holding a reference (`A`) is 4. See also method `getOpcode` in [[scala.tools.asm.Type]].
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
index e8e848161c..6b2786c1a3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
@@ -9,6 +9,7 @@ package opt
import scala.annotation.tailrec
import scala.tools.asm
+import asm.Handle
import asm.Opcodes._
import asm.tree._
import scala.collection.convert.decorateAsScala._
@@ -365,7 +366,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
clonedInstructions.insert(argStores)
- // label for the exit of the inlined functions. xRETURNs are rplaced by GOTOs to this label.
+ // label for the exit of the inlined functions. xRETURNs are replaced by GOTOs to this label.
val postCallLabel = newLabelNode
clonedInstructions.add(postCallLabel)
@@ -455,9 +456,9 @@ class Inliner[BT <: BTypes](val btypes: BT) {
case indy: InvokeDynamicInsnNode =>
callGraph.closureInstantiations.get(indy) match {
- case Some((methodNode, ownerClass)) =>
+ case Some(closureInit) =>
val newIndy = instructionMap(indy).asInstanceOf[InvokeDynamicInsnNode]
- callGraph.closureInstantiations(newIndy) = (callsiteMethod, callsiteClass)
+ callGraph.closureInstantiations(newIndy) = ClosureInstantiation(closureInit.lambdaMetaFactoryCall.copy(indy = newIndy), callsiteMethod, callsiteClass)
case None =>
}
@@ -687,9 +688,67 @@ class Inliner[BT <: BTypes](val btypes: BT) {
}
}
- case ivd: InvokeDynamicInsnNode =>
- // TODO @lry check necessary conditions to inline an indy, instead of giving up
- Right(false)
+ case _: InvokeDynamicInsnNode if destinationClass == calleeDeclarationClass =>
+ // within the same class, any indy instruction can be inlined
+ Right(true)
+
+ // does the InvokeDynamicInsnNode call LambdaMetaFactory?
+ case LambdaMetaFactoryCall(_, _, implMethod, _) =>
+ // an indy instr points to a "call site specifier" (CSP) [1]
+ // - a reference to a bootstrap method [2]
+ // - bootstrap method name
+ // - references to constant arguments, which can be:
+ // - constant (string, long, int, float, double)
+ // - class
+ // - method type (without name)
+ // - method handle
+ // - a method name+type
+ //
+ // execution [3]
+ // - resolve the CSP, yielding the bootstrap method handle, the static args and the name+type
+ // - resolution entails accessibility checking [4]
+ // - execute the `invoke` method of the bootstrap method handle (which is signature polymorphic, check its javadoc)
+ // - the descriptor for the call is made up from the actual arguments on the stack:
+ // - the first parameters are "MethodHandles.Lookup, String, MethodType", then the types of the constant arguments,
+ // - the return type is CallSite
+ // - the values for the call are
+ // - the bootstrap method handle of the CSP is the receiver
+ // - the Lookup object for the class in which the callsite occurs (obtained as through calling MethodHandles.lookup())
+ // - the method name of the CSP
+ // - the method type of the CSP
+ // - the constants of the CSP (primitives are not boxed)
+ // - the resulting `CallSite` object
+ // - has as `type` the method type of the CSP
+ // - is popped from the operand stack
+ // - the `invokeExact` method (signature polymorphic!) of the `target` method handle of the CallSite is invoked
+ // - the method descriptor is that of the CSP
+ // - the receiver is the target of the CallSite
+ // - the other argument values are those that were on the operand stack at the indy instruction (indyLambda: the captured values)
+ //
+ // [1] http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10
+ // [2] http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23
+ // [3] http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic
+ // [4] http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3
+
+ // We cannot generically check if an `invokedynamic` instruction can be safely inlined into
+ // a different class, that depends on the bootstrap method. The Lookup object passed to the
+ // bootstrap method is a capability to access private members of the callsite class. We can
+ // only move the invokedynamic to a new class if we know that the bootstrap method doesn't
+ // use this capability for otherwise non-accessible members.
+ // In the case of indyLambda, it depends on the visibility of the implMethod handle. If
+ // the implMethod is public, lambdaMetaFactory doesn't use the Lookup object's extended
+ // capability, and we can safely inline the instruction into a different class.
+
+ val methodRefClass = classBTypeFromParsedClassfile(implMethod.getOwner)
+ for {
+ (methodNode, methodDeclClassNode) <- byteCodeRepository.methodNode(methodRefClass.internalName, implMethod.getName, implMethod.getDesc): Either[OptimizerWarning, (MethodNode, InternalName)]
+ methodDeclClass = classBTypeFromParsedClassfile(methodDeclClassNode)
+ res <- memberIsAccessible(methodNode.access, methodDeclClass, methodRefClass, destinationClass)
+ } yield {
+ res
+ }
+
+ case _: InvokeDynamicInsnNode => Left(UnknownInvokeDynamicInstruction)
case ci: LdcInsnNode => ci.cst match {
case t: asm.Type => classIsAccessible(bTypeForDescriptorOrInternalNameFromClassfile(t.getInternalName), destinationClass)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
index bd5bab28b5..4132710a96 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
@@ -31,7 +31,7 @@ import scala.tools.nsc.backend.jvm.opt.BytecodeUtils._
* catch block, and the recursive invocation is not necessary.
*
* simplify jumps
- * - various simplifications, see doc domments of individual optimizations
+ * - various simplifications, see doc comments of individual optimizations
* + changing or eliminating jumps may render some code unreachable, therefore "simplify jumps" is
* executed in a loop with "unreachable code"
*
@@ -495,7 +495,7 @@ object LocalOptImpls {
* Replace jumps to a sequence of GOTO instructions by a jump to the final destination.
*
* Jump l; [any ops]; l: GOTO m; [any ops]; m: GOTO n; [any ops]; n: NotGOTO; [...]
- * => Jump n; [rest unchaned]
+ * => Jump n; [rest unchanged]
*
* If there's a loop of GOTOs, the initial jump is replaced by one of the labels in the loop.
*/
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala b/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala
index 0e6ee76eb2..fb1799e092 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala
@@ -170,9 +170,11 @@ abstract class ConstantOptimization extends SubComponent {
// out all the possibilities
case Impossible(possible2) => (possible -- possible2).nonEmpty
})
- def mightNotEqual(other: Contents): Boolean = (this ne other) && (other match {
- // two Possibles might not be equal if either has possible members that the other doesn't
- case Possible(possible2) => (possible -- possible2).nonEmpty || (possible2 -- possible).nonEmpty
+ def mightNotEqual(other: Contents): Boolean = (other match {
+ case Possible(possible2) =>
+ // two Possibles must equal if each is known to be of the same, single value
+ val mustEqual = possible.size == 1 && possible == possible2
+ !mustEqual
case Impossible(_) => true
})
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
index 425c10d153..9f6883f03f 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
@@ -343,7 +343,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
/**
* This function takes care of duplicating the basic block code for inlining the handler
*
- * Note: This function does not duplicate the same basic block twice. It wil contain a map of the duplicated
+ * Note: This function does not duplicate the same basic block twice. It will contain a map of the duplicated
* basic blocks
*/
private def duplicateExceptionHandlerCache(handler: BasicBlock) =
diff --git a/src/compiler/scala/tools/nsc/io/Jar.scala b/src/compiler/scala/tools/nsc/io/Jar.scala
index 2967f67e9c..efb026cdff 100644
--- a/src/compiler/scala/tools/nsc/io/Jar.scala
+++ b/src/compiler/scala/tools/nsc/io/Jar.scala
@@ -154,7 +154,7 @@ object Jar {
def update(key: Attributes.Name, value: String) = attrs.put(key, value)
}
- // See http://download.java.net/jdk7/docs/api/java/nio/file/Path.html
+ // See http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html
// for some ideas.
private val ZipMagicNumber = List[Byte](80, 75, 3, 4)
private def magicNumberIsZip(f: Path) = f.isFile && (f.toFile.bytes().take(4).toList == ZipMagicNumber)
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 9708cba281..eb25eb6e06 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -370,7 +370,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
flags |= Flags.FINAL
in.nextToken()
case DEFAULT =>
- flags |= Flags.DEFAULTMETHOD
+ flags |= Flags.JAVA_DEFAULTMETHOD
in.nextToken()
case NATIVE =>
addAnnot(NativeAttr)
@@ -489,8 +489,8 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
val vparams = formalParams()
if (!isVoid) rtpt = optArrayBrackets(rtpt)
optThrows()
- val isStatic = mods hasFlag Flags.STATIC
- val bodyOk = !inInterface || ((mods hasFlag Flags.DEFAULTMETHOD) || isStatic)
+ val isConcreteInterfaceMethod = !inInterface || (mods hasFlag Flags.JAVA_DEFAULTMETHOD) || (mods hasFlag Flags.STATIC)
+ val bodyOk = !(mods1 hasFlag Flags.DEFERRED) && isConcreteInterfaceMethod
val body =
if (bodyOk && in.token == LBRACE) {
methodBody()
@@ -509,7 +509,9 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
EmptyTree
}
}
- if (inInterface && !isStatic) mods1 |= Flags.DEFERRED
+ // for abstract methods (of classes), the `DEFERRED` flag is alredy set.
+ // here we also set it for interface methods that are not static and not default.
+ if (!isConcreteInterfaceMethod) mods1 |= Flags.DEFERRED
List {
atPos(pos) {
DefDef(mods1, name.toTermName, tparams, List(vparams), rtpt, body)
@@ -749,7 +751,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
val (statics, body) = typeBody(AT, name)
val templ = makeTemplate(annotationParents, body)
addCompanionObject(statics, atPos(pos) {
- ClassDef(mods, name, List(), templ)
+ ClassDef(mods | Flags.JAVA_ANNOTATION, name, List(), templ)
})
}
@@ -807,7 +809,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
if (hasAbstractMember) Flags.ABSTRACT else 0l
}
addCompanionObject(consts ::: statics ::: predefs, atPos(pos) {
- ClassDef(mods | Flags.ENUM | finalFlag | abstractFlag, name, List(),
+ ClassDef(mods | Flags.JAVA_ENUM | finalFlag | abstractFlag, name, List(),
makeTemplate(superclazz :: interfaces, body))
})
}
@@ -828,7 +830,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
skipAhead()
accept(RBRACE)
}
- ValDef(Modifiers(Flags.ENUM | Flags.STABLE | Flags.JAVA | Flags.STATIC), name.toTermName, enumType, blankExpr)
+ ValDef(Modifiers(Flags.JAVA_ENUM | Flags.STABLE | Flags.JAVA | Flags.STATIC), name.toTermName, enumType, blankExpr)
}
(res, hasClassBody)
}
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
index 1a5529140c..dd17750cd4 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
@@ -158,8 +158,8 @@ object Plugin {
def loop(qs: List[Path]): Try[PluginDescription] = qs match {
case Nil => Failure(new MissingPluginException(ps))
case p :: rest =>
- if (p.isDirectory) loadDescriptionFromFile(p.toDirectory / PluginXML)
- else if (p.isFile) loadDescriptionFromJar(p.toFile)
+ if (p.isDirectory) loadDescriptionFromFile(p.toDirectory / PluginXML) orElse loop(rest)
+ else if (p.isFile) loadDescriptionFromJar(p.toFile) orElse loop(rest)
else loop(rest)
}
loop(ps)
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 0cdece59e1..1817cfa25a 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -175,6 +175,7 @@ trait ScalaSettings extends AbsScalaSettings
val YconstOptimization = BooleanSetting ("-Yconst-opt", "Perform optimization with constant values.")
val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees.")
val noCompletion = BooleanSetting ("-Yno-completion", "Disable tab-completion in the REPL.")
+ val completion = ChoiceSetting ("-Ycompletion", "provider", "Select tab-completion in the REPL.", List("pc","adhoc","none"), "pc")
val Xdce = BooleanSetting ("-Ydead-code", "Perform dead code elimination.")
val debug = BooleanSetting ("-Ydebug", "Increase the quantity of debugging output.")
//val doc = BooleanSetting ("-Ydoc", "Generate documentation")
@@ -366,8 +367,8 @@ trait ScalaSettings extends AbsScalaSettings
*/
val YpresentationVerbose = BooleanSetting("-Ypresentation-verbose", "Print information about presentation compiler tasks.")
val YpresentationDebug = BooleanSetting("-Ypresentation-debug", "Enable debugging output for the presentation compiler.")
- val YpresentationStrict = BooleanSetting("-Ypresentation-strict", "Do not report type errors in sources with syntax errors.")
-
+ val YpresentationAnyThread = BooleanSetting("-Ypresentation-any-thread", "Allow use of the presentation compiler from any thread")
+ val YpresentationStrict = BooleanSetting("-Ypresentation-strict", "Do not report type errors in sources with syntax errors.")
val YpresentationLog = StringSetting("-Ypresentation-log", "file", "Log presentation compiler events into file", "")
val YpresentationReplay = StringSetting("-Ypresentation-replay", "file", "Replay presentation compiler events from file", "")
val YpresentationDelay = IntSetting("-Ypresentation-delay", "Wait number of ms after typing before starting typechecking", 0, Some((0, 999)), str => Some(str.toInt))
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 660028eab8..99e61d2482 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -84,6 +84,9 @@ abstract class ClassfileParser {
protected final def u2(): Int = in.nextChar.toInt
protected final def u4(): Int = in.nextInt
+ protected final def s1(): Int = in.nextByte.toInt // sign-extend the byte to int
+ protected final def s2(): Int = (in.nextByte.toInt << 8) | u1 // sign-extend and shift the first byte, or with the unsigned second byte
+
private def readInnerClassFlags() = readClassFlags()
private def readClassFlags() = JavaAccFlags classFlags u2
private def readMethodFlags() = JavaAccFlags methodFlags u2
@@ -284,7 +287,7 @@ abstract class ClassfileParser {
def getType(index: Int): Type = getType(null, index)
def getType(sym: Symbol, index: Int): Type = sigToType(sym, getExternalName(index))
- def getSuperClass(index: Int): Symbol = if (index == 0) AnyClass else getClassSymbol(index)
+ def getSuperClass(index: Int): Symbol = if (index == 0) AnyClass else getClassSymbol(index) // the only classfile that is allowed to have `0` in the super_class is java/lang/Object (see jvm spec)
private def createConstant(index: Int): Constant = {
val start = starts(index)
@@ -862,7 +865,7 @@ abstract class ClassfileParser {
srcfile0 = settings.outputDirs.srcFilesFor(in.file, srcpath).find(_.exists)
case tpnme.CodeATTR =>
if (sym.owner.isInterface) {
- sym setFlag DEFAULTMETHOD
+ sym setFlag JAVA_DEFAULTMETHOD
log(s"$sym in ${sym.owner} is a java8+ default method.")
}
in.skip(attrLen)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 438a71061e..b2f5a4119d 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -326,8 +326,8 @@ abstract class ICodeReader extends ClassfileParser {
case JVM.dconst_0 => code emit CONSTANT(Constant(0.0))
case JVM.dconst_1 => code emit CONSTANT(Constant(1.0))
- case JVM.bipush => code.emit(CONSTANT(Constant(u1))); size += 1
- case JVM.sipush => code.emit(CONSTANT(Constant(u2))); size += 2
+ case JVM.bipush => code.emit(CONSTANT(Constant(s1))); size += 1
+ case JVM.sipush => code.emit(CONSTANT(Constant(s2))); size += 2
case JVM.ldc => code.emit(CONSTANT(pool.getConstant(u1))); size += 1
case JVM.ldc_w => code.emit(CONSTANT(pool.getConstant(u2))); size += 2
case JVM.ldc2_w => code.emit(CONSTANT(pool.getConstant(u2))); size += 2
@@ -466,7 +466,7 @@ abstract class ICodeReader extends ClassfileParser {
size += 2
val local = code.getLocal(u1, INT)
code.emit(LOAD_LOCAL(local))
- code.emit(CONSTANT(Constant(u1)))
+ code.emit(CONSTANT(Constant(s1)))
code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT)))
code.emit(STORE_LOCAL(local))
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 79776485de..82e7c76409 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -111,7 +111,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
impl setInfo new LazyImplClassType(iface)
}
- /** Return the implementation class of a trait; create a new one of one does not yet exist */
+ /** Return the implementation class of a trait; create a new one if one does not yet exist */
def implClass(iface: Symbol): Symbol = {
iface.info
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 86685d46de..6a46c65267 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -137,7 +137,7 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
* and thus may only be accessed from value or method definitions owned by the current class
* (ie there's no point drilling down into nested classes).
*
- * (d) regarding candidates in (b), they are accesible from all places listed in (c) and in addition
+ * (d) regarding candidates in (b), they are accessible from all places listed in (c) and in addition
* from nested classes (nested at any number of levels).
*
* In all cases, we're done with traversing as soon as all candidates have been ruled out.
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index 5a7f6c52da..ea8c1cbaf6 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -281,7 +281,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val parents = addSerializable(abstractFunctionErasedType)
val funOwner = originalFunction.symbol.owner
- // TODO harmonize the naming of delamdafy anon-fun classes with those spun up by Uncurry
+ // TODO harmonize the naming of delambdafy anon-fun classes with those spun up by Uncurry
// - make `anonClass.isAnonymousClass` true.
// - use `newAnonymousClassSymbol` or push the required variations into a similar factory method
// - reinstate the assertion in `Erasure.resolveAnonymousBridgeClash`
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index df622d4d1d..b6695efb0b 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -168,7 +168,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
/** Add the bitmap definitions to the rhs of a method definition.
* If the rhs has been tail-call transformed, insert the bitmap
* definitions inside the top-level label definition, so that each
- * iteration has the lazy values un-initialized. Otherwise add them
+ * iteration has the lazy values uninitialized. Otherwise add them
* at the very beginning of the method.
*/
private def addBitmapDefs(methSym: Symbol, rhs: Tree): Tree = {
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 11f9483f77..a079a76ce7 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -79,9 +79,9 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** Does this field require an initialized bit?
* Note: fields of classes inheriting DelayedInit are not checked.
- * This is because the they are neither initialized in the constructor
+ * This is because they are neither initialized in the constructor
* nor do they have a setter (not if they are vals anyway). The usual
- * logic for setting bitmaps does therefor not work for such fields.
+ * logic for setting bitmaps does therefore not work for such fields.
* That's why they are excluded.
* Note: The `checkinit` option does not check if transient fields are initialized.
*/
@@ -1122,7 +1122,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
if (scope exists (_.isLazy)) {
val map = mutable.Map[Symbol, Set[Symbol]]() withDefaultValue Set()
// check what fields can be nulled for
- for ((field, users) <- singleUseFields(templ); lazyFld <- users)
+ for ((field, users) <- singleUseFields(templ); lazyFld <- users if !lazyFld.accessed.hasAnnotation(TransientAttr))
map(lazyFld) += field
map.toMap
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index b310e6c3a1..ee7c839de9 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -433,7 +433,7 @@ abstract class UnCurry extends InfoTransform
val sym = tree.symbol
- // true if the taget is a lambda body that's been lifted into a method
+ // true if the target is a lambda body that's been lifted into a method
def isLiftedLambdaBody(target: Tree) = target.symbol.isLocalToBlock && target.symbol.isArtifact && target.symbol.name.containsName(nme.ANON_FUN_NAME)
val result = (
@@ -475,13 +475,6 @@ abstract class UnCurry extends InfoTransform
withNeedLift(needLift = true) { super.transform(tree) }
else
super.transform(tree)
- case UnApply(fn, args) =>
- val fn1 = transform(fn)
- val args1 = fn.symbol.name match {
- case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, patmat.alignPatterns(global.typer.context, tree).expectedTypes)
- case _ => args
- }
- treeCopy.UnApply(tree, fn1, args1)
case Apply(fn, args) =>
val needLift = needTryLift || !fn.symbol.isLabel // SI-6749, no need to lift in args to label jumps.
@@ -691,9 +684,46 @@ abstract class UnCurry extends InfoTransform
// declared type and assign this to a synthetic val. Later, we'll patch
// the method body to refer to this, rather than the parameter.
val tempVal: ValDef = {
+ // SI-9442: using the "uncurry-erased" type (the one after the uncurry phase) can lead to incorrect
+ // tree transformations. For example, compiling:
+ // ```
+ // def foo(c: Ctx)(l: c.Tree): Unit = {
+ // val l2: c.Tree = l
+ // }
+ // ```
+ // Results in the following AST:
+ // ```
+ // def foo(c: Ctx, l: Ctx#Tree): Unit = {
+ // val l$1: Ctx#Tree = l.asInstanceOf[Ctx#Tree]
+ // val l2: c.Tree = l$1 // no, not really, it's not.
+ // }
+ // ```
+ // Of course, this is incorrect, since `l$1` has type `Ctx#Tree`, which is not a subtype of `c.Tree`.
+ //
+ // So what we need to do is to use the pre-uncurry type when creating `l$1`, which is `c.Tree` and is
+ // correct. Now, there are two additional problems:
+ // 1. when varargs and byname params are involved, the uncurry transformation desugares these special
+ // cases to actual typerefs, eg:
+ // ```
+ // T* ~> Seq[T] (Scala-defined varargs)
+ // T* ~> Array[T] (Java-defined varargs)
+ // =>T ~> Function0[T] (by name params)
+ // ```
+ // we use the DesugaredParameterType object (defined in scala.reflect.internal.transform.UnCurry)
+ // to redo this desugaring manually here
+ // 2. the type needs to be normalized, since `gen.mkCast` checks this (no HK here, just aliases have
+ // to be expanded before handing the type to `gen.mkAttributedCast`, which calls `gen.mkCast`)
+ val info0 =
+ enteringUncurry(p.symbol.info) match {
+ case DesugaredParameterType(desugaredTpe) =>
+ desugaredTpe
+ case tpe =>
+ tpe
+ }
+ val info = info0.normalize
val tempValName = unit freshTermName (p.name + "$")
- val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(p.symbol.info)
- atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), p.symbol.info)))
+ val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(info)
+ atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), info)))
}
Packed(newParam, tempVal)
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
index 49a4990722..62d9c497ba 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
@@ -38,7 +38,7 @@ trait Logic extends Debugging {
padded.transpose.map(alignedColumns).transpose map (_.mkString(sep)) mkString(lineSep)
}
- // http://www.cis.upenn.edu/~cis510/tcl/chap3.pdf
+ // ftp://ftp.cis.upenn.edu/pub/cis511/public_html/Spring04/chap3.pdf
// http://users.encs.concordia.ca/~ta_ahmed/ms_thesis.pdf
// propositional logic with constants and equality
trait PropositionalLogic {
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
index a11906ace1..1331eb6993 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -150,7 +150,11 @@ trait TreeAndTypeAnalysis extends Debugging {
acc: List[List[Type]]): List[List[Type]] = wl match {
case hd :: tl =>
val children = enumerateChildren(hd)
- groupChildren(tl ++ children, acc :+ filterChildren(children))
+ // put each trait in a new group, since traits could belong to the same
+ // group as a derived class
+ val (traits, nonTraits) = children.partition(_.isTrait)
+ val filtered = (traits.map(List(_)) ++ List(nonTraits)).map(filterChildren)
+ groupChildren(tl ++ children, acc ++ filtered)
case Nil => acc
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala
index 06b39b035a..1642613b9b 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala
@@ -134,7 +134,7 @@ trait MatchCodeGen extends Interface {
trait OptimizedCodegen extends CodegenCore with TypedSubstitution with MatchMonadInterface {
override def codegen: AbsCodegen = optimizedCodegen
- // when we know we're targetting Option, do some inlining the optimizer won't do
+ // when we know we're targeting Option, do some inlining the optimizer won't do
// for example, `o.flatMap(f)` becomes `if(o == None) None else f(o.get)`, similarly for orElse and guard
// this is a special instance of the advanced inlining optimization that takes a method call on
// an object of a type that only has two concrete subclasses, and inlines both bodies, guarded by an if to distinguish the two cases
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
index b3aef8a20e..cca8d2dbb8 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
@@ -286,8 +286,8 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis {
else Apply(Ident(defaultLabel), Nil)
val guardedBody = same.foldRight(jumpToDefault){
- // the last case may be un-guarded (we know it's the last one since fold's accum == jumpToDefault)
- // --> replace jumpToDefault by the un-guarded case's body
+ // the last case may be unguarded (we know it's the last one since fold's accum == jumpToDefault)
+ // --> replace jumpToDefault by the unguarded case's body
case (CaseDef(_, EmptyTree, b), `jumpToDefault`) => b
case (cd@CaseDef(_, g, b), els) if isGuardedCase(cd) => If(g, b, els)
}
@@ -322,7 +322,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis {
var remainingCases = cases
val collapsed = scala.collection.mutable.ListBuffer.empty[CaseDef]
- // when some of collapsed cases (except for the default case itself) did not include an un-guarded case
+ // when some of collapsed cases (except for the default case itself) did not include an unguarded case
// we'll need to emit a labeldef for the default case
var needDefault = false
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternExpander.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternExpander.scala
index e84ccbf754..1916050dd8 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/PatternExpander.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternExpander.scala
@@ -86,9 +86,25 @@ trait PatternExpander[Pattern, Type] {
* @param fixed The non-sequence types which are extracted
* @param repeated The sequence type which is extracted
*/
- final case class Extractor(whole: Type, fixed: List[Type], repeated: Repeated) {
+ final case class Extractor(whole: Type, fixed: List[Type], repeated: Repeated, typeOfSinglePattern: Type) {
require(whole != NoType, s"expandTypes($whole, $fixed, $repeated)")
+ /** A pattern with arity-1 that doesn't match the arity of the Product-like result of the `get` method,
+ * will match that result in its entirety. Example:
+ *
+ * {{{
+ * warning: there was one deprecation warning; re-run with -deprecation for details
+ * scala> object Extractor { def unapply(a: Any): Option[(Int, String)] = Some((1, "2")) }
+ * defined object Extractor
+ *
+ * scala> "" match { case Extractor(x: Int, y: String) => }
+ *
+ * scala> "" match { case Extractor(xy : (Int, String)) => }
+ * warning: there was one deprecation warning; re-run with -deprecation for details
+ * }}}
+ * */
+ def asSinglePattern: Extractor = copy(fixed = List(typeOfSinglePattern))
+
def productArity = fixed.length
def hasSeq = repeated.exists
def elementType = repeated.elementType
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
index b1783dc81f..d4f44303bb 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
@@ -43,8 +43,9 @@ trait ScalacPatternExpanders {
orElse definitions.elementType(ArrayClass, seq)
)
}
- def newExtractor(whole: Type, fixed: List[Type], repeated: Repeated): Extractor =
- logResult(s"newExtractor($whole, $fixed, $repeated")(Extractor(whole, fixed, repeated))
+ def newExtractor(whole: Type, fixed: List[Type], repeated: Repeated, typeOfSinglePattern: Type): Extractor =
+ logResult(s"newExtractor($whole, $fixed, $repeated, $typeOfSinglePattern")(Extractor(whole, fixed, repeated, typeOfSinglePattern))
+ def newExtractor(whole: Type, fixed: List[Type], repeated: Repeated): Extractor = newExtractor(whole, fixed, repeated, tupleType(fixed))
// Turn Seq[A] into Repeated(Seq[A], A, A*)
def repeatedFromSeq(seqType: Type): Repeated = {
@@ -73,26 +74,27 @@ trait ScalacPatternExpanders {
* Unfortunately the MethodType does not carry the information of whether
* it was unapplySeq, so we have to funnel that information in separately.
*/
- def unapplyMethodTypes(whole: Type, result: Type, isSeq: Boolean): Extractor = {
- val expanded = (
- if (result =:= BooleanTpe) Nil
- else typeOfMemberNamedGet(result) match {
+ def unapplyMethodTypes(context: Context, whole: Type, result: Type, isSeq: Boolean): Extractor = {
+ if (result =:= BooleanTpe) newExtractor(whole, Nil, NoRepeated)
+ else {
+ val getResult = typeOfMemberNamedGet(result)
+ def noGetError() = {
+ val name = "unapply" + (if (isSeq) "Seq" else "")
+ context.error(context.tree.pos, s"The result type of an $name method must contain a member `get` to be used as an extractor pattern, no such member exists in ${result}")
+ }
+ val expanded = getResult match {
+ case global.NoType => noGetError(); Nil
case rawGet if !hasSelectors(rawGet) => rawGet :: Nil
case rawGet => typesOfSelectors(rawGet)
}
- )
- expanded match {
- case init :+ last if isSeq => newExtractor(whole, init, repeatedFromSeq(last))
- case tps => newExtractor(whole, tps, NoRepeated)
+ expanded match {
+ case init :+ last if isSeq => newExtractor(whole, init, repeatedFromSeq(last), getResult)
+ case tps => newExtractor(whole, tps, NoRepeated, getResult)
+ }
}
}
}
object alignPatterns extends ScalacPatternExpander {
- /** Converts a T => (A, B, C) extractor to a T => ((A, B, CC)) extractor.
- */
- def tupleExtractor(extractor: Extractor): Extractor =
- extractor.copy(fixed = tupleType(extractor.fixed) :: Nil)
-
private def validateAligned(context: Context, tree: Tree, aligned: Aligned): Aligned = {
import aligned._
@@ -129,8 +131,8 @@ trait ScalacPatternExpanders {
val isUnapply = sel.symbol.name == nme.unapply
val extractor = sel.symbol.name match {
- case nme.unapply => unapplyMethodTypes(firstParamType(fn.tpe), sel.tpe, isSeq = false)
- case nme.unapplySeq => unapplyMethodTypes(firstParamType(fn.tpe), sel.tpe, isSeq = true)
+ case nme.unapply => unapplyMethodTypes(context, firstParamType(fn.tpe), sel.tpe, isSeq = false)
+ case nme.unapplySeq => unapplyMethodTypes(context, firstParamType(fn.tpe), sel.tpe, isSeq = true)
case _ => applyMethodTypes(fn.tpe)
}
@@ -142,12 +144,14 @@ trait ScalacPatternExpanders {
def acceptMessage = if (extractor.isErroneous) "" else s" to hold ${extractor.offeringString}"
val requiresTupling = isUnapply && patterns.totalArity == 1 && productArity > 1
- if (requiresTupling && effectivePatternArity(args) == 1) {
- val sym = sel.symbol.owner
- currentRun.reporting.deprecationWarning(sel.pos, sym, s"${sym} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
- }
-
- val normalizedExtractor = if (requiresTupling) tupleExtractor(extractor) else extractor
+ val normalizedExtractor = if (requiresTupling) {
+ val tupled = extractor.asSinglePattern
+ if (effectivePatternArity(args) == 1 && isTupleType(extractor.typeOfSinglePattern)) {
+ val sym = sel.symbol.owner
+ currentRun.reporting.deprecationWarning(sel.pos, sym, s"${sym} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
+ }
+ tupled
+ } else extractor
validateAligned(context, fn, Aligned(patterns, normalizedExtractor))
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
index fc632e0d0d..309b80f9ba 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
@@ -44,7 +44,7 @@ import scala.language.postfixOps
* which is essentially the intersection of X and |P|, where |P| is
* the erasure of P. If XR <: P, then no warning is emitted.
*
- * We evaluate "X with conform to P" by checking `X <: P_wild, where
+ * We evaluate "X with conform to P" by checking `X <: P_wild`, where
* P_wild is the result of substituting wildcard types in place of
* pattern type variables. This is intentionally stricter than
* (X matchesPattern P), see SI-8597 for motivating test cases.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index a7ef5d5d2f..e73a4c6276 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -168,13 +168,13 @@ trait Contexts { self: Analyzer =>
* fine grained control is needed based on the kind of error; ambiguity errors are often
* suppressed during exploratory typing, such as determining whether `a == b` in an argument
* position is an assignment or a named argument, when `Inferencer#isApplicableSafe` type checks
- * applications with and without an expected type, or whtn `Typer#tryTypedApply` tries to fit arguments to
+ * applications with and without an expected type, or when `Typer#tryTypedApply` tries to fit arguments to
* a function type with/without implicit views.
*
- * When the error policies entails error/warning buffering, the mutable [[ReportBuffer]] records
+ * When the error policies entail error/warning buffering, the mutable [[ReportBuffer]] records
* everything that is issued. It is important to note, that child Contexts created with `make`
* "inherit" the very same `ReportBuffer` instance, whereas children spawned through `makeSilent`
- * receive an separate, fresh buffer.
+ * receive a separate, fresh buffer.
*
* @param tree Tree associated with this context
* @param owner The current owner
@@ -574,19 +574,23 @@ trait Contexts { self: Analyzer =>
/** Issue/buffer/throw the given implicit ambiguity error according to the current mode for error reporting. */
private[typechecker] def issueAmbiguousError(err: AbsAmbiguousTypeError) = reporter.issueAmbiguousError(err)(this)
/** Issue/throw the given error message according to the current mode for error reporting. */
- def error(pos: Position, msg: String) = reporter.error(pos, msg)
+ def error(pos: Position, msg: String) = reporter.error(fixPosition(pos), msg)
/** Issue/throw the given error message according to the current mode for error reporting. */
- def warning(pos: Position, msg: String) = reporter.warning(pos, msg)
- def echo(pos: Position, msg: String) = reporter.echo(pos, msg)
+ def warning(pos: Position, msg: String) = reporter.warning(fixPosition(pos), msg)
+ def echo(pos: Position, msg: String) = reporter.echo(fixPosition(pos), msg)
+ def fixPosition(pos: Position): Position = pos match {
+ case NoPosition => nextEnclosing(_.tree.pos != NoPosition).tree.pos
+ case _ => pos
+ }
def deprecationWarning(pos: Position, sym: Symbol, msg: String): Unit =
- currentRun.reporting.deprecationWarning(pos, sym, msg)
+ currentRun.reporting.deprecationWarning(fixPosition(pos), sym, msg)
def deprecationWarning(pos: Position, sym: Symbol): Unit =
- currentRun.reporting.deprecationWarning(pos, sym) // TODO: allow this to escalate to an error, and implicit search will ignore deprecated implicits
+ currentRun.reporting.deprecationWarning(fixPosition(pos), sym) // TODO: allow this to escalate to an error, and implicit search will ignore deprecated implicits
def featureWarning(pos: Position, featureName: String, featureDesc: String, featureTrait: Symbol, construct: => String = "", required: Boolean): Unit =
- currentRun.reporting.featureWarning(pos, featureName, featureDesc, featureTrait, construct, required)
+ currentRun.reporting.featureWarning(fixPosition(pos), featureName, featureDesc, featureTrait, construct, required)
// nextOuter determines which context is searched next for implicits
@@ -819,7 +823,12 @@ trait Contexts { self: Analyzer =>
case List() =>
List()
case List(ImportSelector(nme.WILDCARD, _, _, _)) =>
- collectImplicits(pre.implicitMembers, pre, imported = true)
+ // Using pre.implicitMembers seems to exposes a problem with out-dated symbols in the IDE,
+ // see the example in https://www.assembla.com/spaces/scala-ide/tickets/1002552#/activity/ticket
+ // I haven't been able to boil that down the an automated test yet.
+ // Looking up implicit members in the package, rather than package object, here is at least
+ // consistent with what is done just below for named imports.
+ collectImplicits(qual.tpe.implicitMembers, pre, imported = true)
case ImportSelector(from, _, to, _) :: sels1 =>
var impls = collect(sels1) filter (info => info.name != from)
if (to != nme.WILDCARD) {
@@ -1239,7 +1248,7 @@ trait Contexts { self: Analyzer =>
type Error = AbsTypeError
type Warning = (Position, String)
- def issue(err: AbsTypeError)(implicit context: Context): Unit = handleError(err.errPos, addDiagString(err.errMsg))
+ def issue(err: AbsTypeError)(implicit context: Context): Unit = handleError(context.fixPosition(err.errPos), addDiagString(err.errMsg))
protected def handleError(pos: Position, msg: String): Unit
protected def handleSuppressedAmbiguous(err: AbsAmbiguousTypeError): Unit = ()
@@ -1256,7 +1265,7 @@ trait Contexts { self: Analyzer =>
* - else, let this context reporter decide
*/
final def issueAmbiguousError(err: AbsAmbiguousTypeError)(implicit context: Context): Unit =
- if (context.ambiguousErrors) reporter.error(err.errPos, addDiagString(err.errMsg)) // force reporting... see TODO above
+ if (context.ambiguousErrors) reporter.error(context.fixPosition(err.errPos), addDiagString(err.errMsg)) // force reporting... see TODO above
else handleSuppressedAmbiguous(err)
@inline final def withFreshErrorBuffer[T](expr: => T): T = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 11984da0d7..494e1e49b7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -110,10 +110,10 @@ trait Implicits {
* Ignore their constr field! The list of type constraints returned along with each tree specifies the constraints that
* must be met by the corresponding type parameter in `tpars` (for the returned implicit view to be valid).
*
- * @arg tp from-type for the implicit conversion
- * @arg context search implicits here
- * @arg tpars symbols that should be considered free type variables
- * (implicit search should not try to solve them, just track their constraints)
+ * @param tp from-type for the implicit conversion
+ * @param context search implicits here
+ * @param tpars symbols that should be considered free type variables
+ * (implicit search should not try to solve them, just track their constraints)
*/
def allViewsFrom(tp: Type, context: Context, tpars: List[Symbol]): List[(SearchResult, List[TypeConstraint])] = {
// my untouchable typevars are better than yours (they can't be constrained by them)
@@ -324,8 +324,10 @@ trait Implicits {
*/
class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context, pos0: Position = NoPosition) extends Typer(context0) with ImplicitsContextErrors {
val searchId = implicitSearchId()
- private def typingLog(what: String, msg: => String) =
- typingStack.printTyping(tree, f"[search #$searchId] $what $msg")
+ private def typingLog(what: String, msg: => String) = {
+ if (printingOk(tree))
+ typingStack.printTyping(f"[search #$searchId] $what $msg")
+ }
import infer._
if (Statistics.canEnable) Statistics.incCounter(implicitSearchCount)
@@ -918,7 +920,7 @@ trait Implicits {
/** Returns all eligible ImplicitInfos and their SearchResults in a map.
*/
- def findAll() = linkedMapFrom(eligible)(typedImplicit(_, ptChecked = false, isLocalToCallsite))
+ def findAll() = linkedMapFrom(eligible)(x => try typedImplicit(x, ptChecked = false, isLocalToCallsite) finally context.reporter.clearAll())
/** Returns the SearchResult of the best match.
*/
@@ -1361,7 +1363,7 @@ trait Implicits {
val succstart = if (stats) Statistics.startTimer(oftypeSucceedNanos) else null
// SI-6667, never search companions after an ambiguous error in in-scope implicits
- val wasAmbigious = result.isAmbiguousFailure
+ val wasAmbiguous = result.isAmbiguousFailure
// TODO: encapsulate
val previousErrs = context.reporter.errors
@@ -1371,7 +1373,7 @@ trait Implicits {
// `materializeImplicit` does some preprocessing for `pt`
// is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`?
- if (result.isFailure && !wasAmbigious)
+ if (result.isFailure && !wasAmbiguous)
result = searchImplicit(implicitsOfExpectedType, isLocalToCallsite = false)
if (result.isFailure)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index ea0a9bb243..9f7bdf7aff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1117,7 +1117,7 @@ trait Infer extends Checkable {
// this is quite nasty: it destructively changes the info of the syms of e.g., method type params
// (see #3692, where the type param T's bounds were set to > : T <: T, so that parts looped)
- // the changes are rolled back by restoreTypeBounds, but might be unintentially observed in the mean time
+ // the changes are rolled back by restoreTypeBounds, but might be unintentionally observed in the mean time
def instantiateTypeVar(tvar: TypeVar) {
val tparam = tvar.origin.typeSymbol
val TypeBounds(lo0, hi0) = tparam.info.bounds
@@ -1375,7 +1375,7 @@ trait Infer extends Checkable {
* Otherwise, if there is no best alternative, error.
*
* @param argtpes0 contains the argument types. If an argument is named, as
- * "a = 3", the corresponding type is `NamedType("a", Int)'. If the name
+ * "a = 3", the corresponding type is `NamedType("a", Int)`. If the name
* of some NamedType does not exist in an alternative's parameter names,
* the type is replaces by `Unit`, i.e. the argument is treated as an
* assignment expression.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 10aefae20b..3ed128cbc5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -55,6 +55,13 @@ trait Macros extends MacroRuntimes with Traces with Helpers {
def globalSettings = global.settings
+ /** Obtains a `ClassLoader` instance used for macro expansion.
+ *
+ * By default a new `ScalaClassLoader` is created using the classpath
+ * from global and the classloader of self as parent.
+ *
+ * Mirrors with runtime definitions (e.g. Repl) need to adjust this method.
+ */
protected def findMacroClassLoader(): ClassLoader = {
val classpath = global.classPath.asURLs
macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath))
@@ -85,9 +92,9 @@ trait Macros extends MacroRuntimes with Traces with Helpers {
*/
case class MacroImplBinding(
// Is this macro impl a bundle (a trait extending *box.Macro) or a vanilla def?
- val isBundle: Boolean,
+ isBundle: Boolean,
// Is this macro impl blackbox (i.e. having blackbox.Context in its signature)?
- val isBlackbox: Boolean,
+ isBlackbox: Boolean,
// Java class name of the class that contains the macro implementation
// is used to load the corresponding object with Java reflection
className: String,
@@ -658,7 +665,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers {
//
// Situation #2 requires measures to be taken. If we're in it, then noone's going to help us infer
// the undetermined type params. Therefore we need to do something ourselves or otherwise this
- // expandee will forever remaing not expanded (see SI-5692). A traditional way out of this conundrum
+ // expandee will forever remain not expanded (see SI-5692). A traditional way out of this conundrum
// is to call `instantiate` and let the inferencer try to find the way out. It works for simple cases,
// but sometimes, if the inferencer lacks information, it will be forced to approximate.
//
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index c1655467e9..4ad81b60ae 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -145,8 +145,8 @@ trait Namers extends MethodSynthesis {
// while Scala's enum constants live directly in the class.
// We don't check for clazz.superClass == JavaEnumClass, because this causes a illegal
// cyclic reference error. See the commit message for details.
- if (context.unit.isJava) owner.companionClass.hasEnumFlag else owner.hasEnumFlag
- vd.mods.hasAllFlags(ENUM | STABLE | STATIC) && ownerHasEnumFlag
+ if (context.unit.isJava) owner.companionClass.hasJavaEnumFlag else owner.hasJavaEnumFlag
+ vd.mods.hasAllFlags(JAVA_ENUM | STABLE | STATIC) && ownerHasEnumFlag
}
def setPrivateWithin[T <: Symbol](tree: Tree, sym: T, mods: Modifiers): T =
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 4b30b4e436..c5abd756f8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -421,7 +421,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
overrideError("cannot be used here - classes can only override abstract types")
} else if (other.isEffectivelyFinal) { // (1.2)
overrideError("cannot override final member")
- } else if (!other.isDeferredOrDefault && !other.hasFlag(DEFAULTMETHOD) && !member.isAnyOverride && !member.isSynthetic) { // (*)
+ } else if (!other.isDeferredOrJavaDefault && !other.hasFlag(JAVA_DEFAULTMETHOD) && !member.isAnyOverride && !member.isSynthetic) { // (*)
// (*) Synthetic exclusion for (at least) default getters, fixes SI-5178. We cannot assign the OVERRIDE flag to
// the default getter: one default getter might sometimes override, sometimes not. Example in comment on ticket.
if (isNeitherInClass && !(other.owner isSubClass member.owner))
@@ -604,7 +604,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
def checkNoAbstractMembers(): Unit = {
// Avoid spurious duplicates: first gather any missing members.
def memberList = clazz.info.nonPrivateMembersAdmitting(VBRIDGE)
- val (missing, rest) = memberList partition (m => m.isDeferredNotDefault && !ignoreDeferred(m))
+ val (missing, rest) = memberList partition (m => m.isDeferredNotJavaDefault && !ignoreDeferred(m))
// Group missing members by the name of the underlying symbol,
// to consolidate getters and setters.
val grouped = missing groupBy (sym => analyzer.underlyingSymbol(sym).name)
@@ -1134,13 +1134,13 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
t hasSymbolWhich (_.accessedOrSelf == valOrDef.symbol)
case _ => false
}
- val trivialInifiniteLoop = (
+ val trivialInfiniteLoop = (
!valOrDef.isErroneous
&& !valOrDef.symbol.isValueParameter
&& valOrDef.symbol.paramss.isEmpty
&& callsSelf
)
- if (trivialInifiniteLoop)
+ if (trivialInfiniteLoop)
reporter.warning(valOrDef.rhs.pos, s"${valOrDef.symbol.fullLocationString} does nothing other than call itself recursively")
}
@@ -1182,11 +1182,23 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
private def eliminateModuleDefs(moduleDef: Tree): List[Tree] = exitingRefchecks {
val ModuleDef(_, _, impl) = moduleDef
val module = moduleDef.symbol
+ val moduleClass = module.moduleClass
val site = module.owner
val moduleName = module.name.toTermName
// The typer doesn't take kindly to seeing this ClassDef; we have to
// set NoType so it will be ignored.
- val cdef = ClassDef(module.moduleClass, impl) setType NoType
+ val cdef = ClassDef(moduleClass, impl) setType NoType
+
+ // This code is related to the fix of SI-9375, which stops adding `readResolve` methods to
+ // non-static (nested) modules. Before the fix, the method would cause the module accessor
+ // to become notPrivate. To prevent binary changes in the 2.11.x branch, we mimic that behavior.
+ // There is a bit of code duplication between here and SyntheticMethods. We cannot call
+ // makeNotPrivate already in SyntheticMethod: that is during type checking, and not all references
+ // are resolved yet, so we cannot rename a definition. This code doesn't exist in the 2.12.x branch.
+ def hasConcreteImpl(name: Name) = moduleClass.info.member(name).alternatives exists (m => !m.isDeferred)
+ val hadReadResolveBeforeSI9375 = moduleClass.isSerializable && !hasConcreteImpl(nme.readResolve)
+ if (hadReadResolveBeforeSI9375)
+ moduleClass.sourceModule.makeNotPrivate(moduleClass.sourceModule.owner)
// Create the module var unless the immediate owner is a class and
// the module var already exists there. See SI-5012, SI-6712.
@@ -1210,7 +1222,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
}
def matchingInnerObject() = {
val newFlags = (module.flags | STABLE) & ~MODULE
- val newInfo = NullaryMethodType(module.moduleClass.tpe)
+ val newInfo = NullaryMethodType(moduleClass.tpe)
val accessor = site.newMethod(moduleName, module.pos, newFlags) setInfoAndEnter newInfo
DefDef(accessor, Select(This(site), module)) :: Nil
@@ -1511,7 +1523,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
sym.isSourceMethod &&
sym.isCase &&
sym.name == nme.apply &&
- isClassTypeAccessible(tree)
+ isClassTypeAccessible(tree) &&
+ !tree.tpe.resultType.typeSymbol.primaryConstructor.isLessAccessibleThan(tree.symbol)
if (doTransform) {
tree foreach {
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index ea44b9dc39..92b0719ba3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -132,7 +132,7 @@ trait StdAttachments {
/** Marks the tree as a macro impl reference, which is a naked reference to a method.
*
* This is necessary for typechecking macro impl references (see `DefaultMacroCompiler.defaultResolveMacroImpl`),
- * because otherwise typing a naked reference will result in the "follow this method with `_' if you want to
+ * because otherwise typing a naked reference will result in the "follow this method with `_` if you want to
* treat it as a partially applied function" errors.
*
* This mark suppresses adapt except for when the annottee is a macro application.
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 966e8f1abe..1b3f066fc1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -322,6 +322,7 @@ trait SyntheticMethods extends ast.TreeDSL {
clazz.isModuleClass
&& clazz.isSerializable
&& !hasConcreteImpl(nme.readResolve)
+ && clazz.isStatic
)
def synthesize(): List[Tree] = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Tags.scala b/src/compiler/scala/tools/nsc/typechecker/Tags.scala
index 57dc74d2a0..56127f4026 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Tags.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Tags.scala
@@ -36,7 +36,7 @@ trait Tags {
* @param allowMaterialization If true (default) then the resolver is allowed to launch materialization macros when there's no class tag in scope.
* If false then materialization macros are prohibited from running.
*
- * @returns Tree that represents an `scala.reflect.ClassTag` for `tp` if everything is okay.
+ * @return Tree that represents an `scala.reflect.ClassTag` for `tp` if everything is okay.
* EmptyTree if the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
* EmptyTree if `allowMaterialization` is false, and there is no class tag in scope.
*/
@@ -57,7 +57,7 @@ trait Tags {
* @param allowMaterialization If true (default) then the resolver is allowed to launch materialization macros when there's no type tag in scope.
* If false then materialization macros are prohibited from running.
*
- * @returns Tree that represents a `scala.reflect.TypeTag` for `tp` if everything is okay.
+ * @return Tree that represents a `scala.reflect.TypeTag` for `tp` if everything is okay.
* EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
* EmptyTree if `allowMaterialization` is false, and there is no array tag in scope.
*/
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index a7d48ceb89..e8db8309f1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -262,7 +262,14 @@ abstract class TreeCheckers extends Analyzer {
checkedTyped(tree, mode, pt)
)
private def checkedTyped(tree: Tree, mode: Mode, pt: Type): Tree = {
- val typed = wrap(tree)(super.typed(tree, mode, pt))
+ val typed = wrap(tree)(super.typed(tree.clearType(), mode, pt))
+
+ // Vlad: super.typed returns null for package defs, why is that?
+ if (typed eq null)
+ return tree
+
+ if (typed.tpe ne null)
+ assert(!typed.tpe.isErroneous, "Tree has erroneous type: " + typed)
if (tree ne typed)
treesDiffer(tree, typed)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b5129af9ec..6b73a538df 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2725,7 +2725,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
*
* If 'T' is not fully defined, it is inferred by type checking
* `apply$body` without a result type before type checking the block.
- * The method's inferred result type is used instead of T`. [See test/files/pos/sammy_poly.scala]
+ * The method's inferred result type is used instead of `T`. [See test/files/pos/sammy_poly.scala]
*
* The `apply` method is identified by the argument `sam`; `S` corresponds to the argument `samClassTp`,
* and `resPt` is derived from `samClassTp` -- it may be fully defined, or not...
@@ -3305,7 +3305,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.3
//
// One can think of these methods as being infinitely overloaded. We create
- // a ficticious new cloned method symbol for each call site that takes on a signature
+ // a fictitious new cloned method symbol for each call site that takes on a signature
// governed by a) the argument types and b) the expected type
val args1 = typedArgs(args, forArgMode(fun, mode))
val pts = args1.map(_.tpe.deconst)
@@ -3558,6 +3558,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def typedAnnotation(ann: Tree, mode: Mode = EXPRmode): AnnotationInfo = {
var hasError: Boolean = false
val pending = ListBuffer[AbsTypeError]()
+ def ErroneousAnnotation = new ErroneousAnnotation().setOriginal(ann)
def finish(res: AnnotationInfo): AnnotationInfo = {
if (hasError) {
@@ -4106,7 +4107,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def resultingTypeTree(tpe: Type) = {
// we need symbol-ful originals for reification
- // hence we go the extra mile to hand-craft tis guy
+ // hence we go the extra mile to hand-craft this guy
val original = arg1 match {
case tt @ TypeTree() if tt.original != null => Annotated(ann, tt.original)
// this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)"
@@ -4258,7 +4259,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// in the special (though common) case where the types are equal, it pays to pack before comparing
// especially virtpatmat needs more aggressive unification of skolemized types
// this breaks src/library/scala/collection/immutable/TrieIterator.scala
- // annotated types need to be lubbed regardless (at least, continations break if you by pass them like this)
+ // annotated types need to be lubbed regardless (at least, continuations break if you bypass them like this)
def samePackedTypes = (
!isPastTyper
&& thenp1.tpe.annotations.isEmpty
@@ -4577,7 +4578,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
typed1(atPos(tree.pos)(Block(stats, Apply(expr, args) setPos tree.pos.makeTransparent)), mode, pt)
case Apply(fun, args) =>
normalTypedApply(tree, fun, args) match {
- case ArrayInstantiation(tree1) => typed(tree1, mode, pt)
+ case ArrayInstantiation(tree1) => if (tree1.isErrorTyped) tree1 else typed(tree1, mode, pt)
case Apply(Select(fun, nme.apply), _) if treeInfo.isSuperConstrCall(fun) => TooManyArgumentListsForConstructor(tree) //SI-5696
case tree1 => tree1
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala b/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala
index 550fd4e68d..37fbb73b85 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala
@@ -159,7 +159,7 @@ trait TypersTracking {
// Some trees which are typed with mind-numbing frequency and
// which add nothing by being printed. Did () type to Unit? Let's
// gamble on yes.
- private def printingOk(t: Tree) = printTypings && (settings.debug.value || !noPrint(t))
+ def printingOk(t: Tree) = printTypings && (settings.debug.value || !noPrint(t))
def noPrintTyping(t: Tree) = (t.tpe ne null) || !printingOk(t)
def noPrintAdapt(tree1: Tree, tree2: Tree) = !printingOk(tree1) || (
(tree1.tpe == tree2.tpe)
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index 8d4d07759f..2811520b67 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -22,7 +22,7 @@ import Jar.isJarOrZip
/** <p>
* This module provides star expansion of '-classpath' option arguments, behaves the same as
- * java, see [http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html]
+ * java, see [[http://docs.oracle.com/javase/6/docs/technotes/tools/windows/classpath.html]]
* </p>
*
* @author Stepan Koltsov
diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala
index 4ff7067a21..501546b8f6 100755..100644
--- a/src/compiler/scala/tools/nsc/util/DocStrings.scala
+++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala
@@ -37,7 +37,7 @@ object DocStrings {
/** Returns index of string `str` after `start` skipping longest
* sequence of space and tab characters, possibly also containing
* a single `*` character or the `/``**` sequence.
- * @pre start == str.length || str(start) == `\n'
+ * @pre start == str.length || str(start) == `\n`
*/
def skipLineLead(str: String, start: Int): Int =
if (start == str.length) start
@@ -49,7 +49,7 @@ object DocStrings {
else idx
}
- /** Skips to next occurrence of `\n' or to the position after the `/``**` sequence following index `start`.
+ /** Skips to next occurrence of `\n` or to the position after the `/``**` sequence following index `start`.
*/
def skipToEol(str: String, start: Int): Int =
if (start + 2 < str.length && (str charAt start) == '/' && (str charAt (start + 1)) == '*' && (str charAt (start + 2)) == '*') start + 3
diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
index ac63232967..e30d1ed7cd 100644
--- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala
+++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
@@ -1,9 +1,11 @@
package scala.tools
package reflect
+import scala.reflect.internal.util.ScalaClassLoader
import scala.tools.nsc.Global
import scala.tools.nsc.reporters.Reporter
import scala.tools.nsc.Settings
+import scala.tools.nsc.typechecker.Analyzer
/** A version of Global that uses reflection to get class
* infos, instead of reading class or source files.
@@ -11,6 +13,20 @@ import scala.tools.nsc.Settings
class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val rootClassLoader: ClassLoader)
extends Global(currentSettings, reporter) with scala.tools.reflect.ReflectSetup with scala.reflect.runtime.SymbolTable {
+ override lazy val analyzer = new {
+ val global: ReflectGlobal.this.type = ReflectGlobal.this
+ } with Analyzer {
+ /** Obtains the classLoader used for runtime macro expansion.
+ *
+ * Macro expansion can use everything available in [[global.classPath]] or [[rootClassLoader]].
+ * The [[rootClassLoader]] is used to obtain runtime defined macros.
+ */
+ override protected def findMacroClassLoader(): ClassLoader = {
+ val classpath = global.classPath.asURLs
+ ScalaClassLoader.fromURLs(classpath, rootClassLoader)
+ }
+ }
+
override def transformedType(sym: Symbol) =
postErasure.transformInfo(sym,
erasure.transformInfo(sym,
diff --git a/src/eclipse/interactive/.gitignore b/src/eclipse/interactive/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/interactive/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/eclipse/partest/.classpath b/src/eclipse/partest/.classpath
index 50757ad2ba..65848ea439 100644
--- a/src/eclipse/partest/.classpath
+++ b/src/eclipse/partest/.classpath
@@ -5,7 +5,7 @@
<classpathentry combineaccessrules="false" kind="src" path="/repl"/>
<classpathentry kind="var" path="M2_REPO/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/scala-sbt/test-interface/1.0/test-interface-1.0.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11/1.0.7/scala-partest_2.11-1.0.7.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11/1.0.9/scala-partest_2.11-1.0.9.jar"/>
<classpathentry kind="var" path="SCALA_BASEDIR/lib/ant/ant.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/>
diff --git a/src/eclipse/partest/.gitignore b/src/eclipse/partest/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/partest/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/eclipse/reflect/.gitignore b/src/eclipse/reflect/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/reflect/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/eclipse/repl/.gitignore b/src/eclipse/repl/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/repl/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/eclipse/scala-compiler/.gitignore b/src/eclipse/scala-compiler/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/scala-compiler/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/eclipse/scala-library/.gitignore b/src/eclipse/scala-library/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/scala-library/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/eclipse/scaladoc/.classpath b/src/eclipse/scaladoc/.classpath
index c8f0e89b8a..3db64f5b0d 100644
--- a/src/eclipse/scaladoc/.classpath
+++ b/src/eclipse/scaladoc/.classpath
@@ -6,8 +6,8 @@
<classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/>
<classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
<classpathentry combineaccessrules="false" kind="src" path="/partest-extras"/>
- <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-xml_2.11.0-M7/1.0.0-RC7/scala-xml_2.11.0-M7-1.0.0-RC7.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-parser-combinators_2.11.0-M7/1.0.0-RC5/scala-parser-combinators_2.11.0-M7-1.0.0-RC5.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11.0-M7/1.0.0-RC8/scala-partest_2.11.0-M7-1.0.0-RC8.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-xml_2.11/1.0.4/scala-xml_2.11-1.0.4.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-parser-combinators_2.11/1.0.4/scala-parser-combinators_2.11-1.0.4.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11/1.0.9/scala-partest_2.11-1.0.9.jar"/>
<classpathentry kind="output" path="build-quick-scaladoc"/>
</classpath>
diff --git a/src/eclipse/scaladoc/.gitignore b/src/eclipse/scaladoc/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/scaladoc/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/eclipse/scalap/.gitignore b/src/eclipse/scalap/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/scalap/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/eclipse/test-junit/.gitignore b/src/eclipse/test-junit/.gitignore
new file mode 100644
index 0000000000..fe789dd686
--- /dev/null
+++ b/src/eclipse/test-junit/.gitignore
@@ -0,0 +1,2 @@
+# what appears to be a Scala IDE-generated file
+.cache-main
diff --git a/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java b/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java
index 19237c9092..a7ef492057 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java
@@ -24,7 +24,7 @@ import java.util.Random;
* {@code ThreadLocalRandom.current().nextX(...)} (where
* {@code X} is {@code Int}, {@code Long}, etc).
* When all usages are of this form, it is never possible to
- * accidently share a {@code ThreadLocalRandom} across multiple threads.
+ * accidentally share a {@code ThreadLocalRandom} across multiple threads.
*
* <p>This class also provides additional commonly used bounded random
* generation methods.
diff --git a/src/intellij/interactive.iml.SAMPLE b/src/intellij/interactive.iml.SAMPLE
index 047b5c9069..267bd3f12b 100644
--- a/src/intellij/interactive.iml.SAMPLE
+++ b/src/intellij/interactive.iml.SAMPLE
@@ -11,5 +11,6 @@
<orderEntry type="module" module-name="library" />
<orderEntry type="module" module-name="reflect" />
<orderEntry type="library" name="starr" level="project" />
+ <orderEntry type="library" name="asm" level="project" />
</component>
</module> \ No newline at end of file
diff --git a/src/intellij/repl.iml.SAMPLE b/src/intellij/repl.iml.SAMPLE
index 7476f30131..e827a2c6d7 100644
--- a/src/intellij/repl.iml.SAMPLE
+++ b/src/intellij/repl.iml.SAMPLE
@@ -10,6 +10,7 @@
<orderEntry type="module" module-name="compiler" />
<orderEntry type="module" module-name="library" />
<orderEntry type="module" module-name="reflect" />
+ <orderEntry type="module" module-name="interactive" />
<orderEntry type="library" name="starr" level="project" />
<orderEntry type="library" name="repl-deps" level="project" />
<orderEntry type="library" name="asm" level="project" />
diff --git a/src/intellij/scaladoc.iml.SAMPLE b/src/intellij/scaladoc.iml.SAMPLE
index 4ba0a848c6..6e6d98b396 100644
--- a/src/intellij/scaladoc.iml.SAMPLE
+++ b/src/intellij/scaladoc.iml.SAMPLE
@@ -14,5 +14,6 @@
<orderEntry type="library" name="scaladoc-deps" level="project" />
<orderEntry type="library" name="ant" level="project" />
<orderEntry type="library" name="partest" level="project" />
+ <orderEntry type="library" name="asm" level="project" />
</component>
</module> \ No newline at end of file
diff --git a/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala b/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala
index 9caebb711d..586f011429 100644
--- a/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala
@@ -268,10 +268,12 @@ trait CompilerControl { self: Global =>
/** Info given for every member found by completion
*/
abstract class Member {
+ def prefix: Type
val sym: Symbol
val tpe: Type
val accessible: Boolean
def implicitlyAdded = false
+ def symNameDropLocal: Name = sym.name.dropLocal
private def accessible_s = if (accessible) "" else "[inaccessible] "
def forceInfoString = {
@@ -288,6 +290,8 @@ trait CompilerControl { self: Global =>
accessible: Boolean,
inherited: Boolean,
viaView: Symbol) extends Member {
+ // should be a case class parameter, but added as a var instead to preserve compatibility with the IDE
+ var prefix: Type = NoType
override def implicitlyAdded = viaView != NoSymbol
}
@@ -295,7 +299,10 @@ trait CompilerControl { self: Global =>
sym: Symbol,
tpe: Type,
accessible: Boolean,
- viaImport: Tree) extends Member
+ viaImport: Tree) extends Member {
+ // should be a case class parameter, but added as a var instead to preserve compatibility with the IDE
+ var prefix: Type = NoType
+ }
// items that get sent to scheduler
diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala
index 727bfdd510..6600fea2d8 100644
--- a/src/interactive/scala/tools/nsc/interactive/Global.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Global.scala
@@ -19,6 +19,7 @@ import scala.annotation.{ elidable, tailrec }
import scala.language.implicitConversions
import scala.tools.nsc.typechecker.Typers
import scala.util.control.Breaks._
+import scala.reflect.internal.Chars.isIdentifierStart
/**
* This trait allows the IDE to have an instance of the PC that
@@ -120,6 +121,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
val debugIDE: Boolean = settings.YpresentationDebug.value
val verboseIDE: Boolean = settings.YpresentationVerbose.value
+ private val anyThread: Boolean = settings.YpresentationAnyThread.value
private def replayName = settings.YpresentationReplay.value
private def logName = settings.YpresentationLog.value
@@ -532,7 +534,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
*/
@elidable(elidable.WARNING)
override def assertCorrectThread() {
- assert(initializing || onCompilerThread,
+ assert(initializing || anyThread || onCompilerThread,
"Race condition detected: You are running a presentation compiler method outside the PC thread.[phase: %s]".format(globalPhase) +
" Please file a ticket with the current stack trace at https://www.assembla.com/spaces/scala-ide/support/tickets")
}
@@ -661,7 +663,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
/** Make sure unit is typechecked
*/
- private def typeCheck(unit: RichCompilationUnit) {
+ private[scala] def typeCheck(unit: RichCompilationUnit) {
debugLog("type checking: "+unit)
parseAndEnter(unit)
unit.status = PartiallyChecked
@@ -792,7 +794,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
}
/** A fully attributed tree located at position `pos` */
- private[interactive] def typedTreeAt(pos: Position): Tree = getUnit(pos.source) match {
+ private[scala] def typedTreeAt(pos: Position): Tree = getUnit(pos.source) match {
case None =>
reloadSources(List(pos.source))
try typedTreeAt(pos)
@@ -998,7 +1000,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def add(sym: Symbol, pre: Type, implicitlyAdded: Boolean)(toMember: (Symbol, Type) => M) {
if ((sym.isGetter || sym.isSetter) && sym.accessed != NoSymbol) {
add(sym.accessed, pre, implicitlyAdded)(toMember)
- } else if (!sym.name.decodedName.containsName("$") && !sym.isSynthetic && sym.hasRawInfo) {
+ } else if (!sym.name.decodedName.containsName("$") && !sym.isError && !sym.isArtifact && sym.hasRawInfo) {
val symtpe = pre.memberType(sym) onTypeError ErrorType
matching(sym, symtpe, this(sym.name)) match {
case Some(m) =>
@@ -1030,10 +1032,12 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def addScopeMember(sym: Symbol, pre: Type, viaImport: Tree) =
locals.add(sym, pre, implicitlyAdded = false) { (s, st) =>
// imported val and var are always marked as inaccessible, but they could be accessed through their getters. SI-7995
- if (s.hasGetter)
+ val member = if (s.hasGetter)
new ScopeMember(s, st, context.isAccessible(s.getter, pre, superAccess = false), viaImport)
else
new ScopeMember(s, st, context.isAccessible(s, pre, superAccess = false), viaImport)
+ member.prefix = pre
+ member
}
def localsToEnclosing() = {
enclosing.addNonShadowed(locals)
@@ -1100,10 +1104,13 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def addTypeMember(sym: Symbol, pre: Type, inherited: Boolean, viaView: Symbol) = {
val implicitlyAdded = viaView != NoSymbol
members.add(sym, pre, implicitlyAdded) { (s, st) =>
- new TypeMember(s, st,
+ val result = new TypeMember(s, st,
context.isAccessible(if (s.hasGetter) s.getter(s.owner) else s, pre, superAccess && !implicitlyAdded),
inherited,
viaView)
+ result.prefix = pre
+ result
+
}
}
@@ -1147,6 +1154,112 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
}
}
+ sealed abstract class CompletionResult {
+ type M <: Member
+ def results: List[M]
+ /** The (possibly partial) name detected that precedes the cursor */
+ def name: Name
+ /** Cursor Offset - positionDelta == position of the start of the name */
+ def positionDelta: Int
+ def matchingResults(nameMatcher: (Name) => Name => Boolean = entered => candidate => candidate.startsWith(entered)): List[M] = {
+ val enteredName = if (name == nme.ERROR) nme.EMPTY else name
+ val matcher = nameMatcher(enteredName)
+ results filter { (member: Member) =>
+ val symbol = member.sym
+ def isStable = member.tpe.isStable || member.sym.isStable || member.sym.getterIn(member.sym.owner).isStable
+ def isJunk = symbol.name.isEmpty || !isIdentifierStart(member.sym.name.charAt(0)) // e.g. <byname>
+ !isJunk && member.accessible && !symbol.isConstructor && (name.isEmpty || matcher(member.sym.name) && (symbol.name.isTermName == name.isTermName || name.isTypeName && isStable))
+ }
+ }
+ }
+ object CompletionResult {
+ final case class ScopeMembers(positionDelta: Int, results: List[ScopeMember], name: Name) extends CompletionResult {
+ type M = ScopeMember
+ }
+ final case class TypeMembers(positionDelta: Int, qualifier: Tree, tree: Tree, results: List[TypeMember], name: Name) extends CompletionResult {
+ type M = TypeMember
+ }
+ case object NoResults extends CompletionResult {
+ override def results = Nil
+ override def name = nme.EMPTY
+ override def positionDelta = 0
+
+ }
+ private val CamelRegex = "([A-Z][^A-Z]*)".r
+ private def camelComponents(s: String): List[String] = {
+ CamelRegex.findAllIn("X" + s).toList match { case head :: tail => head.drop(1) :: tail; case Nil => Nil }
+ }
+ def camelMatch(entered: Name): Name => Boolean = {
+ val enteredS = entered.toString
+ val enteredLowercaseSet = enteredS.toLowerCase().toSet
+
+ (candidate: Name) => {
+ def candidateChunks = camelComponents(candidate.toString)
+ // Loosely based on IntelliJ's autocompletion: the user can just write everything in
+ // lowercase, as we'll let `isl` match `GenIndexedSeqLike` or `isLovely`.
+ def lenientMatch(entered: String, candidate: List[String], matchCount: Int): Boolean = {
+ candidate match {
+ case Nil => entered.isEmpty && matchCount > 0
+ case head :: tail =>
+ val enteredAlternatives = Set(entered, entered.capitalize)
+ head.inits.filter(_.length <= entered.length).exists(init =>
+ enteredAlternatives.exists(entered =>
+ lenientMatch(entered.stripPrefix(init), tail, matchCount + (if (init.isEmpty) 0 else 1))
+ )
+ )
+ }
+ }
+ val containsAllEnteredChars = {
+ // Trying to rule out some candidates quickly before the more expensive `lenientMatch`
+ val candidateLowercaseSet = candidate.toString.toLowerCase().toSet
+ enteredLowercaseSet.diff(candidateLowercaseSet).isEmpty
+ }
+ containsAllEnteredChars && lenientMatch(enteredS, candidateChunks, 0)
+ }
+ }
+ }
+
+ final def completionsAt(pos: Position): CompletionResult = {
+ val focus1: Tree = typedTreeAt(pos)
+ def typeCompletions(tree: Tree, qual: Tree, nameStart: Int, name: Name): CompletionResult = {
+ val qualPos = qual.pos
+ val allTypeMembers = typeMembers(qualPos).toList.flatten
+ val positionDelta: Int = pos.start - nameStart
+ val subName: Name = name.newName(new String(pos.source.content, nameStart, pos.start - nameStart)).encodedName
+ CompletionResult.TypeMembers(positionDelta, qual, tree, allTypeMembers, subName)
+ }
+ focus1 match {
+ case imp@Import(i @ Ident(name), head :: Nil) if head.name == nme.ERROR =>
+ val allMembers = scopeMembers(pos)
+ val nameStart = i.pos.start
+ val positionDelta: Int = pos.start - nameStart
+ val subName = name.subName(0, pos.start - i.pos.start)
+ CompletionResult.ScopeMembers(positionDelta, allMembers, subName)
+ case imp@Import(qual, selectors) =>
+ selectors.reverseIterator.find(_.namePos <= pos.start) match {
+ case None => CompletionResult.NoResults
+ case Some(selector) =>
+ typeCompletions(imp, qual, selector.namePos, selector.name)
+ }
+ case sel@Select(qual, name) =>
+ val qualPos = qual.pos
+ def fallback = qualPos.end + 2
+ val source = pos.source
+ val nameStart: Int = (qualPos.end + 1 until focus1.pos.end).find(p =>
+ source.identifier(source.position(p)).exists(_.length > 0)
+ ).getOrElse(fallback)
+ typeCompletions(sel, qual, nameStart, name)
+ case Ident(name) =>
+ val allMembers = scopeMembers(pos)
+ val positionDelta: Int = pos.start - focus1.pos.start
+ val subName = name.subName(0, positionDelta)
+ CompletionResult.ScopeMembers(positionDelta, allMembers, subName)
+ case _ =>
+ CompletionResult.NoResults
+ }
+ }
+
+
/** Implements CompilerControl.askLoadedTyped */
private[interactive] def waitLoadedTyped(source: SourceFile, response: Response[Tree], keepLoaded: Boolean = false, onSameThread: Boolean = true) {
getUnit(source) match {
diff --git a/src/library-aux/scala/Any.scala b/src/library-aux/scala/Any.scala
index 1c25989c30..e6ed46740e 100644
--- a/src/library-aux/scala/Any.scala
+++ b/src/library-aux/scala/Any.scala
@@ -27,7 +27,7 @@ package scala
* w.print()
* }}}
*
- * See the [[http://docs.scala-lang.org/sips/pending/value-classes.html value classes guide]] for more
+ * See the [[http://docs.scala-lang.org/overviews/core/value-classes.html Value Classes and Universal Traits]] for more
* details on the interplay of universal traits and value classes.
*/
abstract class Any {
@@ -38,7 +38,7 @@ abstract class Any {
* - It is reflexive: for any instance `x` of type `Any`, `x.equals(x)` should return `true`.
* - It is symmetric: for any instances `x` and `y` of type `Any`, `x.equals(y)` should return `true` if and
* only if `y.equals(x)` returns `true`.
- * - It is transitive: for any instances `x`, `y`, and `z` of type `AnyRef` if `x.equals(y)` returns `true` and
+ * - It is transitive: for any instances `x`, `y`, and `z` of type `Any` if `x.equals(y)` returns `true` and
* `y.equals(z)` returns `true`, then `x.equals(z)` should return `true`.
*
* If you override this method, you should verify that your implementation remains an equivalence relation.
diff --git a/src/library-aux/scala/AnyRef.scala b/src/library-aux/scala/AnyRef.scala
index 8c1862e729..7217499da7 100644
--- a/src/library-aux/scala/AnyRef.scala
+++ b/src/library-aux/scala/AnyRef.scala
@@ -45,7 +45,7 @@ trait AnyRef extends Any {
*/
def synchronized[T](body: => T): T
- /** Tests whether the argument (`arg0`) is a reference to the receiver object (`this`).
+ /** Tests whether the argument (`that`) is a reference to the receiver object (`this`).
*
* The `eq` method implements an [[http://en.wikipedia.org/wiki/Equivalence_relation equivalence relation]] on
* non-null instances of `AnyRef`, and has three additional properties:
@@ -73,7 +73,7 @@ trait AnyRef extends Any {
/** The expression `x == that` is equivalent to `if (x eq null) that eq null else x.equals(that)`.
*
- * @param arg0 the object to compare against this object for equality.
+ * @param that the object to compare against this object for equality.
* @return `true` if the receiver object is equivalent to the argument; `false` otherwise.
*/
final def ==(that: Any): Boolean =
diff --git a/src/library/scala/AnyVal.scala b/src/library/scala/AnyVal.scala
index ff62948413..e861860196 100644
--- a/src/library/scala/AnyVal.scala
+++ b/src/library/scala/AnyVal.scala
@@ -48,9 +48,7 @@ package scala
*
* It's important to note that user-defined value classes are limited, and in some circumstances,
* still must allocate a value class instance at runtime. These limitations and circumstances are
- * explained in greater detail in the [[http://docs.scala-lang.org/overviews/core/value-classes.html Value Classes Guide]]
- * as well as in [[http://docs.scala-lang.org/sips/pending/value-classes.html SIP-15: Value Classes]],
- * the Scala Improvement Proposal.
+ * explained in greater detail in the [[http://docs.scala-lang.org/overviews/core/value-classes.html Value Classes and Universal Traits]].
*/
abstract class AnyVal extends Any {
def getClass(): Class[_ <: AnyVal] = null
diff --git a/src/library/scala/Equals.scala b/src/library/scala/Equals.scala
index f2f9ead44c..e06557ccdd 100644
--- a/src/library/scala/Equals.scala
+++ b/src/library/scala/Equals.scala
@@ -13,8 +13,9 @@ package scala
*/
trait Equals extends Any {
/** A method that should be called from every well-designed equals method
- * that is open to be overridden in a subclass. See Programming in Scala,
- * Chapter 28 for discussion and design.
+ * that is open to be overridden in a subclass. See
+ * [[http://www.artima.com/pins1ed/object-equality.html Programming in Scala,
+ * Chapter 28]] for discussion and design.
*
* @param that the value being probed for possible equality
* @return true if this instance can possibly equal `that`, otherwise false
diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala
index f134f5ce3d..7282feebb6 100644
--- a/src/library/scala/Option.scala
+++ b/src/library/scala/Option.scala
@@ -270,7 +270,7 @@ sealed abstract class Option[+A] extends Product with Serializable {
* // Returns None because the partial function doesn't cover the case.
* Some("ftp") collect {case "http" => "HTTP"}
*
- * // Returns None because None is passed to the collect method.
+ * // Returns None because the option is empty. There is no value to pass to the partial function.
* None collect {case value => value}
* }}}
*
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index cef62922ac..94cb331ce1 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -56,7 +56,7 @@ import scala.io.StdIn
* only contain natural numbers (i.e. non-negative), and that the result returned
* will also be natural. `require` is distinct from `assert` in that if the
* condition fails, then the caller of the function is to blame rather than a
- * logical error having been made within `addNaturals` itself. `ensures` is a
+ * logical error having been made within `addNaturals` itself. `ensuring` is a
* form of `assert` that declares the guarantee the function is providing with
* regards to its return value.
*
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index e60fa2f290..69533c12da 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -173,7 +173,7 @@ object StringContext {
/** An exception that is thrown if a string contains a backslash (`\`) character
* that does not start a valid escape sequence.
* @param str The offending string
- * @param idx The index of the offending backslash character in `str`.
+ * @param index The index of the offending backslash character in `str`.
*/
class InvalidEscapeException(str: String, @deprecatedName('idx) val index: Int) extends IllegalArgumentException(
s"""invalid escape ${
diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala
index f786293822..be1da1660a 100644
--- a/src/library/scala/collection/GenSeqLike.scala
+++ b/src/library/scala/collection/GenSeqLike.scala
@@ -274,7 +274,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal
* @tparam B the element type of the returned $coll.
* @tparam That $thatinfo
* @param bf $bfinfo
- * @return a new $coll` which is a copy of this $coll with the element at position `index` replaced by `elem`.
+ * @return a new $coll which is a copy of this $coll with the element at position `index` replaced by `elem`.
* @throws IndexOutOfBoundsException if `index` does not satisfy `0 <= index < length`.
*
* @usecase def updated(index: Int, elem: A): $Coll[A]
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index f77462ce88..a45ec965f5 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -393,20 +393,35 @@ trait GenTraversableOnce[+A] extends Any {
*/
def minBy[B](f: A => B)(implicit cmp: Ordering[B]): A
- def forall(pred: A => Boolean): Boolean
+ /** Tests whether a predicate holds for all elements of this $coll.
+ *
+ * $mayNotTerminateInf
+ *
+ * @param p the predicate used to test elements.
+ * @return `true` if this $coll is empty or the given predicate `p`
+ * holds for all elements of this $coll, otherwise `false`.
+ */
+ def forall(@deprecatedName('pred) p: A => Boolean): Boolean
- def exists(pred: A => Boolean): Boolean
+ /** Tests whether a predicate holds for at least one element of this $coll.
+ *
+ * $mayNotTerminateInf
+ *
+ * @param p the predicate used to test elements.
+ * @return `true` if the given predicate `p` is satisfied by at least one element of this $coll, otherwise `false`
+ */
+ def exists(@deprecatedName('pred) p: A => Boolean): Boolean
/** Finds the first element of the $coll satisfying a predicate, if any.
*
* $mayNotTerminateInf
* $orderDependent
*
- * @param pred the predicate used to test elements.
+ * @param p the predicate used to test elements.
* @return an option value containing the first element in the $coll
* that satisfies `p`, or `None` if none exists.
*/
- def find(pred: A => Boolean): Option[A]
+ def find(@deprecatedName('pred) p: A => Boolean): Option[A]
/** Copies values of this $coll to an array.
* Fills the given array `xs` with values of this $coll.
diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala
index a7e06b4d1a..a7e06b4d1a 100755..100644
--- a/src/library/scala/collection/IndexedSeqOptimized.scala
+++ b/src/library/scala/collection/IndexedSeqOptimized.scala
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index c9037eb3e3..b69e51fdf5 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -392,8 +392,16 @@ trait Iterator[+A] extends TraversableOnce[A] {
*/
def flatMap[B](f: A => GenTraversableOnce[B]): Iterator[B] = new AbstractIterator[B] {
private var cur: Iterator[B] = empty
- def hasNext: Boolean =
- cur.hasNext || self.hasNext && { cur = f(self.next()).toIterator; hasNext }
+ private def nextCur() { cur = f(self.next()).toIterator }
+ def hasNext: Boolean = {
+ // Equivalent to cur.hasNext || self.hasNext && { nextCur(); hasNext }
+ // but slightly shorter bytecode (better JVM inlining!)
+ while (!cur.hasNext) {
+ if (!self.hasNext) return false
+ nextCur()
+ }
+ true
+ }
def next(): B = (if (hasNext) cur else empty).next()
}
@@ -405,6 +413,7 @@ trait Iterator[+A] extends TraversableOnce[A] {
* @note Reuse: $consumesAndProducesIterator
*/
def filter(p: A => Boolean): Iterator[A] = new AbstractIterator[A] {
+ // TODO 2.12 - Make a full-fledged FilterImpl that will reverse sense of p
private var hd: A = _
private var hdDefined: Boolean = false
@@ -470,13 +479,27 @@ trait Iterator[+A] extends TraversableOnce[A] {
* @note Reuse: $consumesAndProducesIterator
*/
@migration("`collect` has changed. The previous behavior can be reproduced with `toSeq`.", "2.8.0")
- def collect[B](pf: PartialFunction[A, B]): Iterator[B] = {
- val self = buffered
- new AbstractIterator[B] {
- private def skip() = while (self.hasNext && !pf.isDefinedAt(self.head)) self.next()
- def hasNext = { skip(); self.hasNext }
- def next() = { skip(); pf(self.next()) }
+ def collect[B](pf: PartialFunction[A, B]): Iterator[B] = new AbstractIterator[B] {
+ // Manually buffer to avoid extra layer of wrapping with buffered
+ private[this] var hd: A = _
+
+ // Little state machine to keep track of where we are
+ // Seek = 0; Found = 1; Empty = -1
+ // Not in vals because scalac won't make them static (@inline def only works with -optimize)
+ // BE REALLY CAREFUL TO KEEP COMMENTS AND NUMBERS IN SYNC!
+ private[this] var status = 0/*Seek*/
+
+ def hasNext = {
+ while (status == 0/*Seek*/) {
+ if (self.hasNext) {
+ hd = self.next()
+ if (pf.isDefinedAt(hd)) status = 1/*Found*/
+ }
+ else status = -1/*Empty*/
+ }
+ status == 1/*Found*/
}
+ def next() = if (hasNext) { status = 0/*Seek*/; pf(hd) } else Iterator.empty.next()
}
/** Produces a collection containing cumulative results of applying the
@@ -578,33 +601,105 @@ trait Iterator[+A] extends TraversableOnce[A] {
* @note Reuse: $consumesOneAndProducesTwoIterators
*/
def span(p: A => Boolean): (Iterator[A], Iterator[A]) = {
- val self = buffered
-
- // Must be a named class to avoid structural call to finish from trailing iterator
+ /*
+ * Giving a name to following iterator (as opposed to trailing) because
+ * anonymous class is represented as a structural type that trailing
+ * iterator is referring (the finish() method) and thus triggering
+ * handling of structural calls. It's not what's intended here.
+ */
class Leading extends AbstractIterator[A] {
- private val drained = new mutable.Queue[A]
- private var finished = false
- def finish(): Unit = {
- require(!finished)
- finished = true
- while (selfish) drained += self.next
+ var lookahead: mutable.Queue[A] = null
+ var hd: A = _
+ /* Status is kept with magic numbers
+ * 1 means next element is in hd and we're still reading into this iterator
+ * 0 means we're still reading but haven't found a next element
+ * -1 means we are done reading into the iterator, so we must rely on lookahead
+ * -2 means we are done but have saved hd for the other iterator to use as its first element
+ */
+ var status = 0
+ private def store(a: A) {
+ if (lookahead == null) lookahead = new mutable.Queue[A]
+ lookahead += a
+ }
+ def hasNext = {
+ if (status < 0) (lookahead ne null) && lookahead.nonEmpty
+ else if (status > 0) true
+ else {
+ if (self.hasNext) {
+ hd = self.next()
+ status = if (p(hd)) 1 else -2
+ }
+ else status = -1
+ status > 0
+ }
}
- private def selfish = self.hasNext && p(self.head)
- def hasNext = if (finished) drained.nonEmpty else selfish
def next() = {
- if (finished) drained.dequeue()
- else if (selfish) self.next()
+ if (hasNext) {
+ if (status == 1) { status = 0; hd }
+ else lookahead.dequeue()
+ }
else empty.next()
}
+ def finish(): Boolean = {
+ if (status == -1) false
+ else if (status == -2) {
+ status = -1
+ true
+ }
+ else {
+ if (status == 1) store(hd)
+ while (self.hasNext) {
+ val a = self.next()
+ if (p(a)) store(a)
+ else {
+ hd = a
+ status = -1
+ return true
+ }
+ }
+ false
+ }
+ }
}
+
val leading = new Leading
+
val trailing = new AbstractIterator[A] {
- private lazy val it = {
- leading.finish()
- self
+ private[this] var myLeading = leading
+ /* Status flags meanings:
+ * -1 not yet accesssed
+ * 0 single element waiting in leading
+ * 1 defer to self
+ */
+ private[this] var status = -1
+ def hasNext = {
+ if (status > 0) self.hasNext
+ else {
+ if (status == 0) true
+ else if (myLeading.finish()) {
+ status = 0
+ true
+ }
+ else {
+ status = 1
+ myLeading = null
+ self.hasNext
+ }
+ }
}
- def hasNext = it.hasNext
- def next() = it.next()
+ def next() = {
+ if (hasNext) {
+ if (status > 0) self.next()
+ else {
+ status = 1
+ val ans = myLeading.hd
+ myLeading = null
+ ans
+ }
+ }
+ else Iterator.empty.next()
+ }
+
override def toString = "unknown-if-empty iterator"
}
@@ -618,18 +713,35 @@ trait Iterator[+A] extends TraversableOnce[A] {
* @return an iterator consisting of the remaining elements
* @note Reuse: $consumesAndProducesIterator
*/
- def dropWhile(p: A => Boolean): Iterator[A] = {
- val self = buffered
- new AbstractIterator[A] {
- var dropped = false
- private def skip() =
- if (!dropped) {
- while (self.hasNext && p(self.head)) self.next()
- dropped = true
+ def dropWhile(p: A => Boolean): Iterator[A] = new AbstractIterator[A] {
+ // Magic value: -1 = hasn't dropped, 0 = found first, 1 = defer to parent iterator
+ private[this] var status = -1
+ // Local buffering to avoid double-wrap with .buffered
+ private[this] var fst: A = _
+ def hasNext: Boolean =
+ if (status == 1) self.hasNext
+ else if (status == 0) true
+ else {
+ while (self.hasNext) {
+ val a = self.next()
+ if (!p(a)) {
+ fst = a
+ status = 0
+ return true
+ }
}
- def hasNext = { skip(); self.hasNext }
- def next() = { skip(); self.next() }
- }
+ status = 1
+ false
+ }
+ def next() =
+ if (hasNext) {
+ if (status == 1) self.next()
+ else {
+ status = 1
+ fst
+ }
+ }
+ else Iterator.empty.next()
}
/** Creates an iterator formed from this iterator and another iterator
@@ -777,7 +889,7 @@ trait Iterator[+A] extends TraversableOnce[A] {
* is equal (as determined by `==`) to `elem`, `false` otherwise.
* @note Reuse: $consumesIterator
*/
- def contains(elem: Any): Boolean = exists(_ == elem)
+ def contains(elem: Any): Boolean = exists(_ == elem) // Note--this seems faster than manual inlining!
/** Finds the first value produced by the iterator satisfying a
* predicate, if any.
@@ -789,12 +901,11 @@ trait Iterator[+A] extends TraversableOnce[A] {
* @note Reuse: $consumesIterator
*/
def find(p: A => Boolean): Option[A] = {
- var res: Option[A] = None
- while (res.isEmpty && hasNext) {
- val e = next()
- if (p(e)) res = Some(e)
+ while (hasNext) {
+ val a = next()
+ if (p(a)) return Some(a)
}
- res
+ None
}
/** Returns the index of the first produced value satisfying a predicate, or -1.
@@ -807,15 +918,11 @@ trait Iterator[+A] extends TraversableOnce[A] {
*/
def indexWhere(p: A => Boolean): Int = {
var i = 0
- var found = false
- while (!found && hasNext) {
- if (p(next())) {
- found = true
- } else {
- i += 1
- }
+ while (hasNext) {
+ if (p(next())) return i
+ i += 1
}
- if (found) i else -1
+ -1
}
/** Returns the index of the first occurrence of the specified
@@ -829,15 +936,11 @@ trait Iterator[+A] extends TraversableOnce[A] {
*/
def indexOf[B >: A](elem: B): Int = {
var i = 0
- var found = false
- while (!found && hasNext) {
- if (next() == elem) {
- found = true
- } else {
- i += 1
- }
+ while (hasNext) {
+ if (next() == elem) return i
+ i += 1
}
- if (found) i else -1
+ -1
}
/** Creates a buffered iterator from this iterator.
diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala
index 875f6e1c02..875f6e1c02 100755..100644
--- a/src/library/scala/collection/JavaConverters.scala
+++ b/src/library/scala/collection/JavaConverters.scala
diff --git a/src/library/scala/collection/LinearSeqOptimized.scala b/src/library/scala/collection/LinearSeqOptimized.scala
index 9c336e8e31..b426061537 100755..100644
--- a/src/library/scala/collection/LinearSeqOptimized.scala
+++ b/src/library/scala/collection/LinearSeqOptimized.scala
@@ -117,20 +117,20 @@ trait LinearSeqOptimized[+A, +Repr <: LinearSeqOptimized[A, Repr]] extends Linea
}
override /*TraversableLike*/
- def foldLeft[B](z: B)(f: (B, A) => B): B = {
+ def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = {
var acc = z
var these = this
while (!these.isEmpty) {
- acc = f(acc, these.head)
+ acc = op(acc, these.head)
these = these.tail
}
acc
}
override /*IterableLike*/
- def foldRight[B](z: B)(f: (A, B) => B): B =
+ def foldRight[B](z: B)(@deprecatedName('f) op: (A, B) => B): B =
if (this.isEmpty) z
- else f(head, tail.foldRight(z)(f))
+ else op(head, tail.foldRight(z)(op))
override /*TraversableLike*/
def reduceLeft[B >: A](f: (B, A) => B): B =
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index 96374ef653..04ae8c8aff 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -357,7 +357,7 @@ trait TraversableLike[+A, +Repr] extends Any
result
}
- /** Tests whether a predicate holds for some of the elements of this $coll.
+ /** Tests whether a predicate holds for at least one element of this $coll.
*
* $mayNotTerminateInf
*
diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala
index 9f9732c62f..e829a0215b 100644
--- a/src/library/scala/collection/convert/Wrappers.scala
+++ b/src/library/scala/collection/convert/Wrappers.scala
@@ -265,17 +265,11 @@ private[collection] trait Wrappers {
def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this }
def -=(key: A): this.type = { underlying remove key; this }
- override def put(k: A, v: B): Option[B] = {
- val r = underlying.put(k, v)
- if (r != null) Some(r) else None
- }
+ override def put(k: A, v: B): Option[B] = Option(underlying.put(k, v))
override def update(k: A, v: B) { underlying.put(k, v) }
- override def remove(k: A): Option[B] = {
- val r = underlying remove k
- if (r != null) Some(r) else None
- }
+ override def remove(k: A): Option[B] = Option(underlying remove k)
def iterator: Iterator[(A, B)] = new AbstractIterator[(A, B)] {
val ui = underlying.entrySet.iterator
@@ -326,25 +320,15 @@ private[collection] trait Wrappers {
* are not guaranteed to be atomic.
*/
case class JConcurrentMapWrapper[A, B](underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with concurrent.Map[A, B] {
- override def get(k: A) = {
- val v = underlying get k
- if (v != null) Some(v)
- else None
- }
+ override def get(k: A) = Option(underlying get k)
override def empty = new JConcurrentMapWrapper(new juc.ConcurrentHashMap[A, B])
- def putIfAbsent(k: A, v: B): Option[B] = {
- val r = underlying.putIfAbsent(k, v)
- if (r != null) Some(r) else None
- }
+ def putIfAbsent(k: A, v: B): Option[B] = Option(underlying.putIfAbsent(k, v))
def remove(k: A, v: B): Boolean = underlying.remove(k, v)
- def replace(k: A, v: B): Option[B] = {
- val prev = underlying.replace(k, v)
- if (prev != null) Some(prev) else None
- }
+ def replace(k: A, v: B): Option[B] = Option(underlying.replace(k, v))
def replace(k: A, oldvalue: B, newvalue: B): Boolean =
underlying.replace(k, oldvalue, newvalue)
@@ -380,25 +364,16 @@ private[collection] trait Wrappers {
case class JDictionaryWrapper[A, B](underlying: ju.Dictionary[A, B]) extends mutable.AbstractMap[A, B] with mutable.Map[A, B] {
override def size: Int = underlying.size
- def get(k: A) = {
- val v = underlying get k
- if (v != null) Some(v) else None
- }
+ def get(k: A) = Option(underlying get k)
def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this }
def -=(key: A): this.type = { underlying remove key; this }
- override def put(k: A, v: B): Option[B] = {
- val r = underlying.put(k, v)
- if (r != null) Some(r) else None
- }
+ override def put(k: A, v: B): Option[B] = Option(underlying.put(k, v))
override def update(k: A, v: B) { underlying.put(k, v) }
- override def remove(k: A): Option[B] = {
- val r = underlying remove k
- if (r != null) Some(r) else None
- }
+ override def remove(k: A): Option[B] = Option(underlying remove k)
def iterator = enumerationAsScalaIterator(underlying.keys) map (k => (k, underlying get k))
diff --git a/src/library/scala/collection/generic/FilterMonadic.scala b/src/library/scala/collection/generic/FilterMonadic.scala
index 8aefbdb926..8aefbdb926 100755..100644
--- a/src/library/scala/collection/generic/FilterMonadic.scala
+++ b/src/library/scala/collection/generic/FilterMonadic.scala
diff --git a/src/library/scala/collection/generic/HasNewBuilder.scala b/src/library/scala/collection/generic/HasNewBuilder.scala
index aa0ce6698d..aa0ce6698d 100755..100644
--- a/src/library/scala/collection/generic/HasNewBuilder.scala
+++ b/src/library/scala/collection/generic/HasNewBuilder.scala
diff --git a/src/library/scala/collection/immutable/DefaultMap.scala b/src/library/scala/collection/immutable/DefaultMap.scala
index e9b277b9c4..e9b277b9c4 100755..100644
--- a/src/library/scala/collection/immutable/DefaultMap.scala
+++ b/src/library/scala/collection/immutable/DefaultMap.scala
diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala
index f548eac88d..27b2bfdde7 100644
--- a/src/library/scala/collection/immutable/HashSet.scala
+++ b/src/library/scala/collection/immutable/HashSet.scala
@@ -162,13 +162,6 @@ class HashSet[A] extends AbstractSet[A]
def - (e: A): HashSet[A] =
nullToEmpty(removed0(e, computeHash(e), 0))
- /** Returns this $coll as an immutable set.
- *
- * A new set will not be built; lazy collections will stay lazy.
- */
- @deprecatedOverriding("Immutable sets should do nothing on toSet but return themselves cast as a Set.", "2.11.0")
- override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]
-
override def filter(p: A => Boolean) = {
val buffer = new Array[HashSet[A]](bufferSize(size))
nullToEmpty(filter0(p, false, 0, buffer, 0))
@@ -201,6 +194,7 @@ class HashSet[A] extends AbstractSet[A]
protected def writeReplace(): AnyRef = new HashSet.SerializationProxy(this)
+ override def toSet[B >: A]: Set[B] = this.asInstanceOf[HashSet[B]]
}
/** $factoryInfo
diff --git a/src/library/scala/collection/immutable/IntMap.scala b/src/library/scala/collection/immutable/IntMap.scala
index 8991d0b75a..cb6196e130 100644
--- a/src/library/scala/collection/immutable/IntMap.scala
+++ b/src/library/scala/collection/immutable/IntMap.scala
@@ -146,7 +146,7 @@ private[immutable] class IntMapKeyIterator[V](it: IntMap[V]) extends IntMapItera
import IntMap._
/** Specialised immutable map structure for integer keys, based on
- * <a href="http://citeseer.ist.psu.edu/okasaki98fast.html">Fast Mergeable Integer Maps</a>
+ * [[http://ittc.ku.edu/~andygill/papers/IntMap98.pdf Fast Mergeable Integer Maps]]
* by Okasaki and Gill. Essentially a trie based on binary digits of the integers.
*
* '''Note:''' This class is as of 2.8 largely superseded by HashMap.
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index 82e38d3549..53146bd66d 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -16,7 +16,7 @@ import scala.annotation.tailrec
import java.io._
/** A class for immutable linked lists representing ordered collections
- * of elements of type.
+ * of elements of type `A`.
*
* This class comes with two implementing case classes `scala.Nil`
* and `scala.::` that implement the abstract members `isEmpty`,
diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala
index a6e6fba0a5..adc975479a 100644
--- a/src/library/scala/collection/immutable/ListSet.scala
+++ b/src/library/scala/collection/immutable/ListSet.scala
@@ -138,13 +138,6 @@ class ListSet[A] extends AbstractSet[A]
override def stringPrefix = "ListSet"
- /** Returns this $coll as an immutable set.
- *
- * A new set will not be built; lazy collections will stay lazy.
- */
- @deprecatedOverriding("Immutable sets should do nothing on toSet but return themselves cast as a Set.", "2.11.0")
- override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]
-
/** Represents an entry in the `ListSet`.
*/
protected class Node(override val head: A) extends ListSet[A] with Serializable {
@@ -186,4 +179,6 @@ class ListSet[A] extends AbstractSet[A]
override def tail: ListSet[A] = self
}
+
+ override def toSet[B >: A]: Set[B] = this.asInstanceOf[ListSet[B]]
}
diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala
index 94a5b7929a..bd5b9c9faf 100644
--- a/src/library/scala/collection/immutable/MapLike.scala
+++ b/src/library/scala/collection/immutable/MapLike.scala
@@ -113,6 +113,11 @@ self =>
override def - (elem: A): immutable.Set[A] =
if (this(elem)) immutable.Set[A]() ++ this - elem
else this
+
+ // ImmutableDefaultKeySet is only protected, so we won't warn on override.
+ // Someone could override in a way that makes widening not okay
+ // (e.g. by overriding +, though the version in this class is fine)
+ override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]
}
/** This function transforms all the values of mappings contained
diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala
index 28e56a6d87..11603a118b 100644
--- a/src/library/scala/collection/immutable/NumericRange.scala
+++ b/src/library/scala/collection/immutable/NumericRange.scala
@@ -175,34 +175,68 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable {
catch { case _: ClassCastException => false }
final override def sum[B >: T](implicit num: Numeric[B]): B = {
- // arithmetic series formula can be used for regular addition
- if ((num eq scala.math.Numeric.IntIsIntegral)||
- (num eq scala.math.Numeric.BigIntIsIntegral)||
- (num eq scala.math.Numeric.ShortIsIntegral)||
- (num eq scala.math.Numeric.ByteIsIntegral)||
- (num eq scala.math.Numeric.CharIsIntegral)||
- (num eq scala.math.Numeric.LongIsIntegral)||
- (num eq scala.math.Numeric.FloatAsIfIntegral)||
- (num eq scala.math.Numeric.BigDecimalIsFractional)||
- (num eq scala.math.Numeric.DoubleAsIfIntegral)) {
- val numAsIntegral = num.asInstanceOf[Integral[B]]
- import numAsIntegral._
- if (isEmpty) num fromInt 0
- else if (numRangeElements == 1) head
- else ((num fromInt numRangeElements) * (head + last) / (num fromInt 2))
- } else {
- // user provided custom Numeric, we cannot rely on arithmetic series formula
- if (isEmpty) num.zero
+ if (isEmpty) num.zero
+ else if (numRangeElements == 1) head
+ else {
+ // If there is no overflow, use arithmetic series formula
+ // a + ... (n terms total) ... + b = n*(a+b)/2
+ if ((num eq scala.math.Numeric.IntIsIntegral)||
+ (num eq scala.math.Numeric.ShortIsIntegral)||
+ (num eq scala.math.Numeric.ByteIsIntegral)||
+ (num eq scala.math.Numeric.CharIsIntegral)) {
+ // We can do math with no overflow in a Long--easy
+ val exact = (numRangeElements * ((num toLong head) + (num toInt last))) / 2
+ num fromInt exact.toInt
+ }
+ else if (num eq scala.math.Numeric.LongIsIntegral) {
+ // Uh-oh, might be overflow, so we have to divide before we overflow.
+ // Either numRangeElements or (head + last) must be even, so divide the even one before multiplying
+ val a = head.toLong
+ val b = last.toLong
+ val ans =
+ if ((numRangeElements & 1) == 0) (numRangeElements / 2) * (a + b)
+ else numRangeElements * {
+ // Sum is even, but we might overflow it, so divide in pieces and add back remainder
+ val ha = a/2
+ val hb = b/2
+ ha + hb + ((a - 2*ha) + (b - 2*hb)) / 2
+ }
+ ans.asInstanceOf[B]
+ }
+ else if ((num eq scala.math.Numeric.FloatAsIfIntegral) ||
+ (num eq scala.math.Numeric.DoubleAsIfIntegral)) {
+ // Try to compute sum with reasonable accuracy, avoiding over/underflow
+ val numAsIntegral = num.asInstanceOf[Integral[B]]
+ import numAsIntegral._
+ val a = math.abs(head.toDouble)
+ val b = math.abs(last.toDouble)
+ val two = num fromInt 2
+ val nre = num fromInt numRangeElements
+ if (a > 1e38 || b > 1e38) nre * ((head / two) + (last / two)) // Compute in parts to avoid Infinity if possible
+ else (nre / two) * (head + last) // Don't need to worry about infinity; this will be more accurate and avoid underflow
+ }
+ else if ((num eq scala.math.Numeric.BigIntIsIntegral) ||
+ (num eq scala.math.Numeric.BigDecimalIsFractional)) {
+ // No overflow, so we can use arithmetic series formula directly
+ // (not going to worry about running out of memory)
+ val numAsIntegral = num.asInstanceOf[Integral[B]]
+ import numAsIntegral._
+ ((num fromInt numRangeElements) * (head + last)) / (num fromInt 2)
+ }
else {
- var acc = num.zero
- var i = head
- var idx = 0
- while(idx < length) {
- acc = num.plus(acc, i)
- i = i + step
- idx = idx + 1
+ // User provided custom Numeric, so we cannot rely on arithmetic series formula (e.g. won't work on something like Z_6)
+ if (isEmpty) num.zero
+ else {
+ var acc = num.zero
+ var i = head
+ var idx = 0
+ while(idx < length) {
+ acc = num.plus(acc, i)
+ i = i + step
+ idx = idx + 1
+ }
+ acc
}
- acc
}
}
}
diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala
index f11217d26a..a86d4b6746 100644
--- a/src/library/scala/collection/immutable/PagedSeq.scala
+++ b/src/library/scala/collection/immutable/PagedSeq.scala
@@ -190,8 +190,8 @@ extends scala.collection.AbstractSeq[T]
val e = if (_end == UndeterminedEnd) _end else start + _end
var f = first1
while (f.end <= s && !f.isLast) {
- if (f.next eq null) f.addMore(more)
- f = f.next
+ if (f.next eq null) f = f.addMore(more)
+ else f = f.next
}
// Warning -- not refining `more` means that slices can freely request and obtain
// data outside of their slice. This is part of the design of PagedSeq
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 3ae8a2c342..ca6720da19 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -153,19 +153,15 @@ extends scala.collection.AbstractSeq[Int]
}
@inline final override def foreach[@specialized(Unit) U](f: Int => U) {
- validateMaxLength()
- val isCommonCase = (start != Int.MinValue || end != Int.MinValue)
- var i = start
- var count = 0
- val terminal = terminalElement
- val step = this.step
- while(
- if(isCommonCase) { i != terminal }
- else { count < numRangeElements }
- ) {
- f(i)
- count += 1
- i += step
+ // Implementation chosen on the basis of favorable microbenchmarks
+ // Note--initialization catches step == 0 so we don't need to here
+ if (!isEmpty) {
+ var i = start
+ while (true) {
+ f(i)
+ if (i == lastElement) return
+ i += step
+ }
}
}
@@ -285,7 +281,7 @@ extends scala.collection.AbstractSeq[Int]
*/
final override def splitAt(n: Int) = (take(n), drop(n))
- /** Creates a new range consisting of the `length - n` last elements of the range.
+ /** Creates a new range consisting of the last `n` elements of the range.
*
* $doesNotUseBuilders
*/
@@ -347,18 +343,19 @@ extends scala.collection.AbstractSeq[Int]
// this is normal integer range with usual addition. arithmetic series formula can be used
if (isEmpty) 0
else if (numRangeElements == 1) head
- else (numRangeElements.toLong * (head + last) / 2).toInt
+ else ((numRangeElements * (head.toLong + last)) / 2).toInt
} else {
// user provided custom Numeric, we cannot rely on arithmetic series formula
if (isEmpty) num.toInt(num.zero)
else {
var acc = num.zero
var i = head
- while(i != terminalElement) {
+ while (true) {
acc = num.plus(acc, i)
+ if (i == lastElement) return num.toInt(acc)
i = i + step
}
- num.toInt(acc)
+ 0 // Never hit this--just to satisfy compiler since it doesn't know while(true) has type Nothing
}
}
}
diff --git a/src/library/scala/collection/immutable/RedBlackTree.scala b/src/library/scala/collection/immutable/RedBlackTree.scala
index 0dad106b29..afb4c9c552 100644
--- a/src/library/scala/collection/immutable/RedBlackTree.scala
+++ b/src/library/scala/collection/immutable/RedBlackTree.scala
@@ -168,7 +168,8 @@ object RedBlackTree {
}
/* Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees
- * http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html */
+ * Constructing Red-Black Trees, Ralf Hinze: http://www.cs.ox.ac.uk/ralf.hinze/publications/WAAAPL99b.ps.gz
+ * Red-Black Trees in a Functional Setting, Chris Okasaki: https://wiki.rice.edu/confluence/download/attachments/2761212/Okasaki-Red-Black.pdf */
private[this] def del[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else {
def balance(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) {
if (isRedTree(tr)) {
@@ -408,11 +409,11 @@ object RedBlackTree {
def cons[B](x: B, xs: NList[B]): NList[B] = new NList(x, xs)
- def foldLeft[A, B](xs: NList[A], z: B)(f: (B, A) => B): B = {
+ def foldLeft[A, B](xs: NList[A], z: B)(op: (B, A) => B): B = {
var acc = z
var these = xs
while (these ne null) {
- acc = f(acc, these.head)
+ acc = op(acc, these.head)
these = these.tail
}
acc
diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala
index 7725ad9ee3..031e5248c1 100644
--- a/src/library/scala/collection/immutable/Set.scala
+++ b/src/library/scala/collection/immutable/Set.scala
@@ -33,9 +33,24 @@ trait Set[A] extends Iterable[A]
with Parallelizable[A, ParSet[A]]
{
override def companion: GenericCompanion[Set] = Set
+
-
- override def toSet[B >: A]: Set[B] = to[({type l[a] = immutable.Set[B]})#l] // for bincompat; remove in dev
+ /** Returns this $coll as an immutable set, perhaps accepting a
+ * wider range of elements. Since it already is an
+ * immutable set, it will only be rebuilt if the underlying structure
+ * cannot be expanded to include arbitrary element types.
+ * For instance, `BitSet` and `SortedSet` will be rebuilt, as
+ * they require `Int` and sortable elements respectively.
+ *
+ * When in doubt, the set will be rebuilt. Rebuilt sets never
+ * need to be rebuilt again.
+ */
+ override def toSet[B >: A]: Set[B] = {
+ // This way of building sets typically has the best benchmarks, surprisingly!
+ val sb = Set.newBuilder[B]
+ foreach(sb += _)
+ sb.result()
+ }
override def seq: Set[A] = this
protected override def parCombiner = ParSet.newCombiner[A] // if `immutable.SetLike` gets introduced, please move this there!
@@ -48,7 +63,7 @@ trait Set[A] extends Iterable[A]
object Set extends ImmutableSetFactory[Set] {
/** $setCanBuildFromInfo */
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Set[A]] = setCanBuildFrom[A]
-
+
/** An optimized representation for immutable empty sets */
private object EmptySet extends AbstractSet[Any] with Set[Any] with Serializable {
override def size: Int = 0
@@ -56,7 +71,7 @@ object Set extends ImmutableSetFactory[Set] {
def + (elem: Any): Set[Any] = new Set1(elem)
def - (elem: Any): Set[Any] = this
def iterator: Iterator[Any] = Iterator.empty
- override def foreach[U](f: Any => U): Unit = {}
+ override def foreach[U](f: Any => U): Unit = ()
override def toSet[B >: Any]: Set[B] = this.asInstanceOf[Set[B]]
}
private[collection] def emptyInstance: Set[Any] = EmptySet
@@ -75,21 +90,23 @@ object Set extends ImmutableSetFactory[Set] {
else this
def iterator: Iterator[A] =
Iterator(elem1)
- override def foreach[U](f: A => U): Unit = {
+ override def foreach[U](f: A => U): Unit = {
f(elem1)
}
- override def exists(f: A => Boolean): Boolean = {
- f(elem1)
+ override def exists(@deprecatedName('f) p: A => Boolean): Boolean = {
+ p(elem1)
}
- override def forall(f: A => Boolean): Boolean = {
- f(elem1)
+ override def forall(@deprecatedName('f) p: A => Boolean): Boolean = {
+ p(elem1)
}
- override def find(f: A => Boolean): Option[A] = {
- if (f(elem1)) Some(elem1)
+ override def find(@deprecatedName('f) p: A => Boolean): Option[A] = {
+ if (p(elem1)) Some(elem1)
else None
}
- @deprecatedOverriding("Immutable sets should do nothing on toSet but return themselves cast as a Set.", "2.11.0")
- override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]
+ // Why is Set1 non-final? Need to fix that!
+ @deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8")
+ override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set1[B]]
+
}
/** An optimized representation for immutable sets of size 2 */
@@ -107,22 +124,23 @@ object Set extends ImmutableSetFactory[Set] {
else this
def iterator: Iterator[A] =
Iterator(elem1, elem2)
- override def foreach[U](f: A => U): Unit = {
+ override def foreach[U](f: A => U): Unit = {
f(elem1); f(elem2)
}
- override def exists(f: A => Boolean): Boolean = {
- f(elem1) || f(elem2)
+ override def exists(@deprecatedName('f) p: A => Boolean): Boolean = {
+ p(elem1) || p(elem2)
}
- override def forall(f: A => Boolean): Boolean = {
- f(elem1) && f(elem2)
+ override def forall(@deprecatedName('f) p: A => Boolean): Boolean = {
+ p(elem1) && p(elem2)
}
- override def find(f: A => Boolean): Option[A] = {
- if (f(elem1)) Some(elem1)
- else if (f(elem2)) Some(elem2)
+ override def find(@deprecatedName('f) p: A => Boolean): Option[A] = {
+ if (p(elem1)) Some(elem1)
+ else if (p(elem2)) Some(elem2)
else None
}
- @deprecatedOverriding("Immutable sets should do nothing on toSet but return themselves cast as a Set.", "2.11.0")
- override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]
+ // Why is Set2 non-final? Need to fix that!
+ @deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8")
+ override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set2[B]]
}
/** An optimized representation for immutable sets of size 3 */
@@ -141,23 +159,24 @@ object Set extends ImmutableSetFactory[Set] {
else this
def iterator: Iterator[A] =
Iterator(elem1, elem2, elem3)
- override def foreach[U](f: A => U): Unit = {
+ override def foreach[U](f: A => U): Unit = {
f(elem1); f(elem2); f(elem3)
}
- override def exists(f: A => Boolean): Boolean = {
- f(elem1) || f(elem2) || f(elem3)
+ override def exists(@deprecatedName('f) p: A => Boolean): Boolean = {
+ p(elem1) || p(elem2) || p(elem3)
}
- override def forall(f: A => Boolean): Boolean = {
- f(elem1) && f(elem2) && f(elem3)
+ override def forall(@deprecatedName('f) p: A => Boolean): Boolean = {
+ p(elem1) && p(elem2) && p(elem3)
}
- override def find(f: A => Boolean): Option[A] = {
- if (f(elem1)) Some(elem1)
- else if (f(elem2)) Some(elem2)
- else if (f(elem3)) Some(elem3)
+ override def find(@deprecatedName('f) p: A => Boolean): Option[A] = {
+ if (p(elem1)) Some(elem1)
+ else if (p(elem2)) Some(elem2)
+ else if (p(elem3)) Some(elem3)
else None
}
- @deprecatedOverriding("Immutable sets should do nothing on toSet but return themselves cast as a Set.", "2.11.0")
- override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]
+ // Why is Set3 non-final? Need to fix that!
+ @deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8")
+ override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set3[B]]
}
/** An optimized representation for immutable sets of size 4 */
@@ -177,24 +196,25 @@ object Set extends ImmutableSetFactory[Set] {
else this
def iterator: Iterator[A] =
Iterator(elem1, elem2, elem3, elem4)
- override def foreach[U](f: A => U): Unit = {
+ override def foreach[U](f: A => U): Unit = {
f(elem1); f(elem2); f(elem3); f(elem4)
}
- override def exists(f: A => Boolean): Boolean = {
- f(elem1) || f(elem2) || f(elem3) || f(elem4)
+ override def exists(@deprecatedName('f) p: A => Boolean): Boolean = {
+ p(elem1) || p(elem2) || p(elem3) || p(elem4)
}
- override def forall(f: A => Boolean): Boolean = {
- f(elem1) && f(elem2) && f(elem3) && f(elem4)
+ override def forall(@deprecatedName('f) p: A => Boolean): Boolean = {
+ p(elem1) && p(elem2) && p(elem3) && p(elem4)
}
- override def find(f: A => Boolean): Option[A] = {
- if (f(elem1)) Some(elem1)
- else if (f(elem2)) Some(elem2)
- else if (f(elem3)) Some(elem3)
- else if (f(elem4)) Some(elem4)
+ override def find(@deprecatedName('f) p: A => Boolean): Option[A] = {
+ if (p(elem1)) Some(elem1)
+ else if (p(elem2)) Some(elem2)
+ else if (p(elem3)) Some(elem3)
+ else if (p(elem4)) Some(elem4)
else None
}
- @deprecatedOverriding("Immutable sets should do nothing on toSet but return themselves cast as a Set.", "2.11.0")
- override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]
+ // Why is Set4 non-final? Need to fix that!
+ @deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8")
+ override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set4[B]]
}
}
diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala
index f1493551ab..682788e18e 100644
--- a/src/library/scala/collection/immutable/SortedMap.scala
+++ b/src/library/scala/collection/immutable/SortedMap.scala
@@ -53,6 +53,12 @@ self =>
val map = self.rangeImpl(from, until)
new map.DefaultKeySortedSet
}
+ override def toSet[C >: A]: Set[C] = {
+ // This way of building sets typically has the best benchmarks, surprisingly!
+ val sb = Set.newBuilder[C]
+ foreach(sb += _)
+ sb.result()
+ }
}
/** Add a key/value pair to this map.
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 17cf02cce6..a6c55f8828 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -508,8 +508,8 @@ self =>
*
* @example {{{
* $naturalsEx
- * naturalsFrom(1) 10 } filter { _ % 5 == 0 } take 10 mkString(", ")
- * // produces
+ * naturalsFrom(1) filter { _ % 5 == 0 } take 10 mkString(", ")
+ * // produces "5, 10, 15, 20, 25, 30, 35, 40, 45, 50"
* }}}
*/
override def filter(p: A => Boolean): Stream[A] = {
@@ -1190,7 +1190,7 @@ object Stream extends SeqFactory[Stream] {
def #:::(prefix: Stream[A]): Stream[A] = prefix append tl
}
- /** A wrapper method that adds `#::` for cons and `#::: for concat as operations
+ /** A wrapper method that adds `#::` for cons and `#:::` for concat as operations
* to streams.
*/
implicit def consWrapper[A](stream: => Stream[A]): ConsWrapper[A] =
diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala
index 1ead894faf..1b52e40b72 100644
--- a/src/library/scala/collection/immutable/StringLike.scala
+++ b/src/library/scala/collection/immutable/StringLike.scala
@@ -217,8 +217,8 @@ self =>
pos = thisString.indexOf(separator, prev)
} while (pos != -1)
- if (prev != thisString.size)
- res += thisString.substring(prev, thisString.size)
+ if (prev != thisString.length)
+ res += thisString.substring(prev, thisString.length)
val initialResult = res.result()
pos = initialResult.length
diff --git a/src/library/scala/collection/immutable/Vector.scala b/src/library/scala/collection/immutable/Vector.scala
index 46d5d0c69c..8bb581d44c 100644
--- a/src/library/scala/collection/immutable/Vector.scala
+++ b/src/library/scala/collection/immutable/Vector.scala
@@ -1156,8 +1156,6 @@ private[immutable] trait VectorPointer[T] {
if (depth == 3) {
display3 = new Array(32)
display3((oldIndex >> 15) & 31) = display2
- display2 = new Array(32)
- display1 = new Array(32)
depth +=1
}
display2 = display3((newIndex >> 15) & 31).asInstanceOf[Array[AnyRef]]
@@ -1170,9 +1168,6 @@ private[immutable] trait VectorPointer[T] {
if (depth == 4) {
display4 = new Array(32)
display4((oldIndex >> 20) & 31) = display3
- display3 = new Array(32)
- display2 = new Array(32)
- display1 = new Array(32)
depth +=1
}
display3 = display4((newIndex >> 20) & 31).asInstanceOf[Array[AnyRef]]
@@ -1187,13 +1182,9 @@ private[immutable] trait VectorPointer[T] {
if (depth == 5) {
display5 = new Array(32)
display5((oldIndex >> 25) & 31) = display4
- display4 = new Array(32)
- display3 = new Array(32)
- display2 = new Array(32)
- display1 = new Array(32)
depth +=1
}
- display4 = display5((newIndex >> 20) & 31).asInstanceOf[Array[AnyRef]]
+ display4 = display5((newIndex >> 25) & 31).asInstanceOf[Array[AnyRef]]
if (display4 == null) display4 = new Array(32)
display3 = display4((newIndex >> 20) & 31).asInstanceOf[Array[AnyRef]]
if (display3 == null) display3 = new Array(32)
diff --git a/src/library/scala/collection/mutable/IndexedSeqOptimized.scala b/src/library/scala/collection/mutable/IndexedSeqOptimized.scala
index 09f0712862..09f0712862 100755..100644
--- a/src/library/scala/collection/mutable/IndexedSeqOptimized.scala
+++ b/src/library/scala/collection/mutable/IndexedSeqOptimized.scala
diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala
index d3c4161e3b..2562f60355 100644
--- a/src/library/scala/collection/mutable/PriorityQueue.scala
+++ b/src/library/scala/collection/mutable/PriorityQueue.scala
@@ -18,8 +18,19 @@ import generic._
*
* Only the `dequeue` and `dequeueAll` methods will return methods in priority
* order (while removing elements from the heap). Standard collection methods
- * including `drop` and `iterator` will remove or traverse the heap in whichever
- * order seems most convenient.
+ * including `drop`, `iterator`, and `toString` will remove or traverse the heap
+ * in whichever order seems most convenient.
+ *
+ * Therefore, printing a `PriorityQueue` will not reveal the priority order of
+ * the elements, though the highest-priority element will be printed first. To
+ * print the elements in order, one must duplicate the `PriorityQueue` (by using
+ * `clone`, for instance) and then dequeue them:
+ *
+ * @example {{{
+ * val pq = collection.mutable.PriorityQueue(1, 2, 5, 3, 7)
+ * println(pq) // elements probably not in order
+ * println(pq.clone.dequeueAll) // prints Vector(7, 5, 3, 2, 1)
+ * }}}
*
* @tparam A type of the elements in this priority queue.
* @param ord implicit ordering used to compare the elements of type `A`.
diff --git a/src/library/scala/collection/mutable/Queue.scala b/src/library/scala/collection/mutable/Queue.scala
index 03d387a535..ad60173b64 100644
--- a/src/library/scala/collection/mutable/Queue.scala
+++ b/src/library/scala/collection/mutable/Queue.scala
@@ -21,7 +21,7 @@ import generic._
* @author Martin Odersky
* @version 2.8
* @since 1
- * @see [[http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html#mutable_queues "Scala's Collection Library overview"]]
+ * @see [[http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html#queues "Scala's Collection Library overview"]]
* section on `Queues` for more information.
*
* @define Coll `mutable.Queue`
diff --git a/src/library/scala/collection/package.scala b/src/library/scala/collection/package.scala
index 6a2b6de75a..13fe7a79c4 100644
--- a/src/library/scala/collection/package.scala
+++ b/src/library/scala/collection/package.scala
@@ -69,6 +69,9 @@ package scala
* characteristics which are described
* in [[http://docs.scala-lang.org/overviews/collections/performance-characteristics.html the guide]].
*
+ * The concrete parallel collections also have specific performance characteristics which are
+ * described in [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#performance-characteristics the parallel collections guide]]
+ *
* === Converting between Java Collections ===
*
* The `JavaConversions` object provides implicit defs that will allow mostly seamless integration
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index 016255dca4..e7b022b895 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -520,22 +520,22 @@ self: ParIterableLike[T, Repr, Sequential] =>
*
* $abortsignalling
*
- * @param pred a predicate used to test elements
+ * @param p a predicate used to test elements
* @return true if `p` holds for all elements, false otherwise
*/
- def forall(pred: T => Boolean): Boolean = {
- tasksupport.executeAndWaitResult(new Forall(pred, splitter assign new DefaultSignalling with VolatileAbort))
+ def forall(@deprecatedName('pred) p: T => Boolean): Boolean = {
+ tasksupport.executeAndWaitResult(new Forall(p, splitter assign new DefaultSignalling with VolatileAbort))
}
/** Tests whether a predicate holds for some element of this $coll.
*
* $abortsignalling
*
- * @param pred a predicate used to test elements
+ * @param p a predicate used to test elements
* @return true if `p` holds for some element, false otherwise
*/
- def exists(pred: T => Boolean): Boolean = {
- tasksupport.executeAndWaitResult(new Exists(pred, splitter assign new DefaultSignalling with VolatileAbort))
+ def exists(@deprecatedName('pred) p: T => Boolean): Boolean = {
+ tasksupport.executeAndWaitResult(new Exists(p, splitter assign new DefaultSignalling with VolatileAbort))
}
/** Finds some element in the collection for which the predicate holds, if such
@@ -546,11 +546,11 @@ self: ParIterableLike[T, Repr, Sequential] =>
*
* $abortsignalling
*
- * @param pred predicate used to test the elements
+ * @param p predicate used to test the elements
* @return an option value with the element if such an element exists, or `None` otherwise
*/
- def find(pred: T => Boolean): Option[T] = {
- tasksupport.executeAndWaitResult(new Find(pred, splitter assign new DefaultSignalling with VolatileAbort))
+ def find(@deprecatedName('pred) p: T => Boolean): Option[T] = {
+ tasksupport.executeAndWaitResult(new Find(p, splitter assign new DefaultSignalling with VolatileAbort))
}
/** Creates a combiner factory. Each combiner factory instance is used
diff --git a/src/library/scala/collection/readme-if-you-want-to-add-something.txt b/src/library/scala/collection/readme-if-you-want-to-add-something.txt
index 6700cb7b68..6700cb7b68 100755..100644
--- a/src/library/scala/collection/readme-if-you-want-to-add-something.txt
+++ b/src/library/scala/collection/readme-if-you-want-to-add-something.txt
diff --git a/src/library/scala/compat/Platform.scala b/src/library/scala/compat/Platform.scala
index 4c82d6e15b..42dfcbfdde 100644
--- a/src/library/scala/compat/Platform.scala
+++ b/src/library/scala/compat/Platform.scala
@@ -41,7 +41,7 @@ object Platform {
* @throws java.lang.ArrayStoreException If either `src` or `dest` are not of type
* [java.lang.Array]; or if the element type of `src` is not
* compatible with that of `dest`.
- * @throws java.lang.IndexOutOfBoundsException If either srcPos` or `destPos` are
+ * @throws java.lang.IndexOutOfBoundsException If either `srcPos` or `destPos` are
* outside of the bounds of their respective arrays; or if `length`
* is negative; or if there are less than `length` elements available
* after `srcPos` or `destPos` in `src` and `dest` respectively.
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index 914646320c..294ca2aa48 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -497,7 +497,7 @@ object Future {
def sequence[A, M[X] <: TraversableOnce[X]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]] = {
in.foldLeft(successful(cbf(in))) {
(fr, fa) => for (r <- fr; a <- fa) yield (r += a)
- } map (_.result())
+ }.map(_.result())(InternalCallbackExecutor)
}
/** Returns a new `Future` to the result of the first future in the list that is completed.
diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala
index 9634f6d900..1ee27b0f36 100644
--- a/src/library/scala/concurrent/SyncVar.scala
+++ b/src/library/scala/concurrent/SyncVar.scala
@@ -40,7 +40,7 @@ class SyncVar[A] {
wait(timeout)
val elapsed = System.nanoTime() - start
// nanoTime should be monotonic, but it's not possible to rely on that.
- // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6458294.
+ // See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294.
if (elapsed < 0) 0 else TimeUnit.NANOSECONDS.toMillis(elapsed)
}
diff --git a/src/library/scala/concurrent/impl/AbstractPromise.java b/src/library/scala/concurrent/impl/AbstractPromise.java
index b8165b6cde..c2520a1692 100644
--- a/src/library/scala/concurrent/impl/AbstractPromise.java
+++ b/src/library/scala/concurrent/impl/AbstractPromise.java
@@ -1,6 +1,6 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2003-2015, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
@@ -8,33 +8,10 @@
package scala.concurrent.impl;
+import java.util.concurrent.atomic.AtomicReference;
-import scala.concurrent.util.Unsafe;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-
-
-
-abstract class AbstractPromise {
- private volatile Object _ref;
-
- final static long _refoffset;
-
- static {
- try {
- _refoffset = Unsafe.instance.objectFieldOffset(AbstractPromise.class.getDeclaredField("_ref"));
- } catch (Throwable t) {
- throw new ExceptionInInitializerError(t);
- }
- }
-
- protected final boolean updateState(Object oldState, Object newState) {
- return Unsafe.instance.compareAndSwapObject(this, _refoffset, oldState, newState);
- }
-
- protected final Object getState() {
- return _ref;
- }
-
- protected final static AtomicReferenceFieldUpdater<AbstractPromise, Object> updater =
- AtomicReferenceFieldUpdater.newUpdater(AbstractPromise.class, Object.class, "_ref");
-} \ No newline at end of file
+@Deprecated // Since 2.11.8. Extend java.util.concurrent.atomic.AtomicReference instead.
+abstract class AbstractPromise extends AtomicReference<Object> {
+ protected final boolean updateState(Object oldState, Object newState) { return compareAndSet(oldState, newState); }
+ protected final Object getState() { return get(); }
+}
diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala
index 60f99199cb..7cb7858b36 100644
--- a/src/library/scala/io/Codec.scala
+++ b/src/library/scala/io/Codec.scala
@@ -21,8 +21,8 @@ import scala.language.implicitConversions
// XML: optional encoding parameter.
// <?xml version="1.0" encoding="ISO8859-1" ?>
//
-// MacRoman vs. UTF-8: see http://jira.codehaus.org/browse/JRUBY-3576
-// -Dfile.encoding: see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4375816
+// MacRoman vs. UTF-8: see http://osdir.com/ml/lang-jruby-devel/2009-04/msg00071.html
+// -Dfile.encoding: see http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4375816
/** A class for character encoding/decoding preferences.
*
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index 6bb35606a6..bb337e7a1d 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -124,7 +124,7 @@ object BigDecimal {
*/
def exact(s: String): BigDecimal = exact(new BigDec(s))
- /** Constructs a 'BigDecimal` that exactly represents the number
+ /** Constructs a `BigDecimal` that exactly represents the number
* specified in base 10 in a character array.
*/
def exact(cs: Array[Char]): BigDecimal = exact(new BigDec(cs))
diff --git a/src/library/scala/ref/WeakReference.scala b/src/library/scala/ref/WeakReference.scala
index 6ee40aed5c..9dcc0bbe5f 100644
--- a/src/library/scala/ref/WeakReference.scala
+++ b/src/library/scala/ref/WeakReference.scala
@@ -28,10 +28,7 @@ object WeakReference {
def apply[T <: AnyRef](value: T) = new WeakReference(value)
/** Optionally returns the referenced value, or `None` if that value no longer exists */
- def unapply[T <: AnyRef](wr: WeakReference[T]): Option[T] = {
- val x = wr.underlying.get
- if (x != null) Some(x) else None
- }
+ def unapply[T <: AnyRef](wr: WeakReference[T]): Option[T] = Option(wr.underlying.get)
}
/**
diff --git a/src/library/scala/reflect/ClassManifestDeprecatedApis.scala b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala
index ca7a3cddb8..82ec872806 100644
--- a/src/library/scala/reflect/ClassManifestDeprecatedApis.scala
+++ b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala
@@ -218,7 +218,7 @@ object ClassManifestFactory {
/** ClassManifest for the abstract type `prefix # name`. `upperBound` is not
* strictly necessary as it could be obtained by reflection. It was
* added so that erasure can be calculated without reflection.
- * todo: remove after next boostrap
+ * todo: remove after next bootstrap
*/
def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] =
new ClassManifest[T] {
@@ -239,4 +239,4 @@ private class ClassTypeManifest[T](
(if (prefix.isEmpty) "" else prefix.get.toString+"#") +
(if (runtimeClass.isArray) "Array" else runtimeClass.getName) +
argString
-} \ No newline at end of file
+}
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index 2f7643bccf..4ff49c44d0 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -248,7 +248,7 @@ object ManifestFactory {
def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] =
arg.asInstanceOf[Manifest[T]].arrayManifest
- /** Manifest for the abstract type `prefix # name'. `upperBound` is not
+ /** Manifest for the abstract type `prefix # name`. `upperBound` is not
* strictly necessary as it could be obtained by reflection. It was
* added so that erasure can be calculated without reflection. */
def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
@@ -269,7 +269,7 @@ object ManifestFactory {
(if (upperBound eq Nothing) "" else " <: "+upperBound)
}
- /** Manifest for the intersection type `parents_0 with ... with parents_n'. */
+ /** Manifest for the intersection type `parents_0 with ... with parents_n`. */
def intersectionType[T](parents: Manifest[_]*): Manifest[T] =
new Manifest[T] {
def runtimeClass = parents.head.runtimeClass
diff --git a/src/library/scala/reflect/NameTransformer.scala b/src/library/scala/reflect/NameTransformer.scala
index a8430548f5..a8430548f5 100755..100644
--- a/src/library/scala/reflect/NameTransformer.scala
+++ b/src/library/scala/reflect/NameTransformer.scala
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 18fcbf8276..20f067f34f 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -155,7 +155,7 @@ object ScalaRunTime {
arr
}
- // Java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957
+ // Java bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4071957
// More background at ticket #2318.
def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m)
diff --git a/src/library/scala/runtime/TraitSetter.java b/src/library/scala/runtime/TraitSetter.java
index d9907c0ac0..d9907c0ac0 100755..100644
--- a/src/library/scala/runtime/TraitSetter.java
+++ b/src/library/scala/runtime/TraitSetter.java
diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala
index 512c4fbc27..4109f5cb4b 100644
--- a/src/library/scala/runtime/Tuple2Zipped.scala
+++ b/src/library/scala/runtime/Tuple2Zipped.scala
@@ -84,12 +84,12 @@ final class Tuple2Zipped[El1, Repr1, El2, Repr2](val colls: (TraversableLike[El1
(b1.result(), b2.result())
}
- def exists(f: (El1, El2) => Boolean): Boolean = {
+ def exists(@deprecatedName('f) p: (El1, El2) => Boolean): Boolean = {
val elems2 = colls._2.iterator
for (el1 <- colls._1) {
if (elems2.hasNext) {
- if (f(el1, elems2.next()))
+ if (p(el1, elems2.next()))
return true
}
else return false
@@ -97,8 +97,8 @@ final class Tuple2Zipped[El1, Repr1, El2, Repr2](val colls: (TraversableLike[El1
false
}
- def forall(f: (El1, El2) => Boolean): Boolean =
- !exists((x, y) => !f(x, y))
+ def forall(@deprecatedName('f) p: (El1, El2) => Boolean): Boolean =
+ !exists((x, y) => !p(x, y))
def foreach[U](f: (El1, El2) => U): Unit = {
val elems2 = colls._2.iterator
diff --git a/src/library/scala/runtime/Tuple3Zipped.scala b/src/library/scala/runtime/Tuple3Zipped.scala
index ffd44acf81..cde7699d40 100644
--- a/src/library/scala/runtime/Tuple3Zipped.scala
+++ b/src/library/scala/runtime/Tuple3Zipped.scala
@@ -90,13 +90,13 @@ final class Tuple3Zipped[El1, Repr1, El2, Repr2, El3, Repr3](val colls: (Travers
result
}
- def exists(f: (El1, El2, El3) => Boolean): Boolean = {
+ def exists(@deprecatedName('f) p: (El1, El2, El3) => Boolean): Boolean = {
val elems2 = colls._2.iterator
val elems3 = colls._3.iterator
for (el1 <- colls._1) {
if (elems2.hasNext && elems3.hasNext) {
- if (f(el1, elems2.next(), elems3.next()))
+ if (p(el1, elems2.next(), elems3.next()))
return true
}
else return false
@@ -104,8 +104,8 @@ final class Tuple3Zipped[El1, Repr1, El2, Repr2, El3, Repr3](val colls: (Travers
false
}
- def forall(f: (El1, El2, El3) => Boolean): Boolean =
- !exists((x, y, z) => !f(x, y, z))
+ def forall(@deprecatedName('f) p: (El1, El2, El3) => Boolean): Boolean =
+ !exists((x, y, z) => !p(x, y, z))
def foreach[U](f: (El1, El2, El3) => U): Unit = {
val elems2 = colls._2.iterator
diff --git a/src/library/scala/runtime/VolatileBooleanRef.java b/src/library/scala/runtime/VolatileBooleanRef.java
index ef5b691118..ef5b691118 100755..100644
--- a/src/library/scala/runtime/VolatileBooleanRef.java
+++ b/src/library/scala/runtime/VolatileBooleanRef.java
diff --git a/src/library/scala/runtime/VolatileByteRef.java b/src/library/scala/runtime/VolatileByteRef.java
index d792b0a386..d792b0a386 100755..100644
--- a/src/library/scala/runtime/VolatileByteRef.java
+++ b/src/library/scala/runtime/VolatileByteRef.java
diff --git a/src/library/scala/runtime/VolatileCharRef.java b/src/library/scala/runtime/VolatileCharRef.java
index 555b171283..555b171283 100755..100644
--- a/src/library/scala/runtime/VolatileCharRef.java
+++ b/src/library/scala/runtime/VolatileCharRef.java
diff --git a/src/library/scala/runtime/VolatileDoubleRef.java b/src/library/scala/runtime/VolatileDoubleRef.java
index 1932055c6a..1932055c6a 100755..100644
--- a/src/library/scala/runtime/VolatileDoubleRef.java
+++ b/src/library/scala/runtime/VolatileDoubleRef.java
diff --git a/src/library/scala/runtime/VolatileFloatRef.java b/src/library/scala/runtime/VolatileFloatRef.java
index 3a81be1146..3a81be1146 100755..100644
--- a/src/library/scala/runtime/VolatileFloatRef.java
+++ b/src/library/scala/runtime/VolatileFloatRef.java
diff --git a/src/library/scala/runtime/VolatileIntRef.java b/src/library/scala/runtime/VolatileIntRef.java
index ae015bc8b1..ae015bc8b1 100755..100644
--- a/src/library/scala/runtime/VolatileIntRef.java
+++ b/src/library/scala/runtime/VolatileIntRef.java
diff --git a/src/library/scala/runtime/VolatileLongRef.java b/src/library/scala/runtime/VolatileLongRef.java
index e596f5aa69..e596f5aa69 100755..100644
--- a/src/library/scala/runtime/VolatileLongRef.java
+++ b/src/library/scala/runtime/VolatileLongRef.java
diff --git a/src/library/scala/runtime/VolatileObjectRef.java b/src/library/scala/runtime/VolatileObjectRef.java
index 6063501ffb..6063501ffb 100755..100644
--- a/src/library/scala/runtime/VolatileObjectRef.java
+++ b/src/library/scala/runtime/VolatileObjectRef.java
diff --git a/src/library/scala/runtime/VolatileShortRef.java b/src/library/scala/runtime/VolatileShortRef.java
index 0a2825941f..0a2825941f 100755..100644
--- a/src/library/scala/runtime/VolatileShortRef.java
+++ b/src/library/scala/runtime/VolatileShortRef.java
diff --git a/src/library/scala/sys/process/Process.scala b/src/library/scala/sys/process/Process.scala
index dcd06c89e9..06b9967908 100644
--- a/src/library/scala/sys/process/Process.scala
+++ b/src/library/scala/sys/process/Process.scala
@@ -68,7 +68,7 @@ trait ProcessCreation {
/** Creates a [[scala.sys.process.ProcessBuilder]] with working dir set to `File` and extra
* environment variables.
*
- * @example {{{ apply("java", new java.ioFile("/opt/app"), "CLASSPATH" -> "library.jar") }}}
+ * @example {{{ apply("java", new java.io.File("/opt/app"), "CLASSPATH" -> "library.jar") }}}
*/
def apply(command: String, cwd: File, extraEnv: (String, String)*): ProcessBuilder =
apply(command, Some(cwd), extraEnv: _*)
@@ -76,7 +76,7 @@ trait ProcessCreation {
/** Creates a [[scala.sys.process.ProcessBuilder]] with working dir set to `File` and extra
* environment variables.
*
- * @example {{{ apply("java" :: javaArgs, new java.ioFile("/opt/app"), "CLASSPATH" -> "library.jar") }}}
+ * @example {{{ apply("java" :: javaArgs, new java.io.File("/opt/app"), "CLASSPATH" -> "library.jar") }}}
*/
def apply(command: Seq[String], cwd: File, extraEnv: (String, String)*): ProcessBuilder =
apply(command, Some(cwd), extraEnv: _*)
@@ -155,8 +155,8 @@ trait ProcessCreation {
* import java.net.URL
* import java.io.File
*
- * val spde = new URL("http://technically.us/spde/About")
- * val dispatch = new URL("http://databinder.net/dispatch/About")
+ * val spde = new URL("http://technically.us/spde.html")
+ * val dispatch = new URL("http://dispatch.databinder.net/Dispatch.html")
* val build = new File("project/build.properties")
* cat(spde, dispatch, build) #| "grep -i scala" !
* }}}
diff --git a/src/library/scala/sys/process/package.scala b/src/library/scala/sys/process/package.scala
index b1976ad4b6..445c3aee60 100644
--- a/src/library/scala/sys/process/package.scala
+++ b/src/library/scala/sys/process/package.scala
@@ -157,7 +157,8 @@ package scala.sys {
* while(input.read() != -1) count += 1
* input.close()
* }
- * cat ! new ProcessIO(_.close(), byteCounter, _.close())
+ * val p = cat run new ProcessIO(_.close(), byteCounter, _.close())
+ * p.exitValue()
* count
* }
*
diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala
index e196d403c2..32b7ec4487 100644
--- a/src/library/scala/util/Either.scala
+++ b/src/library/scala/util/Either.scala
@@ -329,8 +329,8 @@ object Either {
* }}}
*
*/
- def forall(f: A => Boolean) = e match {
- case Left(a) => f(a)
+ def forall(@deprecatedName('f) p: A => Boolean) = e match {
+ case Left(a) => p(a)
case Right(_) => true
}
@@ -345,8 +345,8 @@ object Either {
* }}}
*
*/
- def exists(f: A => Boolean) = e match {
- case Left(a) => f(a)
+ def exists(@deprecatedName('f) p: A => Boolean) = e match {
+ case Left(a) => p(a)
case Right(_) => false
}
@@ -507,9 +507,9 @@ object Either {
* Left(12).right.exists(_ > 10) // false
* }}}
*/
- def exists(f: B => Boolean) = e match {
+ def exists(@deprecatedName('f) p: B => Boolean) = e match {
case Left(_) => false
- case Right(b) => f(b)
+ case Right(b) => p(b)
}
/**
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index 367488f116..d4a5e2f0e8 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -1,6 +1,6 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2006-2015, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
@@ -105,7 +105,7 @@ private[scala] trait PropertiesTrait {
* or "version (unknown)" if it cannot be determined.
*/
val versionString = "version " + scalaPropOrElse("version.number", "(unknown)")
- val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2013, LAMP/EPFL")
+ val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2015, LAMP/EPFL")
/** This is the encoding to use reading in source files, overridden with -encoding.
* Note that it uses "prop" i.e. looks in the scala jar, not the system properties.
diff --git a/src/library/scala/util/Sorting.scala b/src/library/scala/util/Sorting.scala
index ee2bdbc4a7..b4f965f69b 100644
--- a/src/library/scala/util/Sorting.scala
+++ b/src/library/scala/util/Sorting.scala
@@ -88,7 +88,7 @@ object Sorting {
a(pL - 1) = current
pL -= 1
case x if x < 0 =>
- // Already in place. Just update indicies.
+ // Already in place. Just update indices.
iA += 1
case _ if iB > pR =>
// Wrong side. There's room on the other side, so swap
diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala
index aa30887ba0..24c297a2fc 100644
--- a/src/library/scala/util/control/Exception.scala
+++ b/src/library/scala/util/control/Exception.scala
@@ -105,7 +105,7 @@ object Exception {
case x if rethrow(x) => throw x
case x if pf isDefinedAt x => pf(x)
}
- finally fin map (_.invoke())
+ finally fin foreach (_.invoke())
/* Create an empty Try container with this Catch and the supplied `Finally`. */
def andFinally(body: => Unit): Catch[T] = fin match {
diff --git a/src/manual/scala/man1/Command.scala b/src/manual/scala/man1/Command.scala
index 8f811f950e..13e21757c0 100644
--- a/src/manual/scala/man1/Command.scala
+++ b/src/manual/scala/man1/Command.scala
@@ -42,7 +42,7 @@ trait Command {
def authors = Section("AUTHOR",
"Written by Martin Odersky and other members of the " &
- Link("Scala team", "http://www.scala-lang.org/node/89") & ".")
+ Link("Scala team", "http://www.scala-lang.org/news/2014/01/22/10-years-of-scala.html") & ".")
def copyright = Section("COPYRIGHT",
diff --git a/src/partest-extras/scala/tools/partest/ASMConverters.scala b/src/partest-extras/scala/tools/partest/ASMConverters.scala
index 90f314428b..b4c686473b 100644
--- a/src/partest-extras/scala/tools/partest/ASMConverters.scala
+++ b/src/partest-extras/scala/tools/partest/ASMConverters.scala
@@ -58,21 +58,24 @@ object ASMConverters {
case class Method(instructions: List[Instruction], handlers: List[ExceptionHandler], localVars: List[LocalVariable])
- case class Field (opcode: Int, owner: String, name: String, desc: String) extends Instruction
- case class Incr (opcode: Int, `var`: Int, incr: Int) extends Instruction
- case class Op (opcode: Int) extends Instruction
- case class IntOp (opcode: Int, operand: Int) extends Instruction
- case class Jump (opcode: Int, label: Label) extends Instruction
- case class Ldc (opcode: Int, cst: Any) extends Instruction
- case class LookupSwitch(opcode: Int, dflt: Label, keys: List[Int], labels: List[Label]) extends Instruction
- case class TableSwitch (opcode: Int, min: Int, max: Int, dflt: Label, labels: List[Label]) extends Instruction
- case class Invoke (opcode: Int, owner: String, name: String, desc: String, itf: Boolean) extends Instruction
- case class NewArray (opcode: Int, desc: String, dims: Int) extends Instruction
- case class TypeOp (opcode: Int, desc: String) extends Instruction
- case class VarOp (opcode: Int, `var`: Int) extends Instruction
- case class Label (offset: Int) extends Instruction { def opcode: Int = -1 }
- case class FrameEntry (`type`: Int, local: List[Any], stack: List[Any]) extends Instruction { def opcode: Int = -1 }
- case class LineNumber (line: Int, start: Label) extends Instruction { def opcode: Int = -1 }
+ case class Field (opcode: Int, owner: String, name: String, desc: String) extends Instruction
+ case class Incr (opcode: Int, `var`: Int, incr: Int) extends Instruction
+ case class Op (opcode: Int) extends Instruction
+ case class IntOp (opcode: Int, operand: Int) extends Instruction
+ case class Jump (opcode: Int, label: Label) extends Instruction
+ case class Ldc (opcode: Int, cst: Any) extends Instruction
+ case class LookupSwitch (opcode: Int, dflt: Label, keys: List[Int], labels: List[Label]) extends Instruction
+ case class TableSwitch (opcode: Int, min: Int, max: Int, dflt: Label, labels: List[Label]) extends Instruction
+ case class Invoke (opcode: Int, owner: String, name: String, desc: String, itf: Boolean) extends Instruction
+ case class InvokeDynamic(opcode: Int, name: String, desc: String, bsm: MethodHandle, bsmArgs: List[AnyRef]) extends Instruction
+ case class NewArray (opcode: Int, desc: String, dims: Int) extends Instruction
+ case class TypeOp (opcode: Int, desc: String) extends Instruction
+ case class VarOp (opcode: Int, `var`: Int) extends Instruction
+ case class Label (offset: Int) extends Instruction { def opcode: Int = -1 }
+ case class FrameEntry (`type`: Int, local: List[Any], stack: List[Any]) extends Instruction { def opcode: Int = -1 }
+ case class LineNumber (line: Int, start: Label) extends Instruction { def opcode: Int = -1 }
+
+ case class MethodHandle(tag: Int, owner: String, name: String, desc: String)
case class ExceptionHandler(start: Label, end: Label, handler: Label, desc: Option[String])
case class LocalVariable(name: String, desc: String, signature: Option[String], start: Label, end: Label, index: Int)
@@ -111,6 +114,7 @@ object ASMConverters {
case i: t.LookupSwitchInsnNode => LookupSwitch (op(i), applyLabel(i.dflt), lst(i.keys) map (x => x: Int), lst(i.labels) map applyLabel)
case i: t.TableSwitchInsnNode => TableSwitch (op(i), i.min, i.max, applyLabel(i.dflt), lst(i.labels) map applyLabel)
case i: t.MethodInsnNode => Invoke (op(i), i.owner, i.name, i.desc, i.itf)
+ case i: t.InvokeDynamicInsnNode => InvokeDynamic(op(i), i.name, i.desc, convertMethodHandle(i.bsm), convertBsmArgs(i.bsmArgs))
case i: t.MultiANewArrayInsnNode => NewArray (op(i), i.desc, i.dims)
case i: t.TypeInsnNode => TypeOp (op(i), i.desc)
case i: t.VarInsnNode => VarOp (op(i), i.`var`)
@@ -119,6 +123,13 @@ object ASMConverters {
case i: t.LineNumberNode => LineNumber (i.line, applyLabel(i.start))
}
+ private def convertBsmArgs(a: Array[Object]): List[Object] = a.map({
+ case h: asm.Handle => convertMethodHandle(h)
+ case _ => a // can be: Class, method Type, primitive constant
+ })(collection.breakOut)
+
+ private def convertMethodHandle(h: asm.Handle): MethodHandle = MethodHandle(h.getTag, h.getOwner, h.getName, h.getDesc)
+
private def convertHandlers(method: t.MethodNode): List[ExceptionHandler] = {
method.tryCatchBlocks.asScala.map(h => ExceptionHandler(applyLabel(h.start), applyLabel(h.end), applyLabel(h.handler), Option(h.`type`)))(collection.breakOut)
}
@@ -197,21 +208,28 @@ object ASMConverters {
case x => x.asInstanceOf[Object]
}
+ def unconvertMethodHandle(h: MethodHandle): asm.Handle = new asm.Handle(h.tag, h.owner, h.name, h.desc)
+ def unconvertBsmArgs(a: List[Object]): Array[Object] = a.map({
+ case h: MethodHandle => unconvertMethodHandle(h)
+ case o => o
+ })(collection.breakOut)
+
private def visitMethod(method: t.MethodNode, instruction: Instruction, asmLabel: Map[Label, asm.Label]): Unit = instruction match {
- case Field(op, owner, name, desc) => method.visitFieldInsn(op, owner, name, desc)
- case Incr(op, vr, incr) => method.visitIincInsn(vr, incr)
- case Op(op) => method.visitInsn(op)
- case IntOp(op, operand) => method.visitIntInsn(op, operand)
- case Jump(op, label) => method.visitJumpInsn(op, asmLabel(label))
- case Ldc(op, cst) => method.visitLdcInsn(cst)
- case LookupSwitch(op, dflt, keys, labels) => method.visitLookupSwitchInsn(asmLabel(dflt), keys.toArray, (labels map asmLabel).toArray)
- case TableSwitch(op, min, max, dflt, labels) => method.visitTableSwitchInsn(min, max, asmLabel(dflt), (labels map asmLabel).toArray: _*)
- case Invoke(op, owner, name, desc, itf) => method.visitMethodInsn(op, owner, name, desc, itf)
- case NewArray(op, desc, dims) => method.visitMultiANewArrayInsn(desc, dims)
- case TypeOp(op, desc) => method.visitTypeInsn(op, desc)
- case VarOp(op, vr) => method.visitVarInsn(op, vr)
- case l: Label => method.visitLabel(asmLabel(l))
- case FrameEntry(tp, local, stack) => method.visitFrame(tp, local.length, frameTypesToAsm(local, asmLabel).toArray, stack.length, frameTypesToAsm(stack, asmLabel).toArray)
- case LineNumber(line, start) => method.visitLineNumber(line, asmLabel(start))
+ case Field(op, owner, name, desc) => method.visitFieldInsn(op, owner, name, desc)
+ case Incr(op, vr, incr) => method.visitIincInsn(vr, incr)
+ case Op(op) => method.visitInsn(op)
+ case IntOp(op, operand) => method.visitIntInsn(op, operand)
+ case Jump(op, label) => method.visitJumpInsn(op, asmLabel(label))
+ case Ldc(op, cst) => method.visitLdcInsn(cst)
+ case LookupSwitch(op, dflt, keys, labels) => method.visitLookupSwitchInsn(asmLabel(dflt), keys.toArray, (labels map asmLabel).toArray)
+ case TableSwitch(op, min, max, dflt, labels) => method.visitTableSwitchInsn(min, max, asmLabel(dflt), (labels map asmLabel).toArray: _*)
+ case Invoke(op, owner, name, desc, itf) => method.visitMethodInsn(op, owner, name, desc, itf)
+ case InvokeDynamic(op, name, desc, bsm, bsmArgs) => method.visitInvokeDynamicInsn(name, desc, unconvertMethodHandle(bsm), unconvertBsmArgs(bsmArgs))
+ case NewArray(op, desc, dims) => method.visitMultiANewArrayInsn(desc, dims)
+ case TypeOp(op, desc) => method.visitTypeInsn(op, desc)
+ case VarOp(op, vr) => method.visitVarInsn(op, vr)
+ case l: Label => method.visitLabel(asmLabel(l))
+ case FrameEntry(tp, local, stack) => method.visitFrame(tp, local.length, frameTypesToAsm(local, asmLabel).toArray, stack.length, frameTypesToAsm(stack, asmLabel).toArray)
+ case LineNumber(line, start) => method.visitLineNumber(line, asmLabel(start))
}
}
diff --git a/src/partest-extras/scala/tools/partest/IcodeComparison.scala b/src/partest-extras/scala/tools/partest/IcodeComparison.scala
index 7122703918..1430db886e 100644
--- a/src/partest-extras/scala/tools/partest/IcodeComparison.scala
+++ b/src/partest-extras/scala/tools/partest/IcodeComparison.scala
@@ -48,8 +48,13 @@ abstract class IcodeComparison extends DirectTest {
compile("-d" :: testOutput.path :: arg0 :: args.toList : _*)
val icodeFiles = testOutput.files.toList filter (_ hasExtension "icode")
- try icodeFiles sortBy (_.name) flatMap (f => f.lines.toList)
- finally icodeFiles foreach (f => f.delete())
+ // Some methods in scala.reflect.io.File leak an InputStream, leaving the underlying file open.
+ // Windows won't delete an open file, but we must ensure the files get deleted, since the logic
+ // here depends on it (collectIcode will be called multiple times, and we can't allow crosstalk
+ // between calls). So we are careful to use `slurp` which does call `close`, and careful to
+ // check that `delete` returns true indicating successful deletion.
+ try icodeFiles sortBy (_.name) flatMap (f => f.slurp().lines.toList)
+ finally icodeFiles foreach (f => require(f.delete()))
}
/** Collect icode at the default phase, `printIcodeAfterPhase`. */
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 2bf407ee19..a43195d9b6 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -143,7 +143,7 @@ trait Trees { self: Universe =>
/** Find all subtrees matching predicate `p`. Same as `withFilter` */
def filter(f: Tree => Boolean): List[Tree]
- /** Apply `pf' to each subtree on which the function is defined and collect the results.
+ /** Apply `pf` to each subtree on which the function is defined and collect the results.
*/
def collect[T](pf: PartialFunction[Tree, T]): List[T]
diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
index 7db375ca61..bc239ca870 100644
--- a/src/reflect/scala/reflect/api/TypeTags.scala
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -53,7 +53,7 @@ import java.io.ObjectStreamException
* Each of these methods constructs a `TypeTag[T]` or `ClassTag[T]` for the given
* type argument `T`.
*
- * === #2 Using an implicit parameter of type `TypeTag[T]`, `ClassTag[T]`, or `WeakTypeTag[T]
+ * === #2 Using an implicit parameter of type `TypeTag[T]`, `ClassTag[T]`, or `WeakTypeTag[T]`
*
* For example:
* {{{
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index cd7648a44a..f9b49f1730 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -588,7 +588,7 @@ trait Types {
/** An extractor class to create and pattern match with syntax `TypeRef(pre, sym, args)`
* Here, `pre` is the prefix of the type reference, `sym` is the symbol
* referred to by the type reference, and `args` is a possible empty list of
- * type argumenrts.
+ * type arguments.
* @group Extractors
*/
abstract class TypeRefExtractor {
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index 6863cdfd82..b923541b56 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -404,7 +404,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil)
- object ErroneousAnnotation extends CompleteAnnotationInfo(ErrorType, Nil, Nil)
+ class ErroneousAnnotation() extends CompleteAnnotationInfo(ErrorType, Nil, Nil)
/** Extracts symbol of thrown exception from AnnotationInfo.
*
diff --git a/src/reflect/scala/reflect/internal/ClassfileConstants.scala b/src/reflect/scala/reflect/internal/ClassfileConstants.scala
index 53241fb15b..a4223c1cb5 100644
--- a/src/reflect/scala/reflect/internal/ClassfileConstants.scala
+++ b/src/reflect/scala/reflect/internal/ClassfileConstants.scala
@@ -14,7 +14,7 @@ object ClassfileConstants {
final val JAVA_MAJOR_VERSION = 45
final val JAVA_MINOR_VERSION = 3
- /** (see http://java.sun.com/docs/books/jvms/second_edition/jvms-clarify.html)
+ /** (see http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.1)
*
* If the `ACC_INTERFACE` flag is set, the `ACC_ABSTRACT` flag must also
* be set (ch. 2.13.1).
@@ -344,7 +344,8 @@ object ClassfileConstants {
case JAVA_ACC_STATIC => STATIC
case JAVA_ACC_ABSTRACT => if (isAnnotation) 0L else if (isClass) ABSTRACT else DEFERRED
case JAVA_ACC_INTERFACE => if (isAnnotation) 0L else TRAIT | INTERFACE | ABSTRACT
- case JAVA_ACC_ENUM => ENUM
+ case JAVA_ACC_ENUM => JAVA_ENUM
+ case JAVA_ACC_ANNOTATION => JAVA_ANNOTATION
case _ => 0L
}
private def translateFlags(jflags: Int, baseFlags: Long, isClass: Boolean): Long = {
@@ -360,6 +361,7 @@ object ClassfileConstants {
res |= translateFlag0(jflags & JAVA_ACC_ABSTRACT)
res |= translateFlag0(jflags & JAVA_ACC_INTERFACE)
res |= translateFlag0(jflags & JAVA_ACC_ENUM)
+ res |= translateFlag0(jflags & JAVA_ACC_ANNOTATION)
res
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 4e0fc1e36e..0bdf5b4647 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -815,7 +815,7 @@ trait Definitions extends api.StandardDefinitions {
// must filter out "universal" members (getClass is deferred for some reason)
val deferredMembers = (
tp membersBasedOnFlags (excludedFlags = BridgeAndPrivateFlags, requiredFlags = METHOD)
- filter (mem => mem.isDeferredNotDefault && !isUniversalMember(mem)) // TODO: test
+ filter (mem => mem.isDeferredNotJavaDefault && !isUniversalMember(mem)) // TODO: test
)
// if there is only one, it's monomorphic and has a single argument list
diff --git a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
index 0eeca4aace..3e18f88f80 100644
--- a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
+++ b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
@@ -110,7 +110,7 @@ trait ExistentialsAndSkolems {
/**
* Compute an existential type from hidden symbols `hidden` and type `tp`.
* @param hidden The symbols that will be existentially abstracted
- * @param hidden The original type
+ * @param tp The original type
* @param rawOwner The owner for Java raw types.
*/
final def packSymbols(hidden: List[Symbol], tp: Type, rawOwner: Symbol = NoSymbol): Type =
diff --git a/src/reflect/scala/reflect/internal/FlagSets.scala b/src/reflect/scala/reflect/internal/FlagSets.scala
index ef9c77878f..b6521634fb 100644
--- a/src/reflect/scala/reflect/internal/FlagSets.scala
+++ b/src/reflect/scala/reflect/internal/FlagSets.scala
@@ -42,7 +42,7 @@ trait FlagSets extends api.FlagSets { self: SymbolTable =>
val DEFAULTPARAM : FlagSet = Flags.DEFAULTPARAM
val PRESUPER : FlagSet = Flags.PRESUPER
val DEFAULTINIT : FlagSet = Flags.DEFAULTINIT
- val ENUM : FlagSet = Flags.ENUM
+ val ENUM : FlagSet = Flags.JAVA_ENUM
val PARAMACCESSOR : FlagSet = Flags.PARAMACCESSOR
val CASEACCESSOR : FlagSet = Flags.CASEACCESSOR
val SYNTHETIC : FlagSet = Flags.SYNTHETIC
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index 1707061817..754b96a9dd 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -15,65 +15,65 @@ import scala.collection.{ mutable, immutable }
//
// Generated by mkFlagsTable() at Thu Feb 02 20:31:52 PST 2012
//
-// 0: PROTECTED/M
-// 1: OVERRIDE/M
-// 2: PRIVATE/M
-// 3: ABSTRACT/M
-// 4: DEFERRED/M
-// 5: FINAL/M
-// 6: METHOD
-// 7: INTERFACE/M
-// 8: MODULE
-// 9: IMPLICIT/M
-// 10: SEALED/M
-// 11: CASE/M
-// 12: MUTABLE/M
-// 13: PARAM/M
-// 14: PACKAGE
-// 15: MACRO/M
-// 16: BYNAMEPARAM/M CAPTURED COVARIANT/M
-// 17: CONTRAVARIANT/M INCONSTRUCTOR LABEL
-// 18: ABSOVERRIDE/M
-// 19: LOCAL/M
-// 20: JAVA/M
-// 21: SYNTHETIC
-// 22: STABLE
-// 23: STATIC/M
-// 24: CASEACCESSOR/M
-// 25: DEFAULTPARAM/M TRAIT/M
-// 26: BRIDGE
-// 27: ACCESSOR
-// 28: SUPERACCESSOR
-// 29: PARAMACCESSOR/M
-// 30: MODULEVAR
-// 31: LAZY/M
-// 32: IS_ERROR
-// 33: OVERLOADED
-// 34: LIFTED
-// 35: EXISTENTIAL MIXEDIN
-// 36: EXPANDEDNAME
-// 37: IMPLCLASS PRESUPER/M
-// 38: TRANS_FLAG
-// 39: LOCKED
-// 40: SPECIALIZED
-// 41: DEFAULTINIT/M
-// 42: VBRIDGE
-// 43: VARARGS
-// 44: TRIEDCOOKING
-// 45: SYNCHRONIZED/M
-// 46: ARTIFACT
-// 47: DEFAULTMETHOD/M
-// 48: ENUM
-// 49:
+// 0: PROTECTED/M
+// 1: OVERRIDE/M
+// 2: PRIVATE/M
+// 3: ABSTRACT/M
+// 4: DEFERRED/M
+// 5: FINAL/M
+// 6: METHOD
+// 7: INTERFACE/M
+// 8: MODULE
+// 9: IMPLICIT/M
+// 10: SEALED/M
+// 11: CASE/M
+// 12: MUTABLE/M
+// 13: PARAM/M
+// 14: PACKAGE
+// 15: MACRO/M
+// 16: BYNAMEPARAM/M CAPTURED COVARIANT/M
+// 17: CONTRAVARIANT/M INCONSTRUCTOR LABEL
+// 18: ABSOVERRIDE/M
+// 19: LOCAL/M
+// 20: JAVA/M
+// 21: SYNTHETIC
+// 22: STABLE
+// 23: STATIC/M
+// 24: CASEACCESSOR/M
+// 25: DEFAULTPARAM/M TRAIT/M
+// 26: BRIDGE
+// 27: ACCESSOR
+// 28: SUPERACCESSOR
+// 29: PARAMACCESSOR/M
+// 30: MODULEVAR
+// 31: LAZY/M
+// 32: IS_ERROR
+// 33: OVERLOADED
+// 34: LIFTED
+// 35: EXISTENTIAL MIXEDIN
+// 36: EXPANDEDNAME
+// 37: IMPLCLASS PRESUPER/M
+// 38: TRANS_FLAG
+// 39: LOCKED
+// 40: SPECIALIZED
+// 41: DEFAULTINIT/M
+// 42: VBRIDGE
+// 43: VARARGS
+// 44: TRIEDCOOKING
+// 45: SYNCHRONIZED/M
+// 46: ARTIFACT
+// 47: JAVA_DEFAULTMETHOD/M
+// 48: JAVA_ENUM
+// 49: JAVA_ANNOTATION
// 50:
-// 51: lateDEFERRED
-// 52: lateFINAL
-// 53: lateMETHOD
-// 54: lateINTERFACE
-// 55: lateMODULE
-// 56: notPROTECTED
-// 57: notOVERRIDE
-// 58: notPRIVATE
+// 51: lateDEFERRED
+// 52: lateFINAL
+// 53: lateMETHOD
+// 54: lateINTERFACE
+// 55: lateMODULE
+// 56: notPROTECTED
+// 57: notOVERRIDE
+// 58: notPRIVATE
// 59:
// 60:
// 61:
@@ -119,8 +119,9 @@ class ModifierFlags {
final val DEFAULTINIT = 1L << 41 // symbol is initialized to the default value: used by -Xcheckinit
final val ARTIFACT = 1L << 46 // symbol should be ignored when typechecking; will be marked ACC_SYNTHETIC in bytecode
// to see which symbols are marked as ARTIFACT, see scaladocs for FlagValues.ARTIFACT
- final val DEFAULTMETHOD = 1L << 47 // symbol is a java default method
- final val ENUM = 1L << 48 // symbol is an enum
+ final val JAVA_DEFAULTMETHOD = 1L << 47 // symbol is a java default method
+ final val JAVA_ENUM = 1L << 48 // symbol is a java enum
+ final val JAVA_ANNOTATION = 1L << 49 // symbol is a java annotation
// Overridden.
def flagToString(flag: Long): String = ""
@@ -172,12 +173,28 @@ class Flags extends ModifierFlags {
final val SYNCHRONIZED = 1L << 45 // symbol is a method which should be marked ACC_SYNCHRONIZED
// ------- shift definitions -------------------------------------------------------
+ //
+ // Flags from 1L to (1L << 50) are normal flags.
+ //
+ // The flags DEFERRED (1L << 4) to MODULE (1L << 8) have a `late` counterpart. Late flags change
+ // their counterpart from 0 to 1 after a specific phase (see below). The first late flag
+ // (lateDEFERRED) is at (1L << 51), i.e., late flags are shifted by 47. The last one is (1L << 55).
+ //
+ // The flags PROTECTED (1L) to PRIVATE (1L << 2) have a `not` counterpart. Negated flags change
+ // their counterpart from 1 to 0 after a specific phase (see below). They are shifted by 56, i.e.,
+ // the first negated flag (notPROTECTED) is at (1L << 56), the last at (1L << 58).
+ //
+ // Late and negative flags are only enabled after certain phases, implemented by the phaseNewFlags
+ // method of the SubComponent, so they implement a bit of a flag history.
+ //
+ // The flags (1L << 59) to (1L << 63) are currently unused. If added to the InitialFlags mask,
+ // they could be used as normal flags.
- final val InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1.
- final val LateFlags = 0x00FE000000000000L // flags that override flags in 0x1FC.
- final val AntiFlags = 0x7F00000000000000L // flags that cancel flags in 0x07F
- final val LateShift = 47L
- final val AntiShift = 56L
+ final val InitialFlags = 0x0007FFFFFFFFFFFFL // normal flags, enabled from the first phase: 1L to (1L << 50)
+ final val LateFlags = 0x00F8000000000000L // flags that override flags in (1L << 4) to (1L << 8): DEFERRED, FINAL, INTERFACE, METHOD, MODULE
+ final val AntiFlags = 0x0700000000000000L // flags that cancel flags in 1L to (1L << 2): PROTECTED, OVERRIDE, PRIVATE
+ final val LateShift = 47
+ final val AntiShift = 56
// Flags which sketchily share the same slot
// 16: BYNAMEPARAM/M CAPTURED COVARIANT/M
@@ -243,7 +260,7 @@ class Flags extends ModifierFlags {
*/
final val ExplicitFlags =
PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED |
- OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE | LAZY | DEFAULTMETHOD
+ OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE | LAZY | JAVA_DEFAULTMETHOD
/** The two bridge flags */
final val BridgeFlags = BRIDGE | VBRIDGE
@@ -434,9 +451,9 @@ class Flags extends ModifierFlags {
case TRIEDCOOKING => "<triedcooking>" // (1L << 44)
case SYNCHRONIZED => "<synchronized>" // (1L << 45)
case ARTIFACT => "<artifact>" // (1L << 46)
- case DEFAULTMETHOD => "<defaultmethod>" // (1L << 47)
- case ENUM => "<enum>" // (1L << 48)
- case 0x2000000000000L => "" // (1L << 49)
+ case JAVA_DEFAULTMETHOD => "<defaultmethod>" // (1L << 47)
+ case JAVA_ENUM => "<enum>" // (1L << 48)
+ case JAVA_ANNOTATION => "<annotation>" // (1L << 49)
case 0x4000000000000L => "" // (1L << 50)
case `lateDEFERRED` => "<latedeferred>" // (1L << 51)
case `lateFINAL` => "<latefinal>" // (1L << 52)
diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala
index aa8f4c532e..5162b15206 100644
--- a/src/reflect/scala/reflect/internal/HasFlags.scala
+++ b/src/reflect/scala/reflect/internal/HasFlags.scala
@@ -79,49 +79,50 @@ trait HasFlags {
// Tests which come through cleanly: both Symbol and Modifiers use these
// identically, testing for a single flag.
- def hasAbstractFlag = hasFlag(ABSTRACT)
- def hasAccessorFlag = hasFlag(ACCESSOR)
- def hasDefault = hasFlag(DEFAULTPARAM) && hasFlag(METHOD | PARAM) // Second condition disambiguates with TRAIT
- def hasEnumFlag = hasFlag(ENUM)
+ def hasAbstractFlag = hasFlag(ABSTRACT)
+ def hasAccessorFlag = hasFlag(ACCESSOR)
+ def hasDefault = hasFlag(DEFAULTPARAM) && hasFlag(METHOD | PARAM) // Second condition disambiguates with TRAIT
+ def hasJavaEnumFlag = hasFlag(JAVA_ENUM)
+ def hasJavaAnnotationFlag = hasFlag(JAVA_ANNOTATION)
@deprecated("Use isLocalToThis instead", "2.11.0")
- def hasLocalFlag = hasFlag(LOCAL)
- def isLocalToThis = hasFlag(LOCAL)
- def hasModuleFlag = hasFlag(MODULE)
- def hasPackageFlag = hasFlag(PACKAGE)
- def hasStableFlag = hasFlag(STABLE)
- def hasStaticFlag = hasFlag(STATIC)
- def isAbstractOverride = hasFlag(ABSOVERRIDE)
- def isAnyOverride = hasFlag(OVERRIDE | ABSOVERRIDE)
- def isCase = hasFlag(CASE)
- def isCaseAccessor = hasFlag(CASEACCESSOR)
- def isDeferred = hasFlag(DEFERRED)
- def isFinal = hasFlag(FINAL)
- def isArtifact = hasFlag(ARTIFACT)
- def isImplicit = hasFlag(IMPLICIT)
- def isInterface = hasFlag(INTERFACE)
- def isJavaDefined = hasFlag(JAVA)
- def isLabel = hasAllFlags(LABEL | METHOD) && !hasAccessorFlag
- def isLazy = hasFlag(LAZY)
- def isLifted = hasFlag(LIFTED)
- def isMacro = hasFlag(MACRO)
- def isMutable = hasFlag(MUTABLE)
- def isOverride = hasFlag(OVERRIDE)
- def isParamAccessor = hasFlag(PARAMACCESSOR)
- def isPrivate = hasFlag(PRIVATE)
+ def hasLocalFlag = hasFlag(LOCAL)
+ def isLocalToThis = hasFlag(LOCAL)
+ def hasModuleFlag = hasFlag(MODULE)
+ def hasPackageFlag = hasFlag(PACKAGE)
+ def hasStableFlag = hasFlag(STABLE)
+ def hasStaticFlag = hasFlag(STATIC)
+ def isAbstractOverride = hasFlag(ABSOVERRIDE)
+ def isAnyOverride = hasFlag(OVERRIDE | ABSOVERRIDE)
+ def isCase = hasFlag(CASE)
+ def isCaseAccessor = hasFlag(CASEACCESSOR)
+ def isDeferred = hasFlag(DEFERRED)
+ def isFinal = hasFlag(FINAL)
+ def isArtifact = hasFlag(ARTIFACT)
+ def isImplicit = hasFlag(IMPLICIT)
+ def isInterface = hasFlag(INTERFACE)
+ def isJavaDefined = hasFlag(JAVA)
+ def isLabel = hasAllFlags(LABEL | METHOD) && !hasAccessorFlag
+ def isLazy = hasFlag(LAZY)
+ def isLifted = hasFlag(LIFTED)
+ def isMacro = hasFlag(MACRO)
+ def isMutable = hasFlag(MUTABLE)
+ def isOverride = hasFlag(OVERRIDE)
+ def isParamAccessor = hasFlag(PARAMACCESSOR)
+ def isPrivate = hasFlag(PRIVATE)
@deprecated ("Use `hasPackageFlag` instead", "2.11.0")
- def isPackage = hasFlag(PACKAGE)
- def isPrivateLocal = hasAllFlags(PrivateLocal)
- def isProtected = hasFlag(PROTECTED)
- def isProtectedLocal = hasAllFlags(ProtectedLocal)
- def isPublic = hasNoFlags(PRIVATE | PROTECTED) && !hasAccessBoundary
- def isSealed = hasFlag(SEALED)
- def isSpecialized = hasFlag(SPECIALIZED)
- def isSuperAccessor = hasFlag(SUPERACCESSOR)
- def isSynthetic = hasFlag(SYNTHETIC)
- def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM)
-
- def isDeferredOrDefault = hasFlag(DEFERRED | DEFAULTMETHOD)
- def isDeferredNotDefault = isDeferred && !hasFlag(DEFAULTMETHOD)
+ def isPackage = hasFlag(PACKAGE)
+ def isPrivateLocal = hasAllFlags(PrivateLocal)
+ def isProtected = hasFlag(PROTECTED)
+ def isProtectedLocal = hasAllFlags(ProtectedLocal)
+ def isPublic = hasNoFlags(PRIVATE | PROTECTED) && !hasAccessBoundary
+ def isSealed = hasFlag(SEALED)
+ def isSpecialized = hasFlag(SPECIALIZED)
+ def isSuperAccessor = hasFlag(SUPERACCESSOR)
+ def isSynthetic = hasFlag(SYNTHETIC)
+ def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM)
+
+ def isDeferredOrJavaDefault = hasFlag(DEFERRED | JAVA_DEFAULTMETHOD)
+ def isDeferredNotJavaDefault = isDeferred && !hasFlag(JAVA_DEFAULTMETHOD)
def flagBitsToString(bits: Long): String = {
// Fast path for common case
diff --git a/src/reflect/scala/reflect/internal/Kinds.scala b/src/reflect/scala/reflect/internal/Kinds.scala
index 8ae201f045..902ba9fa80 100644
--- a/src/reflect/scala/reflect/internal/Kinds.scala
+++ b/src/reflect/scala/reflect/internal/Kinds.scala
@@ -237,7 +237,7 @@ trait Kinds {
*
* Proper types are represented using ProperTypeKind.
*
- * Type constructors are reprented using TypeConKind.
+ * Type constructors are represented using TypeConKind.
*/
abstract class Kind {
import Kind.StringState
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index 4d0e31b037..15d68bcdfe 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -252,7 +252,14 @@ trait Positions extends api.Positions { self: SymbolTable =>
super.traverse(t)
} else t match {
case mdef: MemberDef =>
- traverseTrees(mdef.mods.annotations)
+ val annTrees = mdef.mods.annotations match {
+ case Nil if mdef.symbol != null =>
+ // After typechecking, annotations are mvoed from the modifiers
+ // to the annotation on the symbol of the anotatee.
+ mdef.symbol.annotations.map(_.original)
+ case anns => anns
+ }
+ traverseTrees(annTrees)
case _ =>
}
}
diff --git a/src/reflect/scala/reflect/internal/SymbolPairs.scala b/src/reflect/scala/reflect/internal/SymbolPairs.scala
index 4763e77a34..a52d2d8510 100644
--- a/src/reflect/scala/reflect/internal/SymbolPairs.scala
+++ b/src/reflect/scala/reflect/internal/SymbolPairs.scala
@@ -217,7 +217,7 @@ abstract class SymbolPairs {
bs(nshifted) |= nmask
}
- /** Implements `bs1 * bs2 * {0..n} != 0.
+ /** Implements `bs1 * bs2 * {0..n} != 0`.
* Used in hasCommonParentAsSubclass */
private def intersectionContainsElementLeq(bs1: BitSet, bs2: BitSet, n: Int): Boolean = {
val nshifted = n >> 5
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 285d59c5e2..4bdb8e6da8 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -495,11 +495,24 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* failure to the point when that name is used for something, which is
* often to the point of never.
*/
- def newStubSymbol(name: Name, missingMessage: String): Symbol = name match {
- case n: TypeName => new StubClassSymbol(this, n, missingMessage)
+ def newStubSymbol(name: Name, missingMessage: String, isPackage: Boolean = false): Symbol = name match {
+ case n: TypeName => if (isPackage) new StubPackageClassSymbol(this, n, missingMessage) else new StubClassSymbol(this, n, missingMessage)
case _ => new StubTermSymbol(this, name.toTermName, missingMessage)
}
+ /** Given a field, construct a term symbol that represents the source construct that gave rise the the field */
+ def sugaredSymbolOrSelf = {
+ val getter = getterIn(owner)
+ if (getter == NoSymbol) {
+ this
+ } else {
+ val result = owner.newValue(getter.name.toTermName, newFlags = getter.flags & ~Flags.METHOD).setPrivateWithin(getter.privateWithin).setInfo(getter.info.resultType)
+ val setter = setterIn(owner)
+ if (setter != NoSymbol) result.setFlag(Flags.MUTABLE)
+ result
+ }
+ }
+
// ----- locking and unlocking ------------------------------------------------------
// True if the symbol is unlocked.
@@ -732,7 +745,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def flags: Long = {
if (Statistics.hotEnabled) Statistics.incCounter(flagsCount)
val fs = _rawflags & phase.flagMask
- (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift)
+ (fs | ((fs & LateFlags) >>> LateShift)) & ~((fs & AntiFlags) >>> AntiShift)
}
def flags_=(fs: Long) = _rawflags = fs
def rawflags_=(x: Long) { _rawflags = x }
@@ -1153,7 +1166,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* phase check (if after flatten) in the (overridden) method "def owner" in
* ModuleSymbol / ClassSymbol. The `rawowner` field is not modified.
* - Owners are also changed in other situations, for example when moving trees into a new
- * lexical context, e.g. in the named/default arguments tranformation, or when translating
+ * lexical context, e.g. in the named/default arguments transformation, or when translating
* extension method definitions.
*
* In general when seeking the owner of a symbol, one should call `owner`.
@@ -2113,7 +2126,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The package class containing this symbol, or NoSymbol if there
* is not one.
* TODO: formulate as enclosingSuchThat, after making sure
- * we can start with current symbol rather than onwner.
+ * we can start with current symbol rather than owner.
* TODO: Also harmonize with enclClass, enclMethod etc.
*/
def enclosingPackageClass: Symbol = {
@@ -3469,6 +3482,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def companionSymbol = fail(NoSymbol)
}
class StubClassSymbol(owner0: Symbol, name0: TypeName, val missingMessage: String) extends ClassSymbol(owner0, owner0.pos, name0) with StubSymbol
+ class StubPackageClassSymbol(owner0: Symbol, name0: TypeName, val missingMessage: String) extends PackageClassSymbol(owner0, owner0.pos, name0) with StubSymbol
class StubTermSymbol(owner0: Symbol, name0: TermName, val missingMessage: String) extends TermSymbol(owner0, owner0.pos, name0) with StubSymbol
trait FreeSymbol extends Symbol {
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index b2248ad518..201b727ed6 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -594,13 +594,12 @@ abstract class TreeGen {
* TupleN(x_1, ..., x_N)
* } ...)
*
- * If any of the P_i are variable patterns, the corresponding `x_i @ P_i' is not generated
+ * If any of the P_i are variable patterns, the corresponding `x_i @ P_i` is not generated
* and the variable constituting P_i is used instead of x_i
*
- * @param mapName The name to be used for maps (either map or foreach)
- * @param flatMapName The name to be used for flatMaps (either flatMap or foreach)
* @param enums The enumerators in the for expression
- * @param body The body of the for expression
+ * @param sugarBody The body of the for expression
+ * @param fresh A source of new names
*/
def mkFor(enums: List[Tree], sugarBody: Tree)(implicit fresh: FreshNameCreator): Tree = {
val (mapName, flatMapName, body) = sugarBody match {
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index e3f95f9fd8..bbd9df05d2 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -1418,7 +1418,7 @@ trait Trees extends api.Trees {
transformTypeDefs(tparams), transform(rhs))
}
case LabelDef(name, params, rhs) =>
- treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LamdaLifter.proxy'
+ treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LambdaLifter.proxy'
case PackageDef(pid, stats) =>
treeCopy.PackageDef(
tree, transform(pid).asInstanceOf[RefTree],
@@ -1601,7 +1601,7 @@ trait Trees extends api.Trees {
case _ =>
// no special handling is required for Function or Import nodes here.
// as they don't have interesting infos attached to their symbols.
- // Subsitution of the referenced symbol of Return nodes is handled
+ // Substitution of the referenced symbol of Return nodes is handled
// in .ChangeOwnerTraverser
}
tree match {
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 8c72405c8d..9697e16da7 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -732,7 +732,7 @@ trait Types
*
* `SubstThisAndSymMap` performs a breadth-first map over this type, which meant that
* symbol substitution occurred before `ThisType` substitution. Consequently, in substitution
- * of a `SingleType(ThisType(`from`), sym), symbols were rebound to `from` rather than `to`.
+ * of a `SingleType(ThisType(from), sym)`, symbols were rebound to `from` rather than `to`.
*/
def substThisAndSym(from: Symbol, to: Type, symsFrom: List[Symbol], symsTo: List[Symbol]): Type =
if (symsFrom eq symsTo) substThis(from, to)
@@ -756,7 +756,7 @@ trait Types
/** Apply `f` to each part of this type */
def foreach(f: Type => Unit) { new ForEachTypeTraverser(f).traverse(this) }
- /** Apply `pf' to each part of this type on which the function is defined */
+ /** Apply `pf` to each part of this type on which the function is defined */
def collect[T](pf: PartialFunction[Type, T]): List[T] = new CollectTypeCollector(pf).collect(this)
/** Apply `f` to each part of this type; children get mapped before their parents */
@@ -2045,7 +2045,7 @@ trait Types
/** SI-3731, SI-8177: when prefix is changed to `newPre`, maintain consistency of prefix and sym
* (where the symbol refers to a declaration "embedded" in the prefix).
*
- * @returns newSym so that `newPre` binds `sym.name` to `newSym`,
+ * @return newSym so that `newPre` binds `sym.name` to `newSym`,
* to remain consistent with `pre` previously binding `sym.name` to `sym`.
*
* `newSym` and `sym` are conceptually the same symbols, but some change to our `prefix`
@@ -2510,6 +2510,9 @@ trait Types
override def baseType(clazz: Symbol): Type = resultType.baseType(clazz)
override def narrow: Type = resultType.narrow
+ // SI-9475: PolyTypes with dependent method types are still dependent
+ override def isDependentMethodType = resultType.isDependentMethodType
+
/** @M: typeDefSig wraps a TypeBounds in a PolyType
* to represent a higher-kinded type parameter
* wrap lo&hi in polytypes to bind variables
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 1fc7aebab0..a9020a3d4c 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -168,7 +168,7 @@ abstract class UnPickler {
}
/** If entry at `i` is undefined, define it by performing
- * operation `op` with `readIndex at start of i'th
+ * operation `op` with `readIndex` at start of i'th
* entry. Restore `readIndex` afterwards.
*/
protected def at[T <: AnyRef](i: Int, op: () => T): T = {
@@ -244,7 +244,7 @@ abstract class UnPickler {
(module map { case (group, art) =>
s"""\n(NOTE: It looks like the $art module is missing; try adding a dependency on "$group" : "$art".
- | See http://docs.scala-lang.org/overviews/core/scala-2.11.html for more information.)""".stripMargin
+ | See http://docs.scala-lang.org/overviews/ for more information.)""".stripMargin
} getOrElse "")
}
@@ -398,7 +398,7 @@ abstract class UnPickler {
val sym = readSymbolRef() match {
case stub: StubSymbol if !stub.isClass =>
// SI-8502 This allows us to create a stub for a unpickled reference to `missingPackage.Foo`.
- stub.owner.newStubSymbol(stub.name.toTypeName, stub.missingMessage)
+ stub.owner.newStubSymbol(stub.name.toTypeName, stub.missingMessage, isPackage = true)
case sym => sym
}
ThisType(sym)
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index 15a87200f1..b8d4050d7d 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
@@ -343,7 +343,7 @@ private[internal] trait TypeMaps {
object rawToExistentialInJava extends TypeMap {
def apply(tp: Type): Type = tp match {
// any symbol that occurs in a java sig, not just java symbols
- // see http://lampsvn.epfl.ch/trac/scala/ticket/2454#comment:14
+ // see https://issues.scala-lang.org/browse/SI-2454?focusedCommentId=46618
case TypeRef(pre, sym, List()) if !sym.typeParams.isEmpty =>
val eparams = typeParamsToExistentials(sym, sym.typeParams)
existentialAbstraction(eparams, TypeRef(pre, sym, eparams map (_.tpe)))
@@ -736,7 +736,7 @@ private[internal] trait TypeMaps {
substFor(sym)
case ClassInfoType(parents, decls, sym) =>
val parents1 = parents mapConserve this
- // We don't touch decls here; they will be touched when an enclosing TreeSubstitutor
+ // We don't touch decls here; they will be touched when an enclosing TreeSubstituter
// transforms the tree that defines them.
if (parents1 eq parents) tp
else ClassInfoType(parents1, decls, sym)
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index 707972242a..01e28e5642 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -90,7 +90,7 @@ trait Erasure {
}
}
- /** Does this vakue class have an underlying type that's a type parameter of
+ /** Does this value class have an underlying type that's a type parameter of
* the class itself?
* This method needs to be called at a phase no later than erasurephase
*/
diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
index abea8bed9f..85e3ac60e8 100644
--- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala
+++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
@@ -40,19 +40,27 @@ trait UnCurry {
apply(MethodType(h.cloneSymbol.resetFlag(IMPLICIT) :: t, restpe))
case NullaryMethodType(restpe) =>
apply(MethodType(List(), restpe))
- case TypeRef(pre, ByNameParamClass, arg :: Nil) =>
- apply(functionType(List(), arg))
- case TypeRef(pre, RepeatedParamClass, arg :: Nil) =>
- apply(seqType(arg))
- case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) =>
- apply(arrayType(
- if (isUnboundedGeneric(arg)) ObjectTpe else arg))
+ case DesugaredParameterType(desugaredTpe) =>
+ apply(desugaredTpe)
case _ =>
expandAlias(mapOver(tp))
}
}
}
+ object DesugaredParameterType {
+ def unapply(tpe: Type): Option[Type] = tpe match {
+ case TypeRef(pre, ByNameParamClass, arg :: Nil) =>
+ Some(functionType(List(), arg))
+ case TypeRef(pre, RepeatedParamClass, arg :: Nil) =>
+ Some(seqType(arg))
+ case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) =>
+ Some(arrayType(if (isUnboundedGeneric(arg)) ObjectTpe else arg))
+ case _ =>
+ None
+ }
+ }
+
private val uncurryType = new TypeMap {
def apply(tp0: Type): Type = {
val tp = expandAlias(tp0)
diff --git a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
index 30dcbc21ca..5cbdb92664 100644
--- a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
+++ b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
@@ -12,7 +12,7 @@ import java.security.cert.Certificate
import java.security.{ ProtectionDomain, CodeSource }
import java.util.{ Collections => JCollections, Enumeration => JEnumeration }
-/** A class loader that loads files from a {@link scala.tools.nsc.io.AbstractFile}.
+/** A class loader that loads files from a [[scala.reflect.io.AbstractFile]].
*
* @author Lex Spoon
*/
diff --git a/src/reflect/scala/reflect/io/Streamable.scala b/src/reflect/scala/reflect/io/Streamable.scala
index aa47947672..99a14d1fb0 100644
--- a/src/reflect/scala/reflect/io/Streamable.scala
+++ b/src/reflect/scala/reflect/io/Streamable.scala
@@ -27,6 +27,10 @@ object Streamable {
* efficient method implementations.
*
* ''Note: This library is considered experimental and should not be used unless you know what you are doing.''
+ *
+ * Note that this code was not written with resource management in mind.
+ * Several methods (such as `chars` and `lines`) create InputStreams they
+ * don't close
*/
trait Bytes {
def inputStream(): InputStream
@@ -82,9 +86,13 @@ object Streamable {
*/
def creationCodec: Codec = implicitly[Codec]
+ /** Caller is responsible for closing the returned BufferedSource. */
def chars(codec: Codec): BufferedSource = Source.fromInputStream(inputStream())(codec)
+ /** Beware! Leaks an InputStream which will not be closed until it gets finalized. */
def lines(): Iterator[String] = lines(creationCodec)
+
+ /** Beware! Leaks an InputStream which will not be closed until it gets finalized. */
def lines(codec: Codec): Iterator[String] = chars(codec).getLines()
/** Obtains an InputStreamReader wrapped around a FileInputStream.
diff --git a/src/reflect/scala/reflect/macros/blackbox/Context.scala b/src/reflect/scala/reflect/macros/blackbox/Context.scala
index 2f9c512efa..ce28b5911e 100644
--- a/src/reflect/scala/reflect/macros/blackbox/Context.scala
+++ b/src/reflect/scala/reflect/macros/blackbox/Context.scala
@@ -29,7 +29,7 @@ package blackbox
* which means that its expansion will be upcast to its return type, enforcing faithfullness of that macro to its
* type signature. Whitebox macros, i.e. the ones defined with `whitebox.Context`, aren't bound by this restriction,
* which enables a number of important use cases, but they are also going to enjoy less support than blackbox macros,
- * so choose wisely. See the [[http://docs.scala-lang.org/overviews/macros.html Macros Guide]] for more information.
+ * so choose wisely. See the [[http://docs.scala-lang.org/overviews/macros/overview.html Macros Guide]] for more information.
*
* @see `scala.reflect.macros.whitebox.Context`
*/
diff --git a/src/reflect/scala/reflect/macros/package.scala b/src/reflect/scala/reflect/macros/package.scala
index cc7111d794..b63d419d61 100644
--- a/src/reflect/scala/reflect/macros/package.scala
+++ b/src/reflect/scala/reflect/macros/package.scala
@@ -10,14 +10,14 @@ package reflect
* Within these functions the programmer has access to compiler APIs.
* For example, it is possible to generate, analyze and typecheck code.
*
- * See the [[http://docs.scala-lang.org/overviews/macros.html Macros Guide]] on how to get started with Scala macros.
+ * See the [[http://docs.scala-lang.org/overviews/macros/overview.html Macros Guide]] on how to get started with Scala macros.
*/
package object macros {
/** The Scala macros context.
*
* In Scala 2.11, macros that were once the one are split into blackbox and whitebox macros,
* with the former being better supported and the latter being more powerful. You can read about
- * the details of the split and the associated trade-offs in the [[http://docs.scala-lang.org/overviews/macros.html Macros Guide]].
+ * the details of the split and the associated trade-offs in the [[http://docs.scala-lang.org/overviews/macros/overview.html Macros Guide]].
*
* `scala.reflect.macros.Context` follows this tendency and turns into `scala.reflect.macros.blackbox.Context`
* and `scala.reflect.macros.whitebox.Context`. The original `Context` is left in place for compatibility reasons,
diff --git a/src/reflect/scala/reflect/macros/whitebox/Context.scala b/src/reflect/scala/reflect/macros/whitebox/Context.scala
index bd48df46cc..272991cba9 100644
--- a/src/reflect/scala/reflect/macros/whitebox/Context.scala
+++ b/src/reflect/scala/reflect/macros/whitebox/Context.scala
@@ -29,7 +29,7 @@ package whitebox
* gaining the ability to refine the type of its expansion beyond its official return type, which enables a number of important use cases.
* Blackbox macros, i.e. the ones defined with `blackbox.Context`, can't do that, so they are less powerful.
* However blackbox macros are also going to enjoy better support than whitebox macros, so choose wisely.
- * See the [[http://docs.scala-lang.org/overviews/macros.html Macros Guide]] for more information.
+ * See the [[http://docs.scala-lang.org/overviews/macros/overview.html Macros Guide]] for more information.
*
* @see `scala.reflect.macros.blackbox.Context`
*/
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 8c32a92ecd..50442519f2 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -124,9 +124,9 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
private def ErrorArrayConstructor(sym: Symbol, owner: Symbol) = abort(s"Cannot instantiate arrays with mirrors. Consider using `scala.reflect.ClassTag(<class of element>).newArray(<length>)` instead")
private def ErrorFree(member: Symbol, freeType: Symbol) = abort(s"cannot reflect ${member.kindString} ${member.name}, because it's a member of a weak type ${freeType.name}")
private def ErrorNonExistentField(sym: Symbol) = abort(
- sm"""Scala field ${sym.name} isn't represented as a Java field, neither it has a Java accessor method
- |note that private parameters of class constructors don't get mapped onto fields and/or accessors,
- |unless they are used outside of their declaring constructors.""")
+ sm"""Scala field ${sym.name} of ${sym.owner} isn't represented as a Java field, nor does it have a
+ |Java accessor method. One common reason for this is that it may be a private class parameter
+ |not used outside the primary constructor.""")
/** Helper functions for extracting typed values from a (Class[_], Any)
* representing an annotation argument.
@@ -755,6 +755,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
val ifaces = jclazz.getGenericInterfaces.toList map typeToScala
val isAnnotation = JavaAccFlags(jclazz).isAnnotation
if (isAnnotation) AnnotationClass.tpe :: ClassfileAnnotationClass.tpe :: ifaces
+ else if (jclazz.isInterface) ObjectTpe :: ifaces // interfaces have Object as superclass in the classfile (see jvm spec), but getGenericSuperclass seems to return null
else (if (jsuperclazz == null) AnyTpe else typeToScala(jsuperclazz)) :: ifaces
} finally {
parentsLevel -= 1
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index ea213cadd9..7725e4a2f0 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -106,7 +106,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.AnnotationInfo
this.Annotation
this.UnmappableAnnotation
- this.ErroneousAnnotation
this.ThrownException
this.typeNames
this.tpnme
@@ -444,7 +443,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.ScalaValueClassesNoUnit
definitions.ScalaValueClasses
-
+ uncurry.DesugaredParameterType
erasure.GenericArray
erasure.scalaErasure
erasure.specialScalaErasure
diff --git a/src/reflect/scala/reflect/runtime/TwoWayCache.scala b/src/reflect/scala/reflect/runtime/TwoWayCache.scala
index d0fc3dac74..6c1ca5b571 100644
--- a/src/reflect/scala/reflect/runtime/TwoWayCache.scala
+++ b/src/reflect/scala/reflect/runtime/TwoWayCache.scala
@@ -26,8 +26,7 @@ private[runtime] class TwoWayCache[J, S] {
private object SomeRef {
def unapply[T](optRef: Option[WeakReference[T]]): Option[T] =
if (optRef.nonEmpty) {
- val result = optRef.get.get
- if (result != null) Some(result) else None
+ Option(optRef.get.get)
} else None
}
diff --git a/src/reflect/scala/reflect/runtime/TwoWayCaches.scala b/src/reflect/scala/reflect/runtime/TwoWayCaches.scala
index 6e2890e536..6ce0c0a728 100644
--- a/src/reflect/scala/reflect/runtime/TwoWayCaches.scala
+++ b/src/reflect/scala/reflect/runtime/TwoWayCaches.scala
@@ -26,8 +26,7 @@ private[runtime] trait TwoWayCaches { self: SymbolTable =>
private object SomeRef {
def unapply[T](optRef: Option[WeakReference[T]]): Option[T] =
if (optRef.nonEmpty) {
- val result = optRef.get.get
- if (result != null) Some(result) else None
+ Option(optRef.get.get)
} else None
}
diff --git a/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala
index c18a9809a0..89e849429d 100644
--- a/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala
+++ b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala
@@ -11,7 +11,7 @@ import _root_.jline.console.completer.ArgumentCompleter.{ ArgumentDelimiter, Arg
// implements a jline interface
class JLineDelimiter extends ArgumentDelimiter {
- def toJLine(args: List[String], cursor: Int) = args match {
+ def toJLine(args: List[String], cursor: Int): ArgumentList = args match {
case Nil => new ArgumentList(new Array[String](0), 0, 0, cursor)
case xs => new ArgumentList(xs.toArray, xs.size - 1, xs.last.length, cursor)
}
diff --git a/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineReader.scala b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineReader.scala
index f0fce13fe8..b5db4c2098 100644
--- a/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineReader.scala
+++ b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineReader.scala
@@ -10,12 +10,13 @@ package scala.tools.nsc.interpreter.jline
import java.util.{Collection => JCollection, List => JList}
import _root_.jline.{console => jconsole}
-import jconsole.completer.{Completer, ArgumentCompleter}
+import jline.console.ConsoleReader
+import jline.console.completer.{CompletionHandler, Completer, ArgumentCompleter}
import jconsole.history.{History => JHistory}
import scala.tools.nsc.interpreter
-import scala.tools.nsc.interpreter.Completion
+import scala.tools.nsc.interpreter.{Completion, JLineCompletion, NoCompletion}
import scala.tools.nsc.interpreter.Completion.Candidates
import scala.tools.nsc.interpreter.session.History
@@ -121,23 +122,48 @@ private class JLineConsoleReader extends jconsole.ConsoleReader with interpreter
def initCompletion(completion: Completion): Unit = {
this setBellEnabled false
- if (completion ne interpreter.NoCompletion) {
- val jlineCompleter = new ArgumentCompleter(new JLineDelimiter,
- new Completer {
- val tc = completion.completer()
- def complete(_buf: String, cursor: Int, candidates: JList[CharSequence]): Int = {
- val buf = if (_buf == null) "" else _buf
- val Candidates(newCursor, newCandidates) = tc.complete(buf, cursor)
- newCandidates foreach (candidates add _)
- newCursor
- }
- }
- )
-
- jlineCompleter setStrict false
-
- this addCompleter jlineCompleter
- this setAutoprintThreshold 400 // max completion candidates without warning
+ // adapt the JLine completion interface
+ def completer =
+ new Completer {
+ val tc = completion.completer()
+ def complete(_buf: String, cursor: Int, candidates: JList[CharSequence]): Int = {
+ val buf = if (_buf == null) "" else _buf
+ val Candidates(newCursor, newCandidates) = tc.complete(buf, cursor)
+ newCandidates foreach (candidates add _)
+ newCursor
+ }
+ }
+
+ // a last bit of nastiness: parsing help depending on the flavor of completer (fixme)
+ completion match {
+ case _: JLineCompletion =>
+ val jlineCompleter = new ArgumentCompleter(new JLineDelimiter, completer)
+ jlineCompleter setStrict false
+ this addCompleter jlineCompleter
+ case NoCompletion => ()
+ case _ => this addCompleter completer
}
+
+ // This is a workaround for https://github.com/jline/jline2/issues/208
+ // and should not be necessary once we upgrade to JLine 2.13.1
+ ///
+ // Test by:
+ // scala> {" ".char}<LEFT><TAB>
+ //
+ // And checking we don't get an extra } on the line.
+ ///
+ val handler = getCompletionHandler
+ setCompletionHandler(new CompletionHandler {
+ override def complete(consoleReader: ConsoleReader, list: JList[CharSequence], i: Int): Boolean = {
+ try {
+ handler.complete(consoleReader, list, i)
+ } finally if (getCursorBuffer.cursor != getCursorBuffer.length()) {
+ print(" ")
+ getCursorBuffer.write(' ')
+ backspace()
+ }
+ }
+ })
+ setAutoprintThreshold(400) // max completion candidates without warning
}
}
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index 6470a450b2..f844029b64 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -1,8 +1,7 @@
/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
+ * Copyright 2005-2015 LAMP/EPFL
* @author Alexander Spoon
*/
-
package scala
package tools.nsc
package interpreter
@@ -24,9 +23,9 @@ import io.AbstractFile
import scala.collection.generic.Clearable
import scala.concurrent.{ ExecutionContext, Await, Future, future }
import ExecutionContext.Implicits._
-import java.io.{ BufferedReader, FileReader }
+import java.io.{ BufferedReader, FileReader, StringReader }
-import scala.util.{Try, Success, Failure}
+import scala.util.{ Try, Success, Failure }
/** The Scala interactive shell. It provides a read-eval-print loop
* around the Interpreter class.
@@ -658,12 +657,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
unleashAndSetPhase()
asyncEcho(isDuringInit, power.banner)
}
- private def unleashAndSetPhase() {
- if (isReplPower) {
- power.unleash()
- // Set the phase to "typer"
- intp beSilentDuring phaseCommand("typer")
- }
+ private def unleashAndSetPhase() = if (isReplPower) {
+ power.unleash()
+ intp beSilentDuring phaseCommand("typer") // Set the phase to "typer"
}
def asyncEcho(async: Boolean, msg: => String) {
@@ -751,28 +747,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
result
}
- private object paste extends Pasted {
- import scala.util.matching.Regex.quote
- val ContinuePrompt = replProps.continuePrompt
- val ContinueString = replProps.continueText // " | "
- val PromptString = prompt.lines.toList.last
- val anyPrompt = s"""\\s*(?:${quote(PromptString.trim)}|${quote(AltPromptString.trim)})\\s*""".r
-
- def isPrompted(line: String) = matchesPrompt(line)
- def isPromptOnly(line: String) = line match { case anyPrompt() => true ; case _ => false }
-
- def interpret(line: String): Unit = {
- echo(line.trim)
- intp interpret line
- echo("")
- }
-
- def transcript(start: String) = {
- echo("\n// Detected repl transcript paste: ctrl-D to finish.\n")
- apply(Iterator(start) ++ readWhile(!isPromptOnly(_)))
- }
-
- def unapply(line: String): Boolean = isPrompted(line)
+ private object paste extends Pasted(prompt) {
+ def interpret(line: String) = intp interpret line
+ def echo(message: String) = ILoop.this echo message
}
private object invocation {
@@ -787,30 +764,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
* read, go ahead and interpret it. Return the full string
* to be recorded for replay, if any.
*/
- def interpretStartingWith(code: String): Option[String] = {
+ final def interpretStartingWith(code: String): Option[String] = {
// signal completion non-completion input has been received
in.completion.resetVerbosity()
- def reallyInterpret = intp.interpret(code) match {
- case IR.Error => None
- case IR.Success => Some(code)
- case IR.Incomplete if in.interactive && code.endsWith("\n\n") =>
- echo("You typed two blank lines. Starting a new command.")
- None
- case IR.Incomplete =>
- in.readLine(paste.ContinuePrompt) match {
- case null =>
- // we know compilation is going to fail since we're at EOF and the
- // parser thinks the input is still incomplete, but since this is
- // a file being read non-interactively we want to fail. So we send
- // it straight to the compiler for the nice error message.
- intp.compileString(code)
- None
-
- case line => interpretStartingWith(code + "\n" + line)
- }
- }
-
/* Here we place ourselves between the user and the interpreter and examine
* the input they are ostensibly submitting. We intervene in several cases:
*
@@ -823,9 +780,33 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
code match {
case "" => None
case lineComment() => None // line comment, do nothing
- case paste() if !paste.running => paste.transcript(code) ; None
+ case paste() if !paste.running => paste.transcript(Iterator(code) ++ readWhile(!paste.isPromptOnly(_))) match {
+ case Some(s) => interpretStartingWith(s)
+ case _ => None
+ }
case invocation() if intp.mostRecentVar != "" => interpretStartingWith(intp.mostRecentVar + code)
- case _ => reallyInterpret
+ case _ => intp.interpret(code) match {
+ case IR.Error => None
+ case IR.Success => Some(code)
+ case IR.Incomplete if in.interactive && code.endsWith("\n\n") =>
+ echo("You typed two blank lines. Starting a new command.")
+ None
+ case IR.Incomplete =>
+ val saved = intp.partialInput
+ intp.partialInput = code + "\n"
+ try {
+ in.readLine(paste.ContinuePrompt) match {
+ case null =>
+ // we know compilation is going to fail since we're at EOF and the
+ // parser thinks the input is still incomplete, but since this is
+ // a file being read non-interactively we want to fail. So we send
+ // it straight to the compiler for the nice error message.
+ intp.compileString(code)
+ None
+ case line => interpretStartingWith(s"$code\n$line")
+ }
+ } finally intp.partialInput = saved
+ }
}
}
@@ -841,9 +822,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
case _ =>
}
- /** Tries to create a JLineReader, falling back to SimpleReader:
- * unless settings or properties are such that it should start
- * with SimpleReader.
+ /** Tries to create a JLineReader, falling back to SimpleReader,
+ * unless settings or properties are such that it should start with SimpleReader.
+ * The constructor of the InteractiveReader must take a Completion strategy,
+ * supplied as a `() => Completion`; the Completion object provides a concrete Completer.
*/
def chooseReader(settings: Settings): InteractiveReader = {
if (settings.Xnojline || Properties.isEmacsShell) SimpleReader()
@@ -851,20 +833,25 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
type Completer = () => Completion
type ReaderMaker = Completer => InteractiveReader
- def instantiate(className: String): ReaderMaker = completer => {
- if (settings.debug) Console.println(s"Trying to instantiate a InteractiveReader from $className")
+ def instantiater(className: String): ReaderMaker = completer => {
+ if (settings.debug) Console.println(s"Trying to instantiate an InteractiveReader from $className")
Class.forName(className).getConstructor(classOf[Completer]).
newInstance(completer).
asInstanceOf[InteractiveReader]
}
- def mkReader(maker: ReaderMaker) =
- if (settings.noCompletion) maker(() => NoCompletion)
- else maker(() => new JLineCompletion(intp)) // JLineCompletion is a misnomer -- it's not tied to jline
+ def mkReader(maker: ReaderMaker) = maker { () =>
+ settings.completion.value match {
+ case _ if settings.noCompletion => NoCompletion
+ case "none" => NoCompletion
+ case "adhoc" => new JLineCompletion(intp) // JLineCompletion is a misnomer; it's not tied to jline
+ case "pc" | _ => new PresentationCompilerCompleter(intp)
+ }
+ }
def internalClass(kind: String) = s"scala.tools.nsc.interpreter.$kind.InteractiveReader"
val readerClasses = sys.props.get("scala.repl.reader").toStream ++ Stream(internalClass("jline"), internalClass("jline_embedded"))
- val readers = readerClasses map (cls => Try { mkReader(instantiate(cls)) })
+ val readers = readerClasses map (cls => Try { mkReader(instantiater(cls)) })
val reader = (readers collect { case Success(reader) => reader } headOption) getOrElse SimpleReader()
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 841b4abfa5..ef6ab4063a 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -15,10 +15,13 @@ import scala.concurrent.{ Future, ExecutionContext }
import scala.reflect.runtime.{ universe => ru }
import scala.reflect.{ ClassTag, classTag }
import scala.reflect.internal.util.{ BatchSourceFile, SourceFile }
+import scala.tools.nsc.interactive
+import scala.tools.nsc.reporters.StoreReporter
+import scala.tools.nsc.util.ClassPath.DefaultJavaContext
import scala.tools.util.PathResolverFactory
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.typechecker.{ TypeStrings, StructuredTypeStrings }
-import scala.tools.nsc.util.{ ScalaClassLoader, stringFromReader, stringFromWriter, StackTraceOps, ClassPath, MergedClassPath }
+import scala.tools.nsc.util._
import ScalaClassLoader.URLClassLoader
import scala.tools.nsc.util.Exceptional.unwrap
import scala.tools.nsc.backend.JavaPlatform
@@ -58,7 +61,7 @@ import java.io.File
* @author Moez A. Abdel-Gawad
* @author Lex Spoon
*/
-class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Settings, protected val out: JPrintWriter) extends AbstractScriptEngine with Compilable with Imports {
+class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Settings, protected val out: JPrintWriter) extends AbstractScriptEngine with Compilable with Imports with PresentationCompilation {
imain =>
setBindings(createBindings, ScriptContext.ENGINE_SCOPE)
@@ -77,6 +80,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
private var _isInitialized: Future[Boolean] = null // set up initialization future
private var bindExceptions = true // whether to bind the lastException variable
private var _executionWrapper = "" // code to be wrapped around all lines
+ var partialInput: String = "" // code accumulated in multi-line REPL input
/** We're going to go to some trouble to initialize the compiler asynchronously.
* It's critical that nothing call into it until it's been initialized or we will
@@ -133,7 +137,6 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
}
catch AbstractOrMissingHandler()
}
- private def tquoted(s: String) = "\"\"\"" + s + "\"\"\""
private val logScope = scala.sys.props contains "scala.repl.scope"
private def scopelog(msg: String) = if (logScope) Console.err.println(msg)
@@ -447,7 +450,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
/** Build a request from the user. `trees` is `line` after being parsed.
*/
- private def buildRequest(line: String, trees: List[Tree]): Request = {
+ private[interpreter] def buildRequest(line: String, trees: List[Tree]): Request = {
executingRequest = new Request(line, trees)
executingRequest
}
@@ -466,11 +469,12 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
pos
}
- private def requestFromLine(line: String, synthetic: Boolean): Either[IR.Result, Request] = {
- val content = line //indentCode(line)
- val trees = parse(content) match {
- case parse.Incomplete => return Left(IR.Incomplete)
- case parse.Error => return Left(IR.Error)
+ private[interpreter] def requestFromLine(line: String, synthetic: Boolean): Either[IR.Result, Request] = {
+ val content = line
+
+ val trees: List[global.Tree] = parse(content) match {
+ case parse.Incomplete(_) => return Left(IR.Incomplete)
+ case parse.Error(_) => return Left(IR.Error)
case parse.Success(trees) => trees
}
repltrace(
@@ -855,7 +859,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
}
/** One line of code submitted by the user for interpretation */
- class Request(val line: String, val trees: List[Tree]) {
+ class Request(val line: String, val trees: List[Tree], generousImports: Boolean = false) {
def defines = defHandlers flatMap (_.definedSymbols)
def imports = importedSymbols
def value = Some(handlers.last) filter (h => h.definesValue) map (h => definedSymbols(h.definesTerm.get)) getOrElse NoSymbol
@@ -888,8 +892,8 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
/** Code to import bound names from previous lines - accessPath is code to
* append to objectName to access anything bound by request.
*/
- lazy val ComputedImports(importsPreamble, importsTrailer, accessPath) =
- exitingTyper(importsCode(referencedNames.toSet, ObjectSourceCode, definesClass))
+ lazy val ComputedImports(headerPreamble, importsPreamble, importsTrailer, accessPath) =
+ exitingTyper(importsCode(referencedNames.toSet, ObjectSourceCode, definesClass, generousImports))
/** the line of code to compute */
def toCompute = line
@@ -905,13 +909,18 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def path = originalPath("$intp")
def envLines = {
if (!isReplPower) Nil // power mode only for now
- else List("def %s = %s".format("$line", tquoted(originalLine)), "def %s = Nil".format("$trees"))
+ else {
+ val escapedLine = Constant(originalLine).escapedStringValue
+ List(s"""def $$line = $escapedLine """, """def $trees = _root_.scala.Nil""")
+ }
}
def preamble = s"""
+ |$headerPreamble
|${preambleHeader format lineRep.readName}
|${envLines mkString (" ", ";\n ", ";\n")}
|$importsPreamble
|${indentCode(toCompute)}""".stripMargin
+ def preambleLength = preamble.length - toCompute.length - 1
val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this
@@ -951,7 +960,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def postwrap = s"}\nval $iw = new $iw\n"
}
- private lazy val ObjectSourceCode: Wrapper =
+ private[interpreter] lazy val ObjectSourceCode: Wrapper =
if (isClassBased) new ClassBasedWrapper else new ObjectBasedWrapper
private object ResultObjectSourceCode extends IMain.CodeAssembler[MemberHandler] {
@@ -1012,6 +1021,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
}
lazy val resultSymbol = lineRep.resolvePathToSymbol(fullAccessPath)
+
def applyToResultMember[T](name: Name, f: Symbol => T) = exitingTyper(f(resultSymbol.info.nonPrivateDecl(name)))
/* typeOf lookup with encoding */
@@ -1165,20 +1175,22 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
/** Parse a line into and return parsing result (error, incomplete or success with list of trees) */
object parse {
- abstract sealed class Result
- case object Error extends Result
- case object Incomplete extends Result
+ abstract sealed class Result { def trees: List[Tree] }
+ case class Error(trees: List[Tree]) extends Result
+ case class Incomplete(trees: List[Tree]) extends Result
case class Success(trees: List[Tree]) extends Result
def apply(line: String): Result = debugging(s"""parse("$line")""") {
var isIncomplete = false
- currentRun.parsing.withIncompleteHandler((_, _) => isIncomplete = true) {
+ def parse = {
reporter.reset()
val trees = newUnitParser(line).parseStats()
- if (reporter.hasErrors) Error
- else if (isIncomplete) Incomplete
+ if (reporter.hasErrors) Error(trees)
+ else if (isIncomplete) Incomplete(trees)
else Success(trees)
}
+ currentRun.parsing.withIncompleteHandler((_, _) => isIncomplete = true) {parse}
+
}
}
@@ -1261,6 +1273,8 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
/** Utility methods for the Interpreter. */
object IMain {
import java.util.Arrays.{ asList => asJavaList }
+ /** Dummy identifier fragement inserted at the cursor before presentation compilation. Needed to support completion of `global.def<TAB>` */
+ val DummyCursorFragment = "_CURSOR_"
class Factory extends ScriptEngineFactory {
@BeanProperty
@@ -1358,3 +1372,4 @@ object IMain {
def stripImpl(str: String): String = naming.unmangle(str)
}
}
+
diff --git a/src/repl/scala/tools/nsc/interpreter/Imports.scala b/src/repl/scala/tools/nsc/interpreter/Imports.scala
index 3ec77e46f1..5742c1d0d8 100644
--- a/src/repl/scala/tools/nsc/interpreter/Imports.scala
+++ b/src/repl/scala/tools/nsc/interpreter/Imports.scala
@@ -70,7 +70,10 @@ trait Imports {
/** Compute imports that allow definitions from previous
* requests to be visible in a new request. Returns
- * three pieces of related code:
+ * three or four pieces of related code:
+ *
+ * 0. Header code fragment that should go at the beginning
+ * of the compilation unit, specifically, import Predef.
*
* 1. An initial code fragment that should go before
* the code of the new request.
@@ -91,30 +94,36 @@ trait Imports {
* (3) It imports multiple same-named implicits, but only the
* last one imported is actually usable.
*/
- case class ComputedImports(prepend: String, append: String, access: String)
- protected def importsCode(wanted: Set[Name], wrapper: Request#Wrapper, definesClass: Boolean): ComputedImports = {
+ case class ComputedImports(header: String, prepend: String, append: String, access: String)
+
+ protected def importsCode(wanted: Set[Name], wrapper: Request#Wrapper, definesClass: Boolean, generousImports: Boolean): ComputedImports = {
+ val header, code, trailingBraces, accessPath = new StringBuilder
+ val currentImps = mutable.HashSet[Name]()
+ var predefEscapes = false // only emit predef import header if name not resolved in history, loosely
+
/** Narrow down the list of requests from which imports
* should be taken. Removes requests which cannot contribute
* useful imports for the specified set of wanted names.
*/
- case class ReqAndHandler(req: Request, handler: MemberHandler) { }
+ case class ReqAndHandler(req: Request, handler: MemberHandler)
def reqsToUse: List[ReqAndHandler] = {
/** Loop through a list of MemberHandlers and select which ones to keep.
- * 'wanted' is the set of names that need to be imported.
+ * 'wanted' is the set of names that need to be imported.
*/
def select(reqs: List[ReqAndHandler], wanted: Set[Name]): List[ReqAndHandler] = {
// Single symbol imports might be implicits! See bug #1752. Rather than
// try to finesse this, we will mimic all imports for now.
def keepHandler(handler: MemberHandler) = handler match {
- /* While defining classes in class based mode - implicits are not needed. */
+ // While defining classes in class based mode - implicits are not needed.
case h: ImportHandler if isClassBased && definesClass => h.importedNames.exists(x => wanted.contains(x))
- case _: ImportHandler => true
- case x => x.definesImplicit || (x.definedNames exists wanted)
+ case _: ImportHandler => true
+ case x if generousImports => x.definesImplicit || (x.definedNames exists (d => wanted.exists(w => d.startsWith(w))))
+ case x => x.definesImplicit || (x.definedNames exists wanted)
}
reqs match {
- case Nil => Nil
+ case Nil => predefEscapes = wanted contains PredefModule.name ; Nil
case rh :: rest if !keepHandler(rh.handler) => select(rest, wanted)
case rh :: rest =>
import rh.handler._
@@ -127,9 +136,6 @@ trait Imports {
select(allReqAndHandlers reverseMap { case (r, h) => ReqAndHandler(r, h) }, wanted).reverse
}
- val code, trailingBraces, accessPath = new StringBuilder
- val currentImps = mutable.HashSet[Name]()
-
// add code for a new object to hold some imports
def addWrapper() {
import nme.{ INTERPRETER_IMPORT_WRAPPER => iw }
@@ -146,6 +152,9 @@ trait Imports {
try op finally addWrapper()
}
+ // imports from Predef are relocated to the template header to allow hiding.
+ def checkHeader(h: ImportHandler) = h.referencedNames contains PredefModule.name
+
// loop through previous requests, adding imports for each one
wrapBeforeAndAfter {
// Reusing a single temporary value when import from a line with multiple definitions.
@@ -153,6 +162,9 @@ trait Imports {
for (ReqAndHandler(req, handler) <- reqsToUse) {
val objName = req.lineRep.readPathInstance
handler match {
+ case h: ImportHandler if checkHeader(h) =>
+ header.clear()
+ header append f"${h.member}%n"
// If the user entered an import, then just use it; add an import wrapping
// level if the import might conflict with some other import
case x: ImportHandler if x.importsWildcard =>
@@ -194,7 +206,8 @@ trait Imports {
}
}
- ComputedImports(code.toString, trailingBraces.toString, accessPath.toString)
+ val computedHeader = if (predefEscapes) header.toString else ""
+ ComputedImports(computedHeader, code.toString, trailingBraces.toString, accessPath.toString)
}
private def allReqAndHandlers =
diff --git a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
index d878988e26..e9b0234a4f 100644
--- a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -9,6 +9,7 @@ package interpreter
import Completion._
import scala.collection.mutable.ListBuffer
import scala.reflect.internal.util.StringOps.longestCommonPrefix
+import scala.tools.nsc.interactive.Global
// REPL completor - queries supplied interpreter for valid
// completions based on current contents of buffer.
@@ -296,7 +297,6 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
override def complete(buf: String, cursor: Int): Candidates = {
verbosity = if (isConsecutiveTabs(buf, cursor)) verbosity + 1 else 0
repldbg(f"%ncomplete($buf, $cursor%d) last = ($lastBuf, $lastCursor%d), verbosity: $verbosity")
-
// we don't try lower priority completions unless higher ones return no results.
def tryCompletion(p: Parsed, completionFunction: Parsed => List[String]): Option[Candidates] = {
val winners = completionFunction(p)
diff --git a/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
index bcba7b6dfd..4e45f6d615 100644
--- a/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -35,7 +35,16 @@ trait MemberHandlers {
// XXX this is obviously inadequate but it's going to require some effort
// to get right.
if (name.toString startsWith "x$") ()
- else importVars += name
+ else {
+ importVars += name
+ // Needed to import `xxx` during line 2 of:
+ // scala> val xxx = ""
+ // scala> def foo: x<TAB>
+ if (name.endsWith(IMain.DummyCursorFragment)) {
+ val stripped = name.stripSuffix(IMain.DummyCursorFragment)
+ importVars += stripped
+ }
+ }
case _ => super.traverse(ast)
}
}
diff --git a/src/repl/scala/tools/nsc/interpreter/Pasted.scala b/src/repl/scala/tools/nsc/interpreter/Pasted.scala
index f8d8c2ddb1..3a7eda1b77 100644
--- a/src/repl/scala/tools/nsc/interpreter/Pasted.scala
+++ b/src/repl/scala/tools/nsc/interpreter/Pasted.scala
@@ -15,19 +15,23 @@ package interpreter
* a transcript should itself be pasteable and should achieve
* the same result.
*/
-abstract class Pasted {
- def interpret(line: String): Unit
- def ContinueString: String
- def PromptString: String
- def AltPromptString: String = "scala> "
+abstract class Pasted(prompt: String) {
+ def interpret(line: String): IR.Result
+ def echo(message: String): Unit
- /* `testBoth` cannot be a val, as `Pasted` is inherited by `object paste` in ILoop,
- which would cause `val testBoth` to be initialized before `val PromptString` was.
+ val PromptString = prompt.lines.toList.last
+ val AltPromptString = "scala> "
+ val ContinuePrompt = replProps.continuePrompt
+ val ContinueString = replProps.continueText // " | "
+ val anyPrompt = {
+ import scala.util.matching.Regex.quote
+ s"""\\s*(?:${quote(PromptString.trim)}|${quote(AltPromptString.trim)})\\s*""".r
+ }
+
+ def isPrompted(line: String) = matchesPrompt(line)
+ def isPromptOnly(line: String) = line match { case anyPrompt() => true ; case _ => false }
- object paste extends Pasted {
- val PromptString = prompt.lines.toList.last
- */
- private def testBoth = PromptString != AltPromptString
+ private val testBoth = PromptString != AltPromptString
private val spacey = " \t".toSet
def matchesPrompt(line: String) = matchesString(line, PromptString) || testBoth && matchesString(line, AltPromptString)
@@ -91,13 +95,26 @@ abstract class Pasted {
case _ => code
}
- def run(): Unit = {
- println("// Replaying %d commands from transcript.\n" format cmds.size)
- cmds foreach { cmd =>
- print(ActualPromptString)
- interpret(cmd)
- }
+ def interpreted(line: String) = {
+ echo(line.trim)
+ val res = interpret(line)
+ if (res != IR.Incomplete) echo("")
+ res
+ }
+ def incompletely(cmd: String) = {
+ print(ActualPromptString)
+ interpreted(cmd) == IR.Incomplete
}
+ def run(): Option[String] = {
+ echo(s"// Replaying ${cmds.size} commands from transcript.\n")
+ cmds find incompletely
+ }
+ }
+
+ // Run transcript and return incomplete line if any.
+ def transcript(lines: TraversableOnce[String]): Option[String] = {
+ echo("\n// Detected repl transcript. Paste more, or ctrl-D to finish.\n")
+ apply(lines)
}
/** Commands start on lines beginning with "scala>" and each successive
@@ -105,9 +122,10 @@ abstract class Pasted {
* Everything else is discarded. When the end of the transcript is spotted,
* all the commands are replayed.
*/
- def apply(lines: TraversableOnce[String]) = {
+ def apply(lines: TraversableOnce[String]): Option[String] = {
isRunning = true
- try new PasteAnalyzer(lines.toList) run()
+ try new PasteAnalyzer(lines.toList).run()
finally isRunning = false
}
+ def unapply(line: String): Boolean = isPrompted(line)
}
diff --git a/src/repl/scala/tools/nsc/interpreter/Power.scala b/src/repl/scala/tools/nsc/interpreter/Power.scala
index 8d8140b638..a14a60d216 100644
--- a/src/repl/scala/tools/nsc/interpreter/Power.scala
+++ b/src/repl/scala/tools/nsc/interpreter/Power.scala
@@ -113,10 +113,13 @@ class Power[ReplValsImpl <: ReplVals : ru.TypeTag: ClassTag](val intp: IMain, re
}
}
- private def customBanner = replProps.powerBanner.option flatMap (f => io.File(f).safeSlurp())
+ private def customBanner = replProps.powerBanner.option flatMap {
+ case f if f.getName == "classic" => Some(classic)
+ case f => io.File(f).safeSlurp()
+ }
private def customInit = replProps.powerInitCode.option flatMap (f => io.File(f).safeSlurp())
- def banner = customBanner getOrElse """
+ def classic = """
|** Power User mode enabled - BEEP WHIR GYVE **
|** :phase has been set to 'typer'. **
|** scala.tools.nsc._ has been imported **
@@ -124,28 +127,30 @@ class Power[ReplValsImpl <: ReplVals : ru.TypeTag: ClassTag](val intp: IMain, re
|** Try :help, :vals, power.<tab> **
""".stripMargin.trim
- private def initImports = List(
- "scala.tools.nsc._",
- "scala.collection.JavaConverters._",
- "intp.global.{ error => _, _ }",
- "definitions.{ getClass => _, _ }",
- "power.rutil._",
- "replImplicits._",
- "treedsl.CODE._"
- )
-
- def init = customInit match {
- case Some(x) => x
- case _ => initImports.mkString("import ", ", ", "")
- }
+ def banner = customBanner getOrElse """
+ |Power mode enabled. :phase is at typer.
+ |import scala.tools.nsc._, intp.global._, definitions._
+ |Try :help or completions for vals._ and power._
+ """.stripMargin.trim
+
+ private def initImports =
+ """scala.tools.nsc._
+ |scala.collection.JavaConverters._
+ |intp.global.{ error => _, _ }
+ |definitions.{ getClass => _, _ }
+ |power.rutil._
+ |replImplicits._
+ |treedsl.CODE._""".stripMargin.lines
+
+ def init = customInit getOrElse initImports.mkString("import ", ", ", "")
- /** Starts up power mode and runs whatever is in init.
+ /** Quietly starts up power mode and runs whatever is in init.
*/
def unleash(): Unit = beQuietDuring {
// First we create the ReplVals instance and bind it to $r
intp.bind("$r", replVals)
// Then we import everything from $r.
- intp interpret ("import " + intp.originalPath("$r") + "._")
+ intp interpret s"import ${ intp.originalPath("$r") }._"
// And whatever else there is to do.
init.lines foreach (intp interpret _)
}
diff --git a/src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala b/src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala
new file mode 100644
index 0000000000..3a2177a4cb
--- /dev/null
+++ b/src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala
@@ -0,0 +1,110 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2015 LAMP/EPFL
+ * @author Martin Odersky
+ */
+package scala.tools.nsc.interpreter
+
+import scala.reflect.internal.util.RangePosition
+import scala.tools.nsc.backend.JavaPlatform
+import scala.tools.nsc.{interactive, Settings}
+import scala.tools.nsc.io._
+import scala.tools.nsc.reporters.StoreReporter
+import scala.tools.nsc.util.ClassPath.DefaultJavaContext
+import scala.tools.nsc.util.{DirectoryClassPath, MergedClassPath}
+
+trait PresentationCompilation {
+ self: IMain =>
+
+ /** Typecheck a line of REPL input, suitably wrapped with "interpreter wrapper" objects/classes, with the
+ * presentation compiler. The result of this method gives access to the typechecked tree and to autocompletion
+ * suggestions.
+ *
+ * The caller is responsible for calling [[PresentationCompileResult#cleanup]] to dispose of the compiler instance.
+ */
+ private[scala] def presentationCompile(line: String): Either[IR.Result, PresentationCompileResult] = {
+ if (global == null) Left(IR.Error)
+ else {
+ // special case for:
+ //
+ // scala> 1
+ // scala> .toInt
+ //
+ // and for multi-line input.
+ val line1 = partialInput + (if (Completion.looksLikeInvocation(line)) { self.mostRecentVar + line } else line)
+ val compiler = newPresentationCompiler()
+ val trees = compiler.newUnitParser(line1).parseStats()
+ val importer = global.mkImporter(compiler)
+ val request = new Request(line1, trees map (t => importer.importTree(t)), generousImports = true)
+ val wrappedCode: String = request.ObjectSourceCode(request.handlers)
+ val unit = compiler.newCompilationUnit(wrappedCode)
+ import compiler._
+ val richUnit = new RichCompilationUnit(unit.source)
+ unitOfFile(richUnit.source.file) = richUnit
+ enteringTyper(typeCheck(richUnit))
+ val result = PresentationCompileResult(compiler)(richUnit, request.ObjectSourceCode.preambleLength + line1.length - line.length)
+ Right(result)
+ }
+ }
+
+ /** Create an instance of the presentation compiler with a classpath comprising the REPL's configured classpath
+ * and the classes output by previously compiled REPL lines.
+ *
+ * You may directly interact with this compiler from any thread, although you must not access it concurrently
+ * from multiple threads.
+ *
+ * You may downcast the `reporter` to `StoreReporter` to access type errors.
+ */
+ def newPresentationCompiler(): interactive.Global = {
+ val replOutClasspath: DirectoryClassPath = new DirectoryClassPath(replOutput.dir, DefaultJavaContext)
+ val mergedClasspath = new MergedClassPath[AbstractFile](replOutClasspath :: global.platform.classPath :: Nil, DefaultJavaContext)
+ def copySettings: Settings = {
+ val s = new Settings(_ => () /* ignores "bad option -nc" errors, etc */)
+ s.processArguments(global.settings.recreateArgs, processAll = false)
+ s.YpresentationAnyThread.value = true
+ s
+ }
+ val storeReporter: StoreReporter = new StoreReporter
+ val interactiveGlobal = new interactive.Global(copySettings, storeReporter) { self =>
+ override lazy val platform: ThisPlatform = new JavaPlatform {
+ val global: self.type = self
+
+ override def classPath: PlatformClassPath = mergedClasspath
+ }
+ }
+ new interactiveGlobal.TyperRun()
+ interactiveGlobal
+ }
+
+ abstract class PresentationCompileResult {
+ val compiler: scala.tools.nsc.interactive.Global
+ def unit: compiler.RichCompilationUnit
+ /** The length of synthetic code the precedes the user writtn code */
+ def preambleLength: Int
+ def cleanup(): Unit = {
+ compiler.askShutdown()
+ }
+ import compiler.CompletionResult
+
+ def completionsAt(cursor: Int): CompletionResult = {
+ val pos = unit.source.position(preambleLength + cursor)
+ compiler.completionsAt(pos)
+ }
+ def typedTreeAt(code: String, selectionStart: Int, selectionEnd: Int): compiler.Tree = {
+ val start = selectionStart + preambleLength
+ val end = selectionEnd + preambleLength
+ val pos = new RangePosition(unit.source, start, start, end)
+ compiler.typedTreeAt(pos)
+ }
+ }
+
+ object PresentationCompileResult {
+ def apply(compiler0: interactive.Global)(unit0: compiler0.RichCompilationUnit, preambleLength0: Int) = new PresentationCompileResult {
+
+ override val compiler = compiler0
+
+ override def unit = unit0.asInstanceOf[compiler.RichCompilationUnit]
+
+ override def preambleLength = preambleLength0
+ }
+ }
+}
diff --git a/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala b/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala
new file mode 100644
index 0000000000..4b0330aaf7
--- /dev/null
+++ b/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala
@@ -0,0 +1,139 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2013 LAMP/EPFL
+ * @author Martin Odersky
+ */
+package scala.tools.nsc.interpreter
+
+import scala.reflect.internal.Flags
+import scala.reflect.internal.util.StringOps
+import scala.tools.nsc.interpreter.Completion.{ScalaCompleter, Candidates}
+import scala.util.control.NonFatal
+
+class PresentationCompilerCompleter(intp: IMain) extends Completion with ScalaCompleter {
+ import PresentationCompilerCompleter._
+ import intp.{PresentationCompileResult => Result}
+
+ private type Handler = Result => Candidates
+
+ private var lastRequest = NoRequest
+ private var tabCount = 0
+ private var lastCommonPrefixCompletion: Option[String] = None
+
+ def resetVerbosity(): Unit = { tabCount = 0 ; lastRequest = NoRequest }
+ def completer(): ScalaCompleter = this
+
+ // A convenience for testing
+ def complete(before: String, after: String = ""): Candidates = complete(before + after, before.length)
+ override def complete(buf: String, cursor: Int): Candidates = {
+ val request = Request(buf, cursor)
+ if (request == lastRequest)
+ tabCount += 1
+ else {
+ tabCount = 0
+ lastRequest = request
+ }
+
+ // secret handshakes
+ val slashPrint = """.*// *print *""".r
+ val slashTypeAt = """.*// *typeAt *(\d+) *(\d+) *""".r
+ val Cursor = IMain.DummyCursorFragment + " "
+
+ def print(result: Result) = {
+ val offset = result.preambleLength
+ val pos1 = result.unit.source.position(offset).withEnd(offset + buf.length)
+ import result.compiler._
+ val tree = new Locator(pos1) locateIn result.unit.body match {
+ case Template(_, _, constructor :: (rest :+ last)) => if (rest.isEmpty) last else Block(rest, last)
+ case t => t
+ }
+ val printed = showCode(tree) + " // : " + tree.tpe.safeToString
+ Candidates(cursor, "" :: printed :: Nil)
+ }
+ def typeAt(result: Result, start: Int, end: Int) = {
+ val tpString = result.compiler.exitingTyper(result.typedTreeAt(buf, start, end).tpe.toString)
+ Candidates(cursor, "" :: tpString :: Nil)
+ }
+ def candidates(result: Result): Candidates = {
+ import result.compiler._
+ import CompletionResult._
+ def defStringCandidates(matching: List[Member], name: Name): Candidates = {
+ val defStrings = for {
+ member <- matching
+ if member.symNameDropLocal == name
+ sym <- member.sym.alternatives
+ sugared = sym.sugaredSymbolOrSelf
+ } yield {
+ val tp = member.prefix memberType sym
+ sugared.defStringSeenAs(tp)
+ }
+ Candidates(cursor, "" :: defStrings.distinct)
+ }
+ val found = result.completionsAt(cursor) match {
+ case NoResults => Completion.NoCandidates
+ case r =>
+ def shouldHide(m: Member): Boolean = {
+ val isUniversal = definitions.isUniversalMember(m.sym)
+ def viaUniversalExtensionMethod = m match {
+ case t: TypeMember if t.implicitlyAdded && t.viaView.info.params.head.info.bounds.isEmptyBounds => true
+ case _ => false
+ }
+ (
+ isUniversal && nme.isReplWrapperName(m.prefix.typeSymbol.name)
+ || isUniversal && tabCount == 0 && r.name.isEmpty
+ || viaUniversalExtensionMethod && tabCount == 0 && r.name.isEmpty
+ )
+ }
+
+ val matching = r.matchingResults().filterNot(shouldHide)
+ val tabAfterCommonPrefixCompletion = lastCommonPrefixCompletion.contains(buf.substring(0, cursor)) && matching.exists(_.symNameDropLocal == r.name)
+ val doubleTab = tabCount > 0 && matching.forall(_.symNameDropLocal == r.name)
+ if (tabAfterCommonPrefixCompletion || doubleTab) defStringCandidates(matching, r.name)
+ else if (matching.isEmpty) {
+ // Lenient matching based on camel case and on eliding JavaBean "get" / "is" boilerplate
+ val camelMatches: List[Member] = r.matchingResults(CompletionResult.camelMatch(_)).filterNot(shouldHide)
+ val memberCompletions = camelMatches.map(_.symNameDropLocal.decoded).distinct.sorted
+ def allowCompletion = (
+ (memberCompletions.size == 1)
+ || CompletionResult.camelMatch(r.name)(r.name.newName(StringOps.longestCommonPrefix(memberCompletions)))
+ )
+ if (memberCompletions.isEmpty) Completion.NoCandidates
+ else if (allowCompletion) Candidates(cursor - r.positionDelta, memberCompletions)
+ else Candidates(cursor, "" :: memberCompletions)
+ } else if (matching.nonEmpty && matching.forall(_.symNameDropLocal == r.name))
+ Completion.NoCandidates // don't offer completion if the only option has been fully typed already
+ else {
+ // regular completion
+ val memberCompletions: List[String] = matching.map(_.symNameDropLocal.decoded).distinct.sorted
+ Candidates(cursor - r.positionDelta, memberCompletions)
+ }
+ }
+ lastCommonPrefixCompletion =
+ if (found != Completion.NoCandidates && buf.length >= found.cursor)
+ Some(buf.substring(0, found.cursor) + StringOps.longestCommonPrefix(found.candidates))
+ else
+ None
+ found
+ }
+ val buf1 = buf.patch(cursor, Cursor, 0)
+ try {
+ intp.presentationCompile(buf1) match {
+ case Left(_) => Completion.NoCandidates
+ case Right(result) => try {
+ buf match {
+ case slashPrint() if cursor == buf.length => print(result)
+ case slashTypeAt(start, end) if cursor == buf.length => typeAt(result, start.toInt, end.toInt)
+ case _ => candidates(result)
+ }
+ } finally result.cleanup()
+ }
+ } catch {
+ case NonFatal(e) =>
+ if (isReplDebug) e.printStackTrace()
+ Completion.NoCandidates
+ }
+ }
+}
+object PresentationCompilerCompleter {
+ private case class Request(line: String, cursor: Int)
+ private val NoRequest = Request("", -1)
+}
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
index fb4ed34571..fb4ed34571 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala b/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala
index 3d80f9da52..3d80f9da52 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala
index 839598a15f..839598a15f 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala
index ac5fec80b3..ac5fec80b3 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala
index f257153bd7..f257153bd7 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala
index 84ee82f994..84ee82f994 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
index 81036b4908..6b13a02c54 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
@@ -280,7 +280,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
{
if (Set("epfl", "EPFL").contains(tpl.universe.settings.docfooter.value))
- <div id="footer">Scala programming documentation. Copyright (c) 2003-2013 <a href="http://www.epfl.ch" target="_top">EPFL</a>, with contributions from <a href="http://typesafe.com" target="_top">Typesafe</a>.</div>
+ <div id="footer">Scala programming documentation. Copyright (c) 2003-2015 <a href="http://www.epfl.ch" target="_top">EPFL</a>, with contributions from <a href="http://typesafe.com" target="_top">Typesafe</a>.</div>
else
<div id="footer"> { tpl.universe.settings.docfooter.value } </div>
}
@@ -676,7 +676,6 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
if (diagramSvg != NodeSeq.Empty) {
<div class="toggleContainer block diagram-container" id={ id + "-container"}>
<span class="toggle diagram-link">{ description }</span>
- <a href="http://docs.scala-lang.org/overviews/scaladoc/usage.html#diagrams" target="_blank" class="diagram-help">Learn more about scaladoc diagrams</a>
<div class="diagram" id={ id }>{
diagramSvg
}</div>
@@ -782,7 +781,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
if (isReduced) NodeSeq.Empty else {
def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = {
def param0(vl: ValueParam): NodeSeq =
- // notice the }{ in the next lines, they are necessary to avoid an undesired withspace in output
+ // notice the }{ in the next lines, they are necessary to avoid an undesired whitespace in output
<span name={ vl.name }>{
Text(vl.name)
}{ Text(": ") ++ typeToHtml(vl.resultType, hasLinks) }{
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala
index 4bed106f43..9381cf3a35 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala
@@ -145,7 +145,7 @@ class DotProcess(settings: doc.Settings) {
// we shouldn't just sit there for 50s not reporting anything, no?
settings.printMsg("Graphviz dot encountered an error when generating the diagram for:")
settings.printMsg(templateName)
- settings.printMsg("These are usually spurious errors, but if you notice a persistant error on")
+ settings.printMsg("These are usually spurious errors, but if you notice a persistent error on")
settings.printMsg("a diagram, please use the " + settings.docDiagramsDebug.name + " flag and report a bug with the output.")
}
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
index 3d9cf8d465..cf81f7fdf5 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
@@ -412,7 +412,17 @@ function textFilter() {
var query = $("#textfilter input").attr("value") || '';
var queryRegExp = compilePattern(query);
- if ((typeof textFilter.lastQuery === "undefined") || (textFilter.lastQuery !== query)) {
+ // if we are filtering on types, then we have to display types
+ // ("display packages only" is not possible when filtering)
+ if (query !== "") {
+ kindFilter("all");
+ }
+
+ // Three things trigger a reload of the left pane list:
+ // typeof textFilter.lastQuery === "undefined" <-- first load, there is nothing yet in the left pane
+ // textFilter.lastQuery !== query <-- the filter text has changed
+ // focusFilterState != null <-- a package has been "focused"
+ if ((typeof textFilter.lastQuery === "undefined") || (textFilter.lastQuery !== query) || (focusFilterState != null)) {
textFilter.lastQuery = query;
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js
index faab0cf1a3..faab0cf1a3 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css
index 7d64b9c5c5..7d64b9c5c5 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala
index fe157c1cc9..66ce2137f2 100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala
@@ -31,7 +31,7 @@ trait CommentFactory extends base.CommentFactoryBase {
defineComment(sym, linkTarget, inTpl)
})
- /** A comment is usualy created by the parser, however for some special
+ /** A comment is usually created by the parser, however for some special
* cases we have to give some `inTpl` comments (parent class for example)
* to the comment of the symbol.
* This function manages some of those cases : Param accessor and Primary constructor */
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala
index ad53dc6bfa..ad53dc6bfa 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala
index 86a7a67160..86a7a67160 100755..100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala
index 1846f375cd..e15963bda9 100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala
@@ -99,7 +99,7 @@ case class NormalNode(tpe: TypeEntity, tpl: Option[TemplateEntity])(val tooltip:
/** A class or trait the thisnode can be converted to by an implicit conversion
* TODO: I think it makes more sense to use the tpe links to templates instead of the TemplateEntity for implicit nodes
- * since some implicit conversions convert the class to complex types that cannot be represented as a single tmeplate
+ * since some implicit conversions convert the class to complex types that cannot be represented as a single template
*/
case class ImplicitNode(tpe: TypeEntity, tpl: Option[TemplateEntity])(val tooltip: Option[String] = None) extends Node { override def isImplicitNode = true }
diff --git a/src/scalap/decoder.properties b/src/scalap/decoder.properties
index 961c60f48c..333f6ce715 100644
--- a/src/scalap/decoder.properties
+++ b/src/scalap/decoder.properties
@@ -1,2 +1,2 @@
version.number=2.0.1
-copyright.string=(c) 2002-2013 LAMP/EPFL
+copyright.string=(c) 2002-2015 LAMP/EPFL
diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
index cfd750055b..eed76c3774 100644
--- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
@@ -114,6 +114,9 @@ object ClassFileParser extends ByteCodeReader {
val methodRef = memberRef("Method")
val interfaceMethodRef = memberRef("InterfaceMethod")
val nameAndType = u2 ~ u2 ^^ add1 { case name ~ descriptor => pool => "NameAndType: " + pool(name) + ", " + pool(descriptor) }
+ val methodHandle = u1 ~ u2 ^^ add1 { case referenceKind ~ referenceIndex => pool => "MethodHandle: " + referenceKind + ", " + pool(referenceIndex) }
+ val methodType = u2 ^^ add1 { case descriptorIndex => pool => "MethodType: " + pool(descriptorIndex) }
+ val invokeDynamic = u2 ~ u2 ^^ add1 { case bootstrapMethodAttrIndex ~ nameAndTypeIndex => pool => "InvokeDynamic: " + "bootstrapMethodAttrIndex = " + bootstrapMethodAttrIndex + ", " + pool(nameAndTypeIndex) }
val constantPoolEntry = u1 >> {
case 1 => utf8String
@@ -127,6 +130,9 @@ object ClassFileParser extends ByteCodeReader {
case 10 => methodRef
case 11 => interfaceMethodRef
case 12 => nameAndType
+ case 15 => methodHandle
+ case 16 => methodType
+ case 18 => invokeDynamic
}
val interfaces = u2 >> u2.times
diff --git a/test/disabled/pos/t1545.scala b/test/disabled/pos/t1545.scala
index 4c5908b8a1..4c5908b8a1 100755..100644
--- a/test/disabled/pos/t1545.scala
+++ b/test/disabled/pos/t1545.scala
diff --git a/test/files/bench/equality/eq.scala b/test/files/bench/equality/eq.scala
index 8ac5b5ef5c..8ac5b5ef5c 100755..100644
--- a/test/files/bench/equality/eq.scala
+++ b/test/files/bench/equality/eq.scala
diff --git a/test/files/bench/equality/eqeq.scala b/test/files/bench/equality/eqeq.scala
index afccece88a..afccece88a 100755..100644
--- a/test/files/bench/equality/eqeq.scala
+++ b/test/files/bench/equality/eqeq.scala
diff --git a/test/files/filters b/test/files/filters
index 51a7507848..e91ca0eb36 100644
--- a/test/files/filters
+++ b/test/files/filters
@@ -1,6 +1,7 @@
#
#Java HotSpot(TM) 64-Bit Server VM warning: Failed to reserve shared memory (errno = 28).
Java HotSpot\(TM\) .* warning:
+OpenJDK .* warning:
# Hotspot receiving VM options through the $_JAVA_OPTIONS
# env variable outputs them on stderr
Picked up _JAVA_OPTIONS:
diff --git a/test/files/jvm/innerClassAttribute/Test.scala b/test/files/jvm/innerClassAttribute/Test.scala
index 376b3c895b..3a6737ca46 100644
--- a/test/files/jvm/innerClassAttribute/Test.scala
+++ b/test/files/jvm/innerClassAttribute/Test.scala
@@ -149,9 +149,7 @@ object Test extends BytecodeTest {
def testA11() = {
val List(ann) = innerClassNodes("A11")
- // in the java class file, the INNERCLASS attribute has more flags (public | static | abstract | interface | annotation)
- // the scala compiler has its own interpretation of java annotations ant their flags.. it only emits publicStatic.
- assertMember(ann, "JavaAnnot_1", "Ann", flags = publicStatic)
+ assertMember(ann, "JavaAnnot_1", "Ann", flags = publicAbstractInterface | Flags.ACC_STATIC | Flags.ACC_ANNOTATION)
}
def testA13() = {
diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check
index 08372685d6..ce3c8062d7 100644
--- a/test/files/jvm/interpreter.check
+++ b/test/files/jvm/interpreter.check
@@ -30,7 +30,7 @@ scala> val four: anotherint = 4
four: anotherint = 4
scala> val bogus: anotherint = "hello"
-<console>:11: error: type mismatch;
+<console>:12: error: type mismatch;
found : String("hello")
required: anotherint
(which expands to) Int
@@ -353,7 +353,7 @@ defined class Term
scala> def f(e: Exp) = e match { // non-exhaustive warning here
case _:Fact => 3
}
-<console>:21: warning: match may not be exhaustive.
+<console>:22: warning: match may not be exhaustive.
It would fail on the following inputs: Exp(), Term()
def f(e: Exp) = e match { // non-exhaustive warning here
^
@@ -363,6 +363,6 @@ scala> :quit
plusOne: (x: Int)Int
res0: Int = 6
res0: String = after reset
-<console>:11: error: not found: value plusOne
+<console>:12: error: not found: value plusOne
plusOne(5) // should be undefined now
^
diff --git a/test/files/jvm/throws-annot-from-java.check b/test/files/jvm/throws-annot-from-java.check
index ace264a4f5..bf639260e7 100644
--- a/test/files/jvm/throws-annot-from-java.check
+++ b/test/files/jvm/throws-annot-from-java.check
@@ -1,10 +1,8 @@
scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
+Power mode enabled. :phase is at typer.
+import scala.tools.nsc._, intp.global._, definitions._
+Try :help or completions for vals._ and power._
scala> :paste
// Entering paste mode (ctrl-D to finish)
diff --git a/test/files/neg/name-lookup-stable.check b/test/files/neg/name-lookup-stable.check
index 751df9505e..68d98c4162 100644
--- a/test/files/neg/name-lookup-stable.check
+++ b/test/files/neg/name-lookup-stable.check
@@ -6,6 +6,6 @@ import ColumnOption._
name-lookup-stable.scala:17: error: reference to PrimaryKey is ambiguous;
it is both defined in class A and imported subsequently by
import ColumnOption._
- PrimaryKey // was already ambigious in 2.10.3
+ PrimaryKey // was already ambiguous in 2.10.3
^
two errors found
diff --git a/test/files/neg/name-lookup-stable.scala b/test/files/neg/name-lookup-stable.scala
index 0d862f06e1..2941e05875 100644
--- a/test/files/neg/name-lookup-stable.scala
+++ b/test/files/neg/name-lookup-stable.scala
@@ -14,7 +14,7 @@ class A {
(null: Any) match { case PrimaryKey => }
- PrimaryKey // was already ambigious in 2.10.3
+ PrimaryKey // was already ambiguous in 2.10.3
}
}
diff --git a/test/files/neg/override.scala b/test/files/neg/override.scala
index 7975516061..7975516061 100755..100644
--- a/test/files/neg/override.scala
+++ b/test/files/neg/override.scala
diff --git a/test/files/neg/t2336.scala b/test/files/neg/t2336.scala
index 4cea02b721..4cea02b721 100755..100644
--- a/test/files/neg/t2336.scala
+++ b/test/files/neg/t2336.scala
diff --git a/test/files/neg/t2494.scala b/test/files/neg/t2494.scala
index 71e6bc4bbf..71e6bc4bbf 100755..100644
--- a/test/files/neg/t2494.scala
+++ b/test/files/neg/t2494.scala
diff --git a/test/files/neg/t2773.scala b/test/files/neg/t2773.scala
index aaa6351c83..aaa6351c83 100755..100644
--- a/test/files/neg/t2773.scala
+++ b/test/files/neg/t2773.scala
diff --git a/test/files/neg/t2779.scala b/test/files/neg/t2779.scala
index d025055aa0..d025055aa0 100755..100644
--- a/test/files/neg/t2779.scala
+++ b/test/files/neg/t2779.scala
diff --git a/test/files/neg/t2870.scala b/test/files/neg/t2870.scala
index 4de19242e3..4de19242e3 100755..100644
--- a/test/files/neg/t2870.scala
+++ b/test/files/neg/t2870.scala
diff --git a/test/files/neg/t2918.scala b/test/files/neg/t2918.scala
index ff2be39ae0..ff2be39ae0 100755..100644
--- a/test/files/neg/t2918.scala
+++ b/test/files/neg/t2918.scala
diff --git a/test/files/neg/t3006.scala b/test/files/neg/t3006.scala
index a84b69c842..a84b69c842 100755..100644
--- a/test/files/neg/t3006.scala
+++ b/test/files/neg/t3006.scala
diff --git a/test/files/neg/t3224.scala b/test/files/neg/t3224.scala
index b7af8a67b5..b7af8a67b5 100755..100644
--- a/test/files/neg/t3224.scala
+++ b/test/files/neg/t3224.scala
diff --git a/test/files/neg/t4425b.check b/test/files/neg/t4425b.check
index 8418b4fd12..a204467586 100644
--- a/test/files/neg/t4425b.check
+++ b/test/files/neg/t4425b.check
@@ -22,16 +22,28 @@ t4425b.scala:10: error: object X is not a case class, nor does it have an unappl
Note: def unapply(x: String)(y: String): Nothing exists in object X, but it cannot be used as an extractor due to its second non-implicit parameter list
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:18: error: too many patterns for object X: expected 1, found 2
+t4425b.scala:18: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
+ println( "" match { case _ X _ => "ok" ; case _ => "fail" })
+ ^
+t4425b.scala:18: error: too many patterns for object X offering Boolean: expected 0, found 2
println( "" match { case _ X _ => "ok" ; case _ => "fail" })
^
-t4425b.scala:19: error: too many patterns for object X: expected 1, found 2
+t4425b.scala:19: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
+ println((X: Any) match { case _ X _ => "ok" ; case _ => "fail" })
+ ^
+t4425b.scala:19: error: too many patterns for object X offering Boolean: expected 0, found 2
println((X: Any) match { case _ X _ => "ok" ; case _ => "fail" })
^
-t4425b.scala:22: error: too many patterns for object X: expected 1, found 2
+t4425b.scala:20: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
+ println( "" match { case X(_) => "ok" ; case _ => "fail" })
+ ^
+t4425b.scala:21: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
+ println((X: Any) match { case X(_) => "ok" ; case _ => "fail" })
+ ^
+t4425b.scala:22: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
println( "" match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:23: error: too many patterns for object X: expected 1, found 2
+t4425b.scala:23: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
t4425b.scala:31: error: too many patterns for object X offering Nothing: expected 1, found 2
@@ -46,4 +58,4 @@ t4425b.scala:35: error: too many patterns for object X offering Nothing: expecte
t4425b.scala:36: error: too many patterns for object X offering Nothing: expected 1, found 2
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
-14 errors found
+18 errors found
diff --git a/test/files/neg/t5376.scala b/test/files/neg/t5376.scala
index 8da3868566..b1ba41bd54 100644
--- a/test/files/neg/t5376.scala
+++ b/test/files/neg/t5376.scala
@@ -12,7 +12,7 @@ object Test {
"a": Int
}
- // Import one implict and one non-implicit method with the
+ // Import one implicit and one non-implicit method with the
// same name in the same scope.
def m2 = {
import O1._
diff --git a/test/files/neg/t6013/Base.java b/test/files/neg/t6013/Base.java
index b73d7fd821..ce6ee47e64 100644
--- a/test/files/neg/t6013/Base.java
+++ b/test/files/neg/t6013/Base.java
@@ -2,7 +2,7 @@ abstract public class Base {
// This must considered to be overridden by Abstract#foo based
// on the erased signatures. This special case is handled by
// `javaErasedOverridingSym` in `RefChecks`.
- public abstract void bar(java.util.List<java.lang.String> foo) { return; }
+ public void bar(java.util.List<java.lang.String> foo) { return; }
// But, a concrete method in a Java superclass must not excuse
// a deferred method in the Java subclass!
diff --git a/test/files/neg/t6446-additional.check b/test/files/neg/t6446-additional.check
index a87af2f1e5..a87af2f1e5 100755..100644
--- a/test/files/neg/t6446-additional.check
+++ b/test/files/neg/t6446-additional.check
diff --git a/test/files/neg/t6446-list.check b/test/files/neg/t6446-list.check
index fa5c581941..fa5c581941 100755..100644
--- a/test/files/neg/t6446-list.check
+++ b/test/files/neg/t6446-list.check
diff --git a/test/files/neg/t6446-missing.check b/test/files/neg/t6446-missing.check
index 029c8057c3..029c8057c3 100755..100644
--- a/test/files/neg/t6446-missing.check
+++ b/test/files/neg/t6446-missing.check
diff --git a/test/files/neg/t6666d.check b/test/files/neg/t6666d.check
deleted file mode 100644
index b4785f0129..0000000000
--- a/test/files/neg/t6666d.check
+++ /dev/null
@@ -1,4 +0,0 @@
-t6666d.scala:7: error: Implementation restriction: access of object TreeOrd$1 from object TreeOrd$2, would require illegal premature access to the unconstructed `this` of class Test
- implicit object TreeOrd extends Ordering[K](){
- ^
-one error found
diff --git a/test/files/neg/t7214neg.scala b/test/files/neg/t7214neg.scala
index ff1ea8082d..e2b2d908d8 100644
--- a/test/files/neg/t7214neg.scala
+++ b/test/files/neg/t7214neg.scala
@@ -1,4 +1,4 @@
-// pattern matcher crashes here trying to synthesize an uneeded outer test.
+// pattern matcher crashes here trying to synthesize an unneeded outer test.
// no-symbol does not have an owner
// at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49)
// at scala.tools.nsc.Global.abort(Global.scala:253)
diff --git a/test/files/neg/t771.scala b/test/files/neg/t771.scala
index 26bf441648..26bf441648 100755..100644
--- a/test/files/neg/t771.scala
+++ b/test/files/neg/t771.scala
diff --git a/test/files/neg/t8127a.check b/test/files/neg/t8127a.check
new file mode 100644
index 0000000000..5a30574861
--- /dev/null
+++ b/test/files/neg/t8127a.check
@@ -0,0 +1,4 @@
+t8127a.scala:7: error: The result type of an unapplySeq method must contain a member `get` to be used as an extractor pattern, no such member exists in Seq[_$1]
+ case H(v) =>
+ ^
+one error found
diff --git a/test/files/neg/t8127a.scala b/test/files/neg/t8127a.scala
new file mode 100644
index 0000000000..c05facdac1
--- /dev/null
+++ b/test/files/neg/t8127a.scala
@@ -0,0 +1,12 @@
+object H {
+ def unapplySeq(m: Any): Seq[_] = List("")
+}
+
+object Test {
+ def unapply(m: Any) = m match {
+ case H(v) =>
+ case _ =>
+ }
+ // now: too many patterns for object H offering Boolean: expected 0, found 1
+ // was: result type Seq[_$2] of unapplySeq defined in method unapplySeq in object H does not conform to Option[_]
+}
diff --git a/test/files/neg/t8597b.scala b/test/files/neg/t8597b.scala
index b29d591cb1..cbf0bf1c5a 100644
--- a/test/files/neg/t8597b.scala
+++ b/test/files/neg/t8597b.scala
@@ -4,7 +4,7 @@ object Unchecked {
// t is a fresh pattern type variable, despite our attempts to
// backtick our way to the enclosing `t`. Under this interpretation,
- // the absense of an unchecked warning is expected.
+ // the absence of an unchecked warning is expected.
(null: Any) match {
case _: Some[t] => // no warn
}
diff --git a/test/files/neg/t8675b.scala b/test/files/neg/t8675b.scala
index bffed2141c..b2212fa234 100644
--- a/test/files/neg/t8675b.scala
+++ b/test/files/neg/t8675b.scala
@@ -9,7 +9,7 @@ object Test {
}
trait Reportable1[Params, R]
- // "missing paramater type" error was swallowed in 2.11.0 leading to a crash
+ // "missing parameter type" error was swallowed in 2.11.0 leading to a crash
// in the backend.
//
// This error is itself a regression (or at least a change) in 2.11.0-M7,
diff --git a/test/files/neg/t8989.check b/test/files/neg/t8989.check
new file mode 100644
index 0000000000..4e89b862bd
--- /dev/null
+++ b/test/files/neg/t8989.check
@@ -0,0 +1,4 @@
+t8989.scala:11: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in A
+ val f = p match {case d(1) => true; case _ => false}
+ ^
+one error found
diff --git a/test/files/neg/t8989.scala b/test/files/neg/t8989.scala
new file mode 100644
index 0000000000..8ed6a901cd
--- /dev/null
+++ b/test/files/neg/t8989.scala
@@ -0,0 +1,14 @@
+class A extends Product1[Int] {
+ def _1 = 1
+ def isEmpty = false // used by scalac
+ def isDefined = !isEmpty // used by dotty
+ def canEqual(a: Any) = true
+}
+
+object d{
+ def unapply(a: Any) = new A
+ val p: Any = ???
+ val f = p match {case d(1) => true; case _ => false}
+}
+
+
diff --git a/test/files/neg/t9401.check b/test/files/neg/t9401.check
new file mode 100644
index 0000000000..638d56db63
--- /dev/null
+++ b/test/files/neg/t9401.check
@@ -0,0 +1,4 @@
+t9401.scala:3: error: cannot find class tag for element type T
+ gencastarray = new Array[T](0)
+ ^
+one error found
diff --git a/test/files/neg/t9401.scala b/test/files/neg/t9401.scala
new file mode 100644
index 0000000000..f42ecc7f74
--- /dev/null
+++ b/test/files/neg/t9401.scala
@@ -0,0 +1,4 @@
+class Resetting[T] {
+ var gencastarray: Any = null
+ gencastarray = new Array[T](0)
+}
diff --git a/test/files/neg/virtpatmat_exhaust_compound.scala b/test/files/neg/virtpatmat_exhaust_compound.scala
index 386c7af98d..4ff04dd06a 100644
--- a/test/files/neg/virtpatmat_exhaust_compound.scala
+++ b/test/files/neg/virtpatmat_exhaust_compound.scala
@@ -10,7 +10,7 @@ case object O3 extends Base2
case object O4 extends Base with Base2
object Test {
- val a /*: Product with Serialiable with Base */ = if (true) O1 else O2
+ val a /*: Product with Serializable with Base */ = if (true) O1 else O2
a match {
case null =>
}
diff --git a/test/files/pos/lexical.scala b/test/files/pos/lexical.scala
index 8c29513bb5..8c29513bb5 100755..100644
--- a/test/files/pos/lexical.scala
+++ b/test/files/pos/lexical.scala
diff --git a/test/files/pos/packageobjs.scala b/test/files/pos/packageobjs.scala
index ccab133716..ccab133716 100755..100644
--- a/test/files/pos/packageobjs.scala
+++ b/test/files/pos/packageobjs.scala
diff --git a/test/files/pos/spec-t6286.scala b/test/files/pos/spec-t6286.scala
index 4d87998ec6..4d87998ec6 100755..100644
--- a/test/files/pos/spec-t6286.scala
+++ b/test/files/pos/spec-t6286.scala
diff --git a/test/files/pos/t1459/AbstractBase.java b/test/files/pos/t1459/AbstractBase.java
index 492419416c..492419416c 100755..100644
--- a/test/files/pos/t1459/AbstractBase.java
+++ b/test/files/pos/t1459/AbstractBase.java
diff --git a/test/files/pos/t1459/App.scala b/test/files/pos/t1459/App.scala
index 36e5022e94..36e5022e94 100755..100644
--- a/test/files/pos/t1459/App.scala
+++ b/test/files/pos/t1459/App.scala
diff --git a/test/files/pos/t1459/Caller.java b/test/files/pos/t1459/Caller.java
index 4ae51d8c57..4ae51d8c57 100755..100644
--- a/test/files/pos/t1459/Caller.java
+++ b/test/files/pos/t1459/Caller.java
diff --git a/test/files/pos/t1722/Test.scala b/test/files/pos/t1722/Test.scala
index f236d3fdc4..f236d3fdc4 100755..100644
--- a/test/files/pos/t1722/Test.scala
+++ b/test/files/pos/t1722/Test.scala
diff --git a/test/files/pos/t1722/Top.scala b/test/files/pos/t1722/Top.scala
index 4ac52412aa..4ac52412aa 100755..100644
--- a/test/files/pos/t1722/Top.scala
+++ b/test/files/pos/t1722/Top.scala
diff --git a/test/files/pos/t1756.scala b/test/files/pos/t1756.scala
index 1d067c3b04..1d067c3b04 100755..100644
--- a/test/files/pos/t1756.scala
+++ b/test/files/pos/t1756.scala
diff --git a/test/files/pos/t2060.scala b/test/files/pos/t2060.scala
index 2c701150e4..2c701150e4 100755..100644
--- a/test/files/pos/t2060.scala
+++ b/test/files/pos/t2060.scala
diff --git a/test/files/pos/t2082.scala b/test/files/pos/t2082.scala
index 3a160612fe..3a160612fe 100755..100644
--- a/test/files/pos/t2082.scala
+++ b/test/files/pos/t2082.scala
diff --git a/test/files/pos/t2179.scala b/test/files/pos/t2179.scala
index 89e22b6e2a..89e22b6e2a 100755..100644
--- a/test/files/pos/t2179.scala
+++ b/test/files/pos/t2179.scala
diff --git a/test/files/pos/t2405.scala b/test/files/pos/t2405.scala
index 224b2ce83b..0bc7a771b2 100644
--- a/test/files/pos/t2405.scala
+++ b/test/files/pos/t2405.scala
@@ -6,14 +6,14 @@ object Test1 {
implicitly[Int]
}
-// Testing for the absense of shadowing #1.
+// Testing for the absence of shadowing #1.
object Test2 {
import A.{x => y}
val x = 2
implicitly[Int]
}
-// Testing for the absense of shadowing #2.
+// Testing for the absence of shadowing #2.
object Test3 {
{
import A.{x => y}
diff --git a/test/files/pos/t2425.scala b/test/files/pos/t2425.scala
index 477d5467aa..477d5467aa 100755..100644
--- a/test/files/pos/t2425.scala
+++ b/test/files/pos/t2425.scala
diff --git a/test/files/pos/t2429.scala b/test/files/pos/t2429.scala
index 550681b6a2..550681b6a2 100755..100644
--- a/test/files/pos/t2429.scala
+++ b/test/files/pos/t2429.scala
diff --git a/test/files/pos/t2433/A.java b/test/files/pos/t2433/A.java
index 340690c402..340690c402 100755..100644
--- a/test/files/pos/t2433/A.java
+++ b/test/files/pos/t2433/A.java
diff --git a/test/files/pos/t2433/B.java b/test/files/pos/t2433/B.java
index 151dd71ca1..151dd71ca1 100755..100644
--- a/test/files/pos/t2433/B.java
+++ b/test/files/pos/t2433/B.java
diff --git a/test/files/pos/t2433/Test.scala b/test/files/pos/t2433/Test.scala
index 02fd89b646..02fd89b646 100755..100644
--- a/test/files/pos/t2433/Test.scala
+++ b/test/files/pos/t2433/Test.scala
diff --git a/test/files/pos/t2484.scala b/test/files/pos/t2484.scala
index 88da6aaac8..88da6aaac8 100755..100644
--- a/test/files/pos/t2484.scala
+++ b/test/files/pos/t2484.scala
diff --git a/test/files/pos/t2504.scala b/test/files/pos/t2504.scala
index 67f8226852..67f8226852 100755..100644
--- a/test/files/pos/t2504.scala
+++ b/test/files/pos/t2504.scala
diff --git a/test/files/pos/t2545.scala b/test/files/pos/t2545.scala
index 6ad994223c..6ad994223c 100755..100644
--- a/test/files/pos/t2545.scala
+++ b/test/files/pos/t2545.scala
diff --git a/test/files/pos/t2635.scala b/test/files/pos/t2635.scala
index 7cd5531356..7cd5531356 100755..100644
--- a/test/files/pos/t2635.scala
+++ b/test/files/pos/t2635.scala
diff --git a/test/files/pos/t2683.scala b/test/files/pos/t2683.scala
index 4ba34b554a..4ba34b554a 100755..100644
--- a/test/files/pos/t2683.scala
+++ b/test/files/pos/t2683.scala
diff --git a/test/files/pos/t2913.scala b/test/files/pos/t2913.scala
index 11d8b92053..11d8b92053 100755..100644
--- a/test/files/pos/t2913.scala
+++ b/test/files/pos/t2913.scala
diff --git a/test/files/pos/t2956/t2956.scala b/test/files/pos/t2956/t2956.scala
index eb6e817465..eb6e817465 100755..100644
--- a/test/files/pos/t2956/t2956.scala
+++ b/test/files/pos/t2956/t2956.scala
diff --git a/test/files/pos/t3174.scala b/test/files/pos/t3174.scala
index c3d90a4946..c3d90a4946 100755..100644
--- a/test/files/pos/t3174.scala
+++ b/test/files/pos/t3174.scala
diff --git a/test/files/pos/t3174b.scala b/test/files/pos/t3174b.scala
index 4df1bfe837..4df1bfe837 100755..100644
--- a/test/files/pos/t3174b.scala
+++ b/test/files/pos/t3174b.scala
diff --git a/test/files/pos/t3568.scala b/test/files/pos/t3568.scala
index c8e3fcc4be..c8e3fcc4be 100755..100644
--- a/test/files/pos/t3568.scala
+++ b/test/files/pos/t3568.scala
diff --git a/test/files/pos/t4553.scala b/test/files/pos/t4553.scala
index 4eefe57b2b..4eefe57b2b 100755..100644
--- a/test/files/pos/t4553.scala
+++ b/test/files/pos/t4553.scala
diff --git a/test/files/pos/t6089b.scala b/test/files/pos/t6089b.scala
index ff7ca157eb..040987413e 100644
--- a/test/files/pos/t6089b.scala
+++ b/test/files/pos/t6089b.scala
@@ -1,5 +1,5 @@
// this crazy code simply tries to nest pattern matches so that the last call is in a tricky-to-determine
-// tail position (my initial tightenign of tailpos detection for SI-6089 ruled this out)
+// tail position (my initial tightening of tailpos detection for SI-6089 ruled this out)
class BKTree {
@annotation.tailrec
final def -?-[AA](a: AA): Boolean = this match {
diff --git a/test/files/neg/t6666d.scala b/test/files/pos/t6666d.scala
index 49a688f91b..49a688f91b 100644
--- a/test/files/neg/t6666d.scala
+++ b/test/files/pos/t6666d.scala
diff --git a/test/files/pos/t7689.scala b/test/files/pos/t7689.scala
index 022e7ab7a0..72cca99bc0 100644
--- a/test/files/pos/t7689.scala
+++ b/test/files/pos/t7689.scala
@@ -2,6 +2,6 @@ object A {
// The default getter must have an explicit return type (List[_] => Int)
// This wasn't happening since e28c3edda4. That commit encoded upper/lower
// bounds of Any/Nothing as EmptyTree, which were triggering an .isEmpty
- // check in Namers#TypeTreeSubstitutor
+ // check in Namers#TypeTreeSubstituter
def x(f: List[_] => Int = _ => 3) = 9
}
diff --git a/test/files/pos/t8002-nested-scope.scala b/test/files/pos/t8002-nested-scope.scala
index a2088bce7a..8ce809e556 100644
--- a/test/files/pos/t8002-nested-scope.scala
+++ b/test/files/pos/t8002-nested-scope.scala
@@ -1,5 +1,5 @@
// This test serves to capture the status quo, but should really
-// emit an accessibiltiy error.
+// emit an accessibility error.
// `Namers#companionSymbolOf` seems too lenient, and currently doesn't
// implement the same-scope checks mentioned:
diff --git a/test/files/pos/t9369.flags b/test/files/pos/t9369.flags
new file mode 100644
index 0000000000..b5a8748652
--- /dev/null
+++ b/test/files/pos/t9369.flags
@@ -0,0 +1 @@
+-Xfatal-warnings -unchecked
diff --git a/test/files/pos/t9369.scala b/test/files/pos/t9369.scala
new file mode 100644
index 0000000000..94be2ea4e7
--- /dev/null
+++ b/test/files/pos/t9369.scala
@@ -0,0 +1,24 @@
+object Test {
+
+ trait Tree
+
+ sealed abstract class Prop
+
+ trait Simple extends Prop
+
+ case class Atom(tree: Tree) extends Prop with Simple
+
+ case class Not(prop: Prop) extends Prop with Simple
+
+ def simplify1(prop: Prop): Prop = prop match {
+ case Atom(tree) => ???
+ case Not(prop) => ???
+ case _ => ???
+ }
+
+ def simplify2(prop: Prop): Prop = prop match {
+ case Not(Atom(tree)) => ???
+ case Not(Not(prop)) => ???
+ case _ => ???
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t9370/ThePlugin.scala b/test/files/pos/t9370/ThePlugin.scala
new file mode 100644
index 0000000000..cd800781dc
--- /dev/null
+++ b/test/files/pos/t9370/ThePlugin.scala
@@ -0,0 +1,31 @@
+package scala.test.plugins
+
+import scala.tools.nsc
+import nsc.Global
+import nsc.Phase
+import nsc.plugins.Plugin
+import nsc.plugins.PluginComponent
+
+class ThePlugin(val global: Global) extends Plugin {
+ import global._
+
+ val name = "timebomb"
+ val description = "Explodes if run. Maybe I haven't implemented it yet."
+ val components = List[PluginComponent](thePhase1)
+
+ private object thePhase1 extends PluginComponent {
+ val global = ThePlugin.this.global
+
+ val runsAfter = List[String]("parser")
+ override val runsBefore = List[String]("namer")
+ val phaseName = ThePlugin.this.name
+
+ def newPhase(prev: Phase) = new ThePhase(prev)
+ }
+
+ private class ThePhase(prev: Phase) extends Phase(prev) {
+ override def name = ThePlugin.this.name
+ override def run = ???
+ }
+}
+
diff --git a/test/files/pos/t9370/sample_2.flags b/test/files/pos/t9370/sample_2.flags
new file mode 100644
index 0000000000..dd7eb55d33
--- /dev/null
+++ b/test/files/pos/t9370/sample_2.flags
@@ -0,0 +1 @@
+-Xplugin:/tmp -Xplugin:. -Xplugin-require:timebomb -Ystop-after:parser
diff --git a/test/files/pos/t9370/sample_2.scala b/test/files/pos/t9370/sample_2.scala
new file mode 100644
index 0000000000..7eb11b8204
--- /dev/null
+++ b/test/files/pos/t9370/sample_2.scala
@@ -0,0 +1,6 @@
+
+package sample
+
+// just a sample that is compiled with the explosive plugin disabled
+object Sample extends App {
+}
diff --git a/test/files/pos/t9370/scalac-plugin.xml b/test/files/pos/t9370/scalac-plugin.xml
new file mode 100644
index 0000000000..2558d6fd03
--- /dev/null
+++ b/test/files/pos/t9370/scalac-plugin.xml
@@ -0,0 +1,5 @@
+<plugin>
+ <name>ignored</name>
+ <classname>scala.test.plugins.ThePlugin</classname>
+</plugin>
+
diff --git a/test/files/pos/t9392/client_2.scala b/test/files/pos/t9392/client_2.scala
new file mode 100644
index 0000000000..6b706fea12
--- /dev/null
+++ b/test/files/pos/t9392/client_2.scala
@@ -0,0 +1,4 @@
+class Client {
+ Macro()
+}
+
diff --git a/test/files/pos/t9392/macro_1.scala b/test/files/pos/t9392/macro_1.scala
new file mode 100644
index 0000000000..3f67ac17b2
--- /dev/null
+++ b/test/files/pos/t9392/macro_1.scala
@@ -0,0 +1,16 @@
+import language.experimental.macros
+
+
+object Macro {
+
+ import reflect.macros.blackbox.Context
+ def impl(c: Context)(): c.Tree = {
+ import c.universe._
+ val tree = q"""class C; new C"""
+ val tree1 = c.typecheck(tree)
+ val tpe = tree1.tpe
+ val tree2 = c.typecheck(c.untypecheck(tree1))
+ q"""$tree2.asInstanceOf[$tpe]"""
+ }
+ def apply(): Any = macro impl
+}
diff --git a/test/files/pos/t9393/NamedImpl_1.java b/test/files/pos/t9393/NamedImpl_1.java
new file mode 100644
index 0000000000..02ec9b4671
--- /dev/null
+++ b/test/files/pos/t9393/NamedImpl_1.java
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+package bug;
+
+import bug.Named_1;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+
+public class NamedImpl_1 implements Named_1 {
+
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+}
diff --git a/test/files/pos/t9393/NamedImpl_2.java b/test/files/pos/t9393/NamedImpl_2.java
new file mode 100644
index 0000000000..c87e94016d
--- /dev/null
+++ b/test/files/pos/t9393/NamedImpl_2.java
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+package bug;
+
+import bug.Named_2;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+
+public class NamedImpl_2 implements Named_2 {
+
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+}
diff --git a/test/files/pos/t9393/Named_1.java b/test/files/pos/t9393/Named_1.java
new file mode 100644
index 0000000000..30a6c9839a
--- /dev/null
+++ b/test/files/pos/t9393/Named_1.java
@@ -0,0 +1,3 @@
+package bug;
+
+public @interface Named_1 {}
diff --git a/test/files/pos/t9393/Named_2.java b/test/files/pos/t9393/Named_2.java
new file mode 100644
index 0000000000..3210fb636a
--- /dev/null
+++ b/test/files/pos/t9393/Named_2.java
@@ -0,0 +1,3 @@
+package bug;
+
+public @interface Named_2 {}
diff --git a/test/files/pos/t9393/test_2.scala b/test/files/pos/t9393/test_2.scala
new file mode 100644
index 0000000000..8ea346129d
--- /dev/null
+++ b/test/files/pos/t9393/test_2.scala
@@ -0,0 +1,4 @@
+class C {
+ new bug.NamedImpl_1 // separate compilation, testing the classfile parser
+ new bug.NamedImpl_2 // mixed compilation, testing the java source parser
+}
diff --git a/test/files/pos/t9442.scala b/test/files/pos/t9442.scala
new file mode 100644
index 0000000000..2ea81e79cb
--- /dev/null
+++ b/test/files/pos/t9442.scala
@@ -0,0 +1,14 @@
+trait Ctx {
+ trait Tree
+}
+trait Lst[+A] {
+ def zip[A1 >: A, B](that: Lst[B]): Nothing
+}
+class C[@specialized(Int) T] {
+ def moo(t: T) = {
+ def foo1(c: Ctx)(l: Lst[c.Tree]) = l zip l
+ def foo2(c: Ctx)(l: Lst[c.Tree]*) = l(0) zip l(1)
+ def foo3(c: Ctx)(l: => Lst[c.Tree]) = l zip l
+ ???
+ }
+}
diff --git a/test/files/pos/t9475.scala b/test/files/pos/t9475.scala
new file mode 100644
index 0000000000..ce9c250ace
--- /dev/null
+++ b/test/files/pos/t9475.scala
@@ -0,0 +1,19 @@
+trait Ctx {
+ trait Tree
+}
+
+trait Lst[+A] {
+ def zip[A1 >: A, B](that: Lst[B]): Nothing
+}
+
+object Test {
+
+ // both of these methods should be transformed by uncurry
+ // such that List[c.Tree] becomes List[Ctx#Tree]:
+ def foo1(c: Ctx)(l: Lst[c.Tree]) = l zip l
+ def foo2[@specialized T](c: Ctx)(l: Lst[c.Tree], t: T) = l zip l
+
+ // if this doesn't happen for the 2nd method, the specialization
+ // transformation fails
+}
+
diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check
index 4bf68b3d4e..94a3d64d68 100644
--- a/test/files/presentation/callcc-interpreter.check
+++ b/test/files/presentation/callcc-interpreter.check
@@ -3,7 +3,7 @@ reload: CallccInterpreter.scala
askTypeCompletion at CallccInterpreter.scala(51,34)
================================================================================
[response] askTypeCompletion at (51,34)
-retrieved 57 members
+retrieved 66 members
abstract trait Term extends AnyRef
abstract trait Value extends AnyRef
case class Add extends callccInterpreter.Term with Product with Serializable
@@ -50,6 +50,15 @@ final def synchronized[T0](x$1: T0): T0
final def wait(): Unit
final def wait(x$1: Long): Unit
final def wait(x$1: Long,x$2: Int): Unit
+object Add
+object App
+object Ccc
+object Con
+object Fun
+object Lam
+object M
+object Num
+object Var
private[this] val term0: callccInterpreter.App
private[this] val term1: callccInterpreter.App
private[this] val term2: callccInterpreter.Add
diff --git a/test/files/presentation/doc/doc.scala b/test/files/presentation/doc/doc.scala
index f2233f1828..f2233f1828 100755..100644
--- a/test/files/presentation/doc/doc.scala
+++ b/test/files/presentation/doc/doc.scala
diff --git a/test/files/presentation/doc/src/Class.scala b/test/files/presentation/doc/src/Class.scala
index a974bd6f5c..a974bd6f5c 100755..100644
--- a/test/files/presentation/doc/src/Class.scala
+++ b/test/files/presentation/doc/src/Class.scala
diff --git a/test/files/presentation/doc/src/p/Base.scala b/test/files/presentation/doc/src/p/Base.scala
index d91632b6f6..d91632b6f6 100755..100644
--- a/test/files/presentation/doc/src/p/Base.scala
+++ b/test/files/presentation/doc/src/p/Base.scala
diff --git a/test/files/presentation/doc/src/p/Derived.scala b/test/files/presentation/doc/src/p/Derived.scala
index 1a9c9a26d1..1a9c9a26d1 100755..100644
--- a/test/files/presentation/doc/src/p/Derived.scala
+++ b/test/files/presentation/doc/src/p/Derived.scala
diff --git a/test/files/run/class-symbol-contravariant.check b/test/files/run/class-symbol-contravariant.check
index 1d95273b50..5166fce96a 100644
--- a/test/files/run/class-symbol-contravariant.check
+++ b/test/files/run/class-symbol-contravariant.check
@@ -1,10 +1,8 @@
scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
+Power mode enabled. :phase is at typer.
+import scala.tools.nsc._, intp.global._, definitions._
+Try :help or completions for vals._ and power._
scala> val u = rootMirror.universe
u: $r.intp.global.type = <global>
diff --git a/test/files/run/constant-type.check b/test/files/run/constant-type.check
index b92f1481a3..9df1353354 100644
--- a/test/files/run/constant-type.check
+++ b/test/files/run/constant-type.check
@@ -1,10 +1,8 @@
scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
+Power mode enabled. :phase is at typer.
+import scala.tools.nsc._, intp.global._, definitions._
+Try :help or completions for vals._ and power._
scala> val s = transformedType(StringClass.toType).asInstanceOf[Type]
s: $r.intp.global.Type = String
diff --git a/test/files/run/constrained-types.check b/test/files/run/constrained-types.check
index 670d6f49aa..5444cf2088 100644
--- a/test/files/run/constrained-types.check
+++ b/test/files/run/constrained-types.check
@@ -133,16 +133,16 @@ y: String = hello
scala>
scala> val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
-<console>:11: error: not found: value e
+<console>:12: error: not found: value e
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
-<console>:11: error: not found: value f
+<console>:12: error: not found: value f
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
-<console>:11: error: not found: value g
+<console>:12: error: not found: value g
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
-<console>:11: error: not found: value h
+<console>:12: error: not found: value h
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
diff --git a/test/files/run/dead-code-elimination.scala b/test/files/run/dead-code-elimination.scala
index fd3f2a996a..2291b22f7a 100644
--- a/test/files/run/dead-code-elimination.scala
+++ b/test/files/run/dead-code-elimination.scala
@@ -10,7 +10,7 @@
// the stack after code elimination.
//
// Originally, this did not compile, but I included it in the run
-// tests because this was ASM-dependand and did not happen for GenJVM.
+// tests because this was ASM-dependent and did not happen for GenJVM.
//
// Thus, we run the code and force the loading of class B -- if the
// bytecode is incorrect, it will fail the test.
diff --git a/test/files/run/idempotency-case-classes.check b/test/files/run/idempotency-case-classes.check
index 5a8d0ad9d3..ea698cec59 100644
--- a/test/files/run/idempotency-case-classes.check
+++ b/test/files/run/idempotency-case-classes.check
@@ -47,8 +47,7 @@ C(2,3)
case <synthetic> def unapply(x$0: C): Option[(Int, Int)] = if (x$0.==(null))
scala.this.None
else
- Some.apply[(Int, Int)](scala.Tuple2.apply[Int, Int](x$0.x, x$0.y));
- <synthetic> private def readResolve(): Object = C
+ Some.apply[(Int, Int)](scala.Tuple2.apply[Int, Int](x$0.x, x$0.y))
};
Predef.println(C.apply(2, 3))
}
diff --git a/test/files/run/kind-repl-command.check b/test/files/run/kind-repl-command.check
index e050fb4bc1..560529ba03 100644
--- a/test/files/run/kind-repl-command.check
+++ b/test/files/run/kind-repl-command.check
@@ -19,7 +19,7 @@ scala> :k new { def empty = false }
AnyRef{def empty: Boolean}'s kind is A
scala> :k Nonexisting
-<console>:11: error: not found: value Nonexisting
+<console>:12: error: not found: value Nonexisting
Nonexisting
^
diff --git a/test/files/run/list_map.scala b/test/files/run/list_map.scala
index fba3aae228..fba3aae228 100755..100644
--- a/test/files/run/list_map.scala
+++ b/test/files/run/list_map.scala
diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala
index 7fb4a04546..4159dbdf91 100644
--- a/test/files/run/names-defaults.scala
+++ b/test/files/run/names-defaults.scala
@@ -192,7 +192,7 @@ object Test extends App {
println(argName) // should be 4
test5 { argName = 5 }
println(argName) // should be 5
- val a: Unit = test1(a = 10, b = "2") // local values a and b exist, but not ambiuous since they're val's
+ val a: Unit = test1(a = 10, b = "2") // local values a and b exist, but it's not ambiguous since they're vals
// dependent types and copy method
diff --git a/test/files/run/nothingTypeNoOpt.scala b/test/files/run/nothingTypeNoOpt.scala
index 5c5a20fa3b..454539a4b1 100644
--- a/test/files/run/nothingTypeNoOpt.scala
+++ b/test/files/run/nothingTypeNoOpt.scala
@@ -26,7 +26,7 @@ class C {
}
def f5(x: Boolean) = {
- // stack heights need to be the smae. ??? looks to the jvm like returning a value of
+ // stack heights need to be the same. ??? looks to the jvm like returning a value of
// type Nothing$, need to drop or throw it.
println(
if (x) { ???; 10 }
diff --git a/test/files/run/reflection-fieldmirror-ctorparam.check b/test/files/run/reflection-fieldmirror-ctorparam.check
index e391e7ccfe..c66be94ed7 100644
--- a/test/files/run/reflection-fieldmirror-ctorparam.check
+++ b/test/files/run/reflection-fieldmirror-ctorparam.check
@@ -1,3 +1,3 @@
-class scala.ScalaReflectionException: Scala field x isn't represented as a Java field, neither it has a Java accessor method
-note that private parameters of class constructors don't get mapped onto fields and/or accessors,
-unless they are used outside of their declaring constructors.
+class scala.ScalaReflectionException: Scala field x of class A isn't represented as a Java field, nor does it have a
+Java accessor method. One common reason for this is that it may be a private class parameter
+not used outside the primary constructor.
diff --git a/test/files/run/reify-repl-fail-gracefully.check b/test/files/run/reify-repl-fail-gracefully.check
index 025d377a43..32ed876356 100644
--- a/test/files/run/reify-repl-fail-gracefully.check
+++ b/test/files/run/reify-repl-fail-gracefully.check
@@ -8,7 +8,7 @@ import scala.reflect.runtime.universe._
scala>
scala> reify
-<console>:15: error: too few argument lists for macro invocation
+<console>:16: error: too few argument lists for macro invocation
reify
^
diff --git a/test/files/run/reify_newimpl_22.check b/test/files/run/reify_newimpl_22.check
index e69dc60199..985f646579 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>:18: free term: Ident(TermName("x")) defined by res0 in <console>:17:14
+<console>:19: free term: Ident(TermName("x")) defined by res0 in <console>:18:14
val code = reify {
^
2
diff --git a/test/files/run/reify_newimpl_23.check b/test/files/run/reify_newimpl_23.check
index 1356d509d3..f60113c69f 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>:16: free type: Ident(TypeName("T")) defined by foo in <console>:15:16
+<console>:17: free type: Ident(TypeName("T")) defined by foo in <console>:16:16
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 e512cfc52e..9104d8df0b 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>:14: free term: Ident(TermName("x")) defined by res0 in <console>:13:14
+<console>:15: free term: Ident(TermName("x")) defined by res0 in <console>:14:14
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 b203389db1..cbb21854ba 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>:12: free type: Ident(TypeName("T")) defined by foo in <console>:10:16
+<console>:13: free type: Ident(TypeName("T")) defined by foo in <console>:11:16
val tt = implicitly[WeakTypeTag[List[T]]]
^
foo: [T]=> Unit
diff --git a/test/files/run/repl-bare-expr.check b/test/files/run/repl-bare-expr.check
index f0c488455f..e0a1f4ecd6 100644
--- a/test/files/run/repl-bare-expr.check
+++ b/test/files/run/repl-bare-expr.check
@@ -1,12 +1,12 @@
scala> 2 ; 3
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
2 ;;
^
res0: Int = 3
scala> { 2 ; 3 }
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
{ 2 ; 3 }
^
res1: Int = 3
@@ -15,16 +15,16 @@ scala> 5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Mooo
1 +
2 +
3 } ; bippy+88+11
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
defined object Cow
diff --git a/test/files/run/repl-parens.check b/test/files/run/repl-parens.check
index 35853f10da..6516f4ea90 100644
--- a/test/files/run/repl-parens.check
+++ b/test/files/run/repl-parens.check
@@ -18,10 +18,10 @@ scala> ( (2 + 2 ) )
res5: Int = 4
scala> 5 ; ( (2 + 2 ) ) ; ((5))
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; ( (2 + 2 ) ) ;;
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; ( (2 + 2 ) ) ;;
^
res6: Int = 5
@@ -38,16 +38,16 @@ res9: String = 4423
scala>
scala> 55 ; ((2 + 2)) ; (1, 2, 3)
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
55 ; ((2 + 2)) ;;
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
55 ; ((2 + 2)) ;;
^
res10: (Int, Int, Int) = (1,2,3)
scala> 55 ; (x: Int) => x + 1 ; () => ((5))
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
55 ; (x: Int) => x + 1 ;;
^
res11: () => Int = <function0>
@@ -58,7 +58,7 @@ scala> () => 5
res12: () => Int = <function0>
scala> 55 ; () => 5
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
55 ;;
^
res13: () => Int = <function0>
diff --git a/test/files/run/repl-paste-2.check b/test/files/run/repl-paste-2.check
index 5b6a84144d..4c589df41a 100644
--- a/test/files/run/repl-paste-2.check
+++ b/test/files/run/repl-paste-2.check
@@ -1,7 +1,7 @@
scala> scala> 999l
-// Detected repl transcript paste: ctrl-D to finish.
+// Detected repl transcript. Paste more, or ctrl-D to finish.
res4: Int = 0123
@@ -42,7 +42,7 @@ scala> res5 + res6
res1: Int = 690
scala> val x = dingus
-<console>:10: error: not found: value dingus
+<console>:11: error: not found: value dingus
val x = dingus
^
diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check
index 2a7b7783d9..0d4a30b8e3 100644
--- a/test/files/run/repl-power.check
+++ b/test/files/run/repl-power.check
@@ -1,10 +1,8 @@
scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
+Power mode enabled. :phase is at typer.
+import scala.tools.nsc._, intp.global._, definitions._
+Try :help or completions for vals._ and power._
scala> // guarding against "error: reference to global is ambiguous"
@@ -25,4 +23,7 @@ m: $r.treedsl.global.Literal = 10
scala> typed(m).tpe // typed is in scope
res2: $r.treedsl.global.Type = Int(10)
+scala> """escaping is hard, m'kah"""
+res3: String = escaping is hard, m'kah
+
scala> :quit
diff --git a/test/files/run/repl-power.scala b/test/files/run/repl-power.scala
index 4dfeb37885..5ecaad8723 100644
--- a/test/files/run/repl-power.scala
+++ b/test/files/run/repl-power.scala
@@ -1,7 +1,9 @@
import scala.tools.partest.ReplTest
object Test extends ReplTest {
- def code = """
+ def tripleQuote(s: String) = "\"\"\"" + s + "\"\"\""
+
+ def code = s"""
:power
// guarding against "error: reference to global is ambiguous"
global.emptyValDef // "it is imported twice in the same scope by ..."
@@ -9,5 +11,6 @@ val tp = ArrayClass[scala.util.Random] // magic with tags
tp.memberType(Array_apply) // evidence
val m = LIT(10) // treedsl
typed(m).tpe // typed is in scope
+${tripleQuote("escaping is hard, m'kah")}
""".trim
}
diff --git a/test/files/run/repl-reset.check b/test/files/run/repl-reset.check
index b0683fff79..cf4d9a149e 100644
--- a/test/files/run/repl-reset.check
+++ b/test/files/run/repl-reset.check
@@ -28,13 +28,13 @@ Forgetting all expression results and named terms: $intp, BippyBungus, x1, x2, x
Forgetting defined types: BippyBungus
scala> x1 + x2 + x3
-<console>:11: error: not found: value x1
+<console>:12: error: not found: value x1
x1 + x2 + x3
^
-<console>:11: error: not found: value x2
+<console>:12: error: not found: value x2
x1 + x2 + x3
^
-<console>:11: error: not found: value x3
+<console>:12: error: not found: value x3
x1 + x2 + x3
^
@@ -42,7 +42,7 @@ scala> val x1 = 4
x1: Int = 4
scala> new BippyBungus
-<console>:11: error: not found: type BippyBungus
+<console>:12: error: not found: type BippyBungus
new BippyBungus
^
diff --git a/test/files/run/repl-serialization.check b/test/files/run/repl-serialization.check
index eb62729f5c..bbbf0dcdf1 100644
--- a/test/files/run/repl-serialization.check
+++ b/test/files/run/repl-serialization.check
@@ -20,6 +20,5 @@ u: U = U
evaluating O
constructing A
== reconstituting into a fresh classloader
- evaluating O
== evaluating reconstituted lambda
constructing A
diff --git a/test/files/run/repl-transcript.check b/test/files/run/repl-transcript.check
index 762a96b9cc..d0b455cbf6 100644
--- a/test/files/run/repl-transcript.check
+++ b/test/files/run/repl-transcript.check
@@ -1,7 +1,7 @@
scala> scala> class Bippity
-// Detected repl transcript paste: ctrl-D to finish.
+// Detected repl transcript. Paste more, or ctrl-D to finish.
defined class Bippity
diff --git a/test/files/run/repl-trim-stack-trace.scala b/test/files/run/repl-trim-stack-trace.scala
index ea91e32239..c0814905f9 100644
--- a/test/files/run/repl-trim-stack-trace.scala
+++ b/test/files/run/repl-trim-stack-trace.scala
@@ -12,7 +12,7 @@ f: Nothing
scala> f
java.lang.Exception: Uh-oh
- at .f(<console>:10)
+ at .f(<console>:11)
... 69 elided
scala> def f = throw new Exception("")
@@ -20,7 +20,7 @@ f: Nothing
scala> f
java.lang.Exception:
- at .f(<console>:10)
+ at .f(<console>:11)
... 69 elided
scala> def f = throw new Exception
@@ -28,7 +28,7 @@ f: Nothing
scala> f
java.lang.Exception
- at .f(<console>:10)
+ at .f(<console>:11)
... 69 elided
scala> :quit"""
diff --git a/test/files/run/scalapInvokedynamic.check b/test/files/run/scalapInvokedynamic.check
new file mode 100644
index 0000000000..8e4b08f234
--- /dev/null
+++ b/test/files/run/scalapInvokedynamic.check
@@ -0,0 +1,5 @@
+class C extends scala.AnyRef {
+ def this() = { /* compiled code */ }
+ def m: java.lang.String = { /* compiled code */ }
+}
+
diff --git a/test/files/run/scalapInvokedynamic.scala b/test/files/run/scalapInvokedynamic.scala
new file mode 100644
index 0000000000..670cf26662
--- /dev/null
+++ b/test/files/run/scalapInvokedynamic.scala
@@ -0,0 +1,11 @@
+class C {
+ def m = {
+ val f = (x: String) => x.trim
+ f(" H ae i ")
+ }
+}
+
+object Test extends App {
+ val testClassesDir = System.getProperty("partest.output")
+ scala.tools.scalap.Main.main(Array("-cp", testClassesDir, "C"))
+} \ No newline at end of file
diff --git a/test/files/run/t1931.scala b/test/files/run/t1931.scala
new file mode 100644
index 0000000000..eedfa9b03d
--- /dev/null
+++ b/test/files/run/t1931.scala
@@ -0,0 +1,43 @@
+
+import scala.tools.partest.SessionTest
+
+object Test extends SessionTest {
+
+ def session =
+"""
+scala> val x: Any = 42
+x: Any = 42
+
+scala> x + " works"
+res0: String = 42 works
+
+scala> import Predef.{ any2stringadd => _, _ }
+import Predef.{any2stringadd=>_, _}
+
+scala> x + " works"
+<console>:14: error: value + is not a member of Any
+ x + " works"
+ ^
+
+scala> import Predef._
+import Predef._
+
+scala> x + " works"
+res2: String = 42 works
+
+scala> object Predef { def f = 42 }
+defined object Predef
+
+scala> import Predef._
+import Predef._
+
+scala> f
+<console>:14: error: not found: value f
+ f
+ ^
+
+scala> Predef.f
+res4: Int = 42
+
+scala> :quit"""
+}
diff --git a/test/files/run/t2127.scala b/test/files/run/t2127.scala
index 869d8a38d6..839c8d6a5c 100755..100644
--- a/test/files/run/t2127.scala
+++ b/test/files/run/t2127.scala
@@ -28,5 +28,5 @@
}
-The constructor invocation of Bar is done within the scope of object Foo's constructor, and therefor the private constructor of Foo should be visible and accessible.
+The constructor invocation of Bar is done within the scope of object Foo's constructor, and therefore the private constructor of Foo should be visible and accessible.
*/
diff --git a/test/files/run/t2503.scala b/test/files/run/t2503.scala
index 21801e2dbd..21801e2dbd 100755..100644
--- a/test/files/run/t2503.scala
+++ b/test/files/run/t2503.scala
diff --git a/test/files/run/t3026.scala b/test/files/run/t3026.scala
index 22dde9cc03..22dde9cc03 100755..100644
--- a/test/files/run/t3026.scala
+++ b/test/files/run/t3026.scala
diff --git a/test/files/run/t4542.check b/test/files/run/t4542.check
index 3ab3eaffd8..6e099222b0 100644
--- a/test/files/run/t4542.check
+++ b/test/files/run/t4542.check
@@ -5,7 +5,7 @@ scala> @deprecated("foooo", "ReplTest version 1.0-FINAL") class Foo() {
defined class Foo
scala> val f = new Foo
-<console>:11: warning: class Foo is deprecated: foooo
+<console>:12: warning: class Foo is deprecated: foooo
val f = new Foo
^
f: Foo = Bippy
diff --git a/test/files/run/t4594-repl-settings.scala b/test/files/run/t4594-repl-settings.scala
index cbd87b5949..f2d1a8b3f8 100644
--- a/test/files/run/t4594-repl-settings.scala
+++ b/test/files/run/t4594-repl-settings.scala
@@ -15,7 +15,7 @@ object Test extends SessionTest {
|scala> :settings -deprecation
|
|scala> def b = depp
- |<console>:11: warning: method depp is deprecated: Please don't do that.
+ |<console>:12: warning: method depp is deprecated: Please don't do that.
| def b = depp
| ^
|b: String
diff --git a/test/files/run/t4658.check b/test/files/run/t4658.check
index bb6405175e..3bc52daef3 100644
--- a/test/files/run/t4658.check
+++ b/test/files/run/t4658.check
@@ -1,5 +1,5 @@
Ranges:
-1073741824
+-1073741824
1073741824
0
0
@@ -20,7 +20,7 @@ Ranges:
-10
IntRanges:
-1073741824
--1073741824
+1073741824
0
0
55
@@ -78,3 +78,6 @@ BigIntRanges:
-24
-30
-10
+BigInt agrees with Long: true
+Long agrees with Int when rounded: true
+Numeric Int agrees with Range: true
diff --git a/test/files/run/t4658.scala b/test/files/run/t4658.scala
index 8c07c50694..7fc6d4584c 100644
--- a/test/files/run/t4658.scala
+++ b/test/files/run/t4658.scala
@@ -2,6 +2,7 @@ import scala.collection.immutable.NumericRange
//#4658
object Test {
+ // Only works for Int values! Need to rethink explicit otherwise.
case class R(start: Int, end: Int, step: Int = 1, inclusive: Boolean = true)
val rangeData = Array(
@@ -28,6 +29,14 @@ object Test {
numericLongRanges.foreach{range => println(range.sum)}
println("BigIntRanges:")
numericBigIntRanges.foreach{range => println(range.sum)}
+ println("BigInt agrees with Long: " +
+ (numericLongRanges zip numericBigIntRanges).forall{ case (lr, bir) => lr.sum == bir.sum }
+ )
+ println("Long agrees with Int when rounded: " +
+ (numericLongRanges zip numericIntRanges).forall{ case (lr, ir) => lr.sum.toInt == ir.sum }
+ )
+ println("Numeric Int agrees with Range: " +
+ (numericIntRanges zip ranges).forall{ case (ir, r) => ir.sum == r.sum }
+ )
}
-
} \ No newline at end of file
diff --git a/test/files/run/t5655.check b/test/files/run/t5655.check
index 857a5ab556..9191997624 100644
--- a/test/files/run/t5655.check
+++ b/test/files/run/t5655.check
@@ -6,7 +6,7 @@ scala> import x._
import x._
scala> x
-<console>:15: error: reference to x is ambiguous;
+<console>:16: error: reference to x is ambiguous;
it is imported twice in the same scope by
import x._
and import x
@@ -14,7 +14,7 @@ and import x
^
scala> x
-<console>:15: error: reference to x is ambiguous;
+<console>:16: error: reference to x is ambiguous;
it is imported twice in the same scope by
import x._
and import x
diff --git a/test/files/run/t5699.check b/test/files/run/t5699.check
index df19644ae6..df19644ae6 100755..100644
--- a/test/files/run/t5699.check
+++ b/test/files/run/t5699.check
diff --git a/test/files/run/t5699.scala b/test/files/run/t5699.scala
index 409bcd250c..409bcd250c 100755..100644
--- a/test/files/run/t5699.scala
+++ b/test/files/run/t5699.scala
diff --git a/test/files/run/t5717.scala b/test/files/run/t5717.scala
index a0997f5a49..a0997f5a49 100755..100644
--- a/test/files/run/t5717.scala
+++ b/test/files/run/t5717.scala
diff --git a/test/files/run/t6146b.check b/test/files/run/t6146b.check
index 0e0c216cd7..11149c50fd 100644
--- a/test/files/run/t6146b.check
+++ b/test/files/run/t6146b.check
@@ -4,11 +4,9 @@ It would fail on the following inputs: S2(), S3()
^
scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
+Power mode enabled. :phase is at typer.
+import scala.tools.nsc._, intp.global._, definitions._
+Try :help or completions for vals._ and power._
scala> val u = rootMirror.universe; import u._, language._
u: $r.intp.global.type = <global>
diff --git a/test/files/run/t6439.check b/test/files/run/t6439.check
index eee2da1b12..dd7ba9f81d 100644
--- a/test/files/run/t6439.check
+++ b/test/files/run/t6439.check
@@ -48,11 +48,9 @@ scala> type F = Int // no warn
defined type alias F
scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
+Power mode enabled. :phase is at typer.
+import scala.tools.nsc._, intp.global._, definitions._
+Try :help or completions for vals._ and power._
scala> object lookup {
import intp._
diff --git a/test/files/run/t720.scala b/test/files/run/t720.scala
new file mode 100644
index 0000000000..a5cb2495cf
--- /dev/null
+++ b/test/files/run/t720.scala
@@ -0,0 +1,48 @@
+class Lazy(f: => Int) {
+ lazy val get: Int = f
+}
+
+class UsedLater(f: => Int) {
+ lazy val get: Int = f
+ def other = f
+}
+
+class TransientLazy(f: => Int) {
+ @transient
+ lazy val get: Int = f
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ testLazy()
+ testUsedLater()
+ }
+
+ def testLazy() {
+ val o = new Lazy("".length)
+ val f = classOf[Lazy].getDeclaredField("f")
+ f.setAccessible(true)
+ assert(f.get(o) != null)
+ o.get
+ assert(f.get(o) == null)
+ }
+
+ def testUsedLater() {
+ val o = new UsedLater("".length)
+ val f = classOf[UsedLater].getDeclaredField("f")
+ f.setAccessible(true)
+ assert(f.get(o) != null)
+ o.get
+ assert(f.get(o) != null)
+ }
+
+ def testTransientLazy() {
+ val o = new TransientLazy("".length)
+ val f = classOf[TransientLazy].getDeclaredField("f")
+ f.setAccessible(true)
+ assert(f.get(o) != null)
+ o.get
+ assert(f.get(o) != null) // SI-9365
+ }
+}
+
diff --git a/test/files/run/t7214.scala b/test/files/run/t7214.scala
index 15c2c24fa0..b2ef53eeab 100644
--- a/test/files/run/t7214.scala
+++ b/test/files/run/t7214.scala
@@ -1,4 +1,4 @@
-// pattern matcher crashes here trying to synthesize an uneeded outer test.
+// pattern matcher crashes here trying to synthesize an unneeded outer test.
// no-symbol does not have an owner
// at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49)
// at scala.tools.nsc.Global.abort(Global.scala:253)
diff --git a/test/files/run/t7246.check b/test/files/run/t7246.check
index ce01362503..ce01362503 100755..100644
--- a/test/files/run/t7246.check
+++ b/test/files/run/t7246.check
diff --git a/test/files/run/t7246/Outer.java b/test/files/run/t7246/Outer.java
index 163276fb3b..163276fb3b 100755..100644
--- a/test/files/run/t7246/Outer.java
+++ b/test/files/run/t7246/Outer.java
diff --git a/test/files/run/t7246/Test.scala b/test/files/run/t7246/Test.scala
index 9f23ca8f3a..9f23ca8f3a 100755..100644
--- a/test/files/run/t7246/Test.scala
+++ b/test/files/run/t7246/Test.scala
diff --git a/test/files/run/t7246b.check b/test/files/run/t7246b.check
index 5073bd8617..5073bd8617 100755..100644
--- a/test/files/run/t7246b.check
+++ b/test/files/run/t7246b.check
diff --git a/test/files/run/t7246b/Base.scala b/test/files/run/t7246b/Base.scala
index 4e71d3313d..4e71d3313d 100755..100644
--- a/test/files/run/t7246b/Base.scala
+++ b/test/files/run/t7246b/Base.scala
diff --git a/test/files/run/t7246b/Outer.java b/test/files/run/t7246b/Outer.java
index 53a79316ef..53a79316ef 100755..100644
--- a/test/files/run/t7246b/Outer.java
+++ b/test/files/run/t7246b/Outer.java
diff --git a/test/files/run/t7246b/Test.scala b/test/files/run/t7246b/Test.scala
index f0982ea8d0..f0982ea8d0 100755..100644
--- a/test/files/run/t7246b/Test.scala
+++ b/test/files/run/t7246b/Test.scala
diff --git a/test/files/run/t7319.check b/test/files/run/t7319.check
index 31923e7119..4d8429e8f2 100644
--- a/test/files/run/t7319.check
+++ b/test/files/run/t7319.check
@@ -15,21 +15,21 @@ warning: there was one feature warning; re-run with -feature for details
convert: [F[X <: F[X]]](builder: F[_ <: F[_]])Int
scala> convert(Some[Int](0))
-<console>:15: error: no type parameters for method convert: (builder: F[_ <: F[_]])Int exist so that it can be applied to arguments (Some[Int])
+<console>:16: error: no type parameters for method convert: (builder: F[_ <: F[_]])Int exist so that it can be applied to arguments (Some[Int])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : Some[Int]
required: ?F[_$1] forSome { type _$1 <: ?F[_$2] forSome { type _$2 } }
convert(Some[Int](0))
^
-<console>:15: error: type mismatch;
+<console>:16: error: type mismatch;
found : Some[Int]
required: F[_ <: F[_]]
convert(Some[Int](0))
^
scala> Range(1,2).toArray: Seq[_]
-<console>:14: error: polymorphic expression cannot be instantiated to expected type;
+<console>:15: error: polymorphic expression cannot be instantiated to expected type;
found : [B >: Int]Array[B]
required: Seq[_]
Range(1,2).toArray: Seq[_]
diff --git a/test/files/run/t7341.flags b/test/files/run/t7341.flags
index ae08446055..ae08446055 100755..100644
--- a/test/files/run/t7341.flags
+++ b/test/files/run/t7341.flags
diff --git a/test/files/run/t7341.scala b/test/files/run/t7341.scala
index ffea7f918b..ffea7f918b 100755..100644
--- a/test/files/run/t7341.scala
+++ b/test/files/run/t7341.scala
diff --git a/test/files/run/t7747-repl.check b/test/files/run/t7747-repl.check
index f19c39e7e1..d698ea668d 100644
--- a/test/files/run/t7747-repl.check
+++ b/test/files/run/t7747-repl.check
@@ -15,13 +15,13 @@ scala> val z = x * y
z: Int = 156
scala> 2 ; 3
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
2 ;;
^
res0: Int = 3
scala> { 2 ; 3 }
-<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
{ 2 ; 3 }
^
res1: Int = 3
@@ -30,16 +30,16 @@ scala> 5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Mooo
1 +
2 +
3 } ; bippy+88+11
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; 10 ; case object Cow ; 20 ; class Moo { override def toString = "Moooooo" } ; 30 ; def bippy = {
^
defined object Cow
@@ -81,10 +81,10 @@ scala> ( (2 + 2 ) )
res10: Int = 4
scala> 5 ; ( (2 + 2 ) ) ; ((5))
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; ( (2 + 2 ) ) ;;
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
5 ; ( (2 + 2 ) ) ;;
^
res11: Int = 5
@@ -101,16 +101,16 @@ res14: String = 4423
scala>
scala> 55 ; ((2 + 2)) ; (1, 2, 3)
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
55 ; ((2 + 2)) ;;
^
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
55 ; ((2 + 2)) ;;
^
res15: (Int, Int, Int) = (1,2,3)
scala> 55 ; (x: Int) => x + 1 ; () => ((5))
-<console>:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:13: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
55 ; (x: Int) => x + 1 ;;
^
res16: () => Int = <function0>
@@ -121,7 +121,7 @@ scala> () => 5
res17: () => Int = <function0>
scala> 55 ; () => 5
-<console>:10: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
+<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
55 ;;
^
res18: () => Int = <function0>
@@ -209,13 +209,13 @@ Forgetting all expression results and named terms: $intp, BippyBungus, Bovine, C
Forgetting defined types: BippyBungus, Moo, Ruminant
scala> x1 + x2 + x3
-<console>:11: error: not found: value x1
+<console>:12: error: not found: value x1
x1 + x2 + x3
^
-<console>:11: error: not found: value x2
+<console>:12: error: not found: value x2
x1 + x2 + x3
^
-<console>:11: error: not found: value x3
+<console>:12: error: not found: value x3
x1 + x2 + x3
^
@@ -223,7 +223,7 @@ scala> val x1 = 4
x1: Int = 4
scala> new BippyBungus
-<console>:11: error: not found: type BippyBungus
+<console>:12: error: not found: type BippyBungus
new BippyBungus
^
@@ -295,11 +295,9 @@ scala> b(a)
res4: String = Found Sum
scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
+Power mode enabled. :phase is at typer.
+import scala.tools.nsc._, intp.global._, definitions._
+Try :help or completions for vals._ and power._
scala> intp.lastRequest
res5: $r.intp.Request = Request(line=def $ires3 = intp.global, 1 trees)
diff --git a/test/files/run/t7850c.scala b/test/files/run/t7850c.scala
new file mode 100644
index 0000000000..25b9c0028d
--- /dev/null
+++ b/test/files/run/t7850c.scala
@@ -0,0 +1,11 @@
+// Testing that isEmpty and get are viewed with `memberType` from `Casey1`.
+trait T[A, B >: Null] { def isEmpty: A = false.asInstanceOf[A]; def get: B = null}
+class Casey1() extends T[Boolean, String]
+object Casey1 { def unapply(a: Casey1) = a }
+
+object Test {
+ def main(args: Array[String]) {
+ val c @ Casey1(x) = new Casey1()
+ assert(x == c.get)
+ }
+}
diff --git a/test/files/run/t7850d.scala b/test/files/run/t7850d.scala
new file mode 100644
index 0000000000..ccc98f1bcc
--- /dev/null
+++ b/test/files/run/t7850d.scala
@@ -0,0 +1,17 @@
+// Testing that the ad-hoc overload resolution of isEmpty/get discards
+// parameter-accepting variants
+trait T[A, B >: Null] { def isEmpty: A = false.asInstanceOf[A]; def get: B = null}
+class Casey1(val a: Int) {
+ def isEmpty: Boolean = false
+ def isEmpty(x: Int): Boolean = ???
+ def get: Int = a
+ def get(x: Int): String = ???
+}
+object Casey1 { def unapply(a: Casey1) = a }
+
+object Test {
+ def main(args: Array[String]) {
+ val c @ Casey1(x) = new Casey1(0)
+ assert(x == c.get)
+ }
+}
diff --git a/test/files/run/t8047.scala b/test/files/run/t8047.scala
index f5660541e8..9ec8c1dc56 100644
--- a/test/files/run/t8047.scala
+++ b/test/files/run/t8047.scala
@@ -1,7 +1,7 @@
object Test extends App {
import scala.reflect.runtime.universe._
//
- // x's owner is outer Test scope. Previosly the quasiquote expansion
+ // x's owner is outer Test scope. Previously the quasiquote expansion
// looked like:
//
// object Test {
diff --git a/test/files/run/t8346.check b/test/files/run/t8346.check
deleted file mode 100644
index 1ba5c31abe..0000000000
--- a/test/files/run/t8346.check
+++ /dev/null
@@ -1,6 +0,0 @@
-BitSet: List(invariant, invariant, invariant, invariant)
-HashSet: List(covariant (true), covariant (true), covariant (true), covariant (true))
-ListSet: List(covariant (true), covariant (true), covariant (true), covariant (true))
-SortedSet: List(invariant, invariant, invariant, invariant)
-TreeSet: List(invariant, invariant, invariant, invariant)
-ValueSet: invariant
diff --git a/test/files/run/t8346.scala b/test/files/run/t8346.scala
deleted file mode 100644
index 5f3df84174..0000000000
--- a/test/files/run/t8346.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-object Test extends App {
- import reflect.ClassTag
-
- object SomeEnum extends Enumeration {
- val one, two, three, four = Value
- }
-
- def sctor[A <: Set[Int]](f: Int => A)(implicit A: ClassTag[A])
- : (String, Int => Set[Int]) =
- (A.runtimeClass.getSimpleName, f)
-
- val inits: Seq[(String, Int => Set[Int])] = {
- import collection.immutable.{Seq => _, _}
- Seq(sctor(BitSet(_)),
- sctor(HashSet(_)),
- sctor(ListSet(_)),
- sctor(SortedSet(_)),
- sctor(TreeSet(_)))
- }
-
- def sVarInfo[A](sa: Set[A]): String = {
- val saa = sa.toSet[Any]
- if (sa eq saa) s"""covariant (${(saa + "hi") contains "hi"})"""
- else "invariant"
- }
-
- inits foreach {case (name, singleton) =>
- print(s"${name}: ")
- val one = singleton(1)
- println(Seq(2,3,4).scanLeft(one)(_ + _) map sVarInfo toList)
- }
-
- println(s"ValueSet: ${sVarInfo(SomeEnum.values)}")
-}
diff --git a/test/files/run/t8502b.scala b/test/files/run/t8502b.scala
new file mode 100644
index 0000000000..4f70d13bb0
--- /dev/null
+++ b/test/files/run/t8502b.scala
@@ -0,0 +1,46 @@
+import scala.tools.partest._
+import java.io.File
+
+// used to crash with an assertion failure in flatten because the type symbol created for the missing
+// package was a ClassSymbol, not a PackageClassSymbol
+// - isFlattenablePrefix(vanishingPackage) was true (wrongly)
+// - therefore flatten tried to flatten the class defined in the package, but the class is
+// top-level, vanishingClass.enclosingTopLevelClass is NoSymbol
+object Test extends StoreReporterDirectTest {
+ def code = ???
+
+ def compileCode(code: String) = {
+ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
+ }
+
+ def show(): Unit = {
+ compileCode("""
+ class Outer {
+ class Nested extends vanishing.Vanishing
+ }
+
+ package vanishing {
+ class Vanishing
+ }
+ """)
+ assert(filteredInfos.isEmpty, filteredInfos)
+ deletePackage("vanishing")
+ compileCode("""
+ class Test {
+ def f(o: Outer): Outer = o
+ }
+ """)
+ assert(storeReporter.infos.isEmpty, storeReporter.infos.mkString("\n")) // Included a MissingRequirementError before.
+ }
+
+ def deletePackage(name: String) {
+ val directory = new File(testOutput.path, name)
+ for (f <- directory.listFiles()) {
+ assert(f.getName.endsWith(".class"))
+ assert(f.delete())
+ }
+ assert(directory.listFiles().isEmpty)
+ assert(directory.delete())
+ }
+}
diff --git a/test/files/run/t9029.flags b/test/files/run/t9029.flags
new file mode 100644
index 0000000000..dcc59ebe32
--- /dev/null
+++ b/test/files/run/t9029.flags
@@ -0,0 +1 @@
+-deprecation
diff --git a/test/files/run/t9029.scala b/test/files/run/t9029.scala
new file mode 100644
index 0000000000..c01033b76e
--- /dev/null
+++ b/test/files/run/t9029.scala
@@ -0,0 +1,15 @@
+class Y(val _2: Int, val _1: String)
+
+object X { def unapply(u: Unit): Option[Y] = Some(new Y(42, "!")) }
+
+object Test {
+ def test1 = {
+ val X(y) = ()
+ val yy: Y = y
+ assert(yy._1 == "!")
+ assert(yy._2 == 42)
+ }
+ def main(args: Array[String]): Unit = {
+ test1
+ }
+}
diff --git a/test/files/run/t9029b.check b/test/files/run/t9029b.check
new file mode 100644
index 0000000000..aeb2d5e239
--- /dev/null
+++ b/test/files/run/t9029b.check
@@ -0,0 +1 @@
+Some(1)
diff --git a/test/files/run/t9029b.scala b/test/files/run/t9029b.scala
new file mode 100644
index 0000000000..764d0771ec
--- /dev/null
+++ b/test/files/run/t9029b.scala
@@ -0,0 +1,31 @@
+class Foo(val x: Bar) {
+ def isEmpty = false
+ def get = x
+}
+
+object Foo {
+ def unapply(x: Foo) = x
+}
+
+class Bar(val x: Option[Int], val y: Option[Int]) {
+ def isEmpty = false
+ def get = this
+ def _1 = x
+ def _2 = y
+}
+
+object Bar {
+ def unapply(x: Bar) = x
+}
+
+object Test {
+ def nameBased: Unit = {
+ val x: AnyRef = new Foo(new Bar(Some(1), Some(2)))
+ x match {
+ case Foo(Bar(x1, x2)) => println(x1)
+ }
+ }
+ def main(args: Array[String]): Unit = {
+ nameBased
+ }
+}
diff --git a/test/files/run/t9029c.scala b/test/files/run/t9029c.scala
new file mode 100644
index 0000000000..ccb51e23ae
--- /dev/null
+++ b/test/files/run/t9029c.scala
@@ -0,0 +1,21 @@
+object Extractor {
+ def unapply(a: Any): Option[Product2[Int, String]] = Some(new P2(1, "2"))
+}
+class P2[A, B](val _1: A, val _2: B) extends Product2[A, B] {
+ def canEqual(other: Any) = true
+ def isP2 = true
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ "" match {
+ case Extractor(p) =>
+ val pp: Product2[Int, String] = p
+ }
+ "" match {
+ case Extractor(x, y) =>
+ val xx: Int = x
+ val yy: String = y
+ }
+ }
+}
diff --git a/test/files/run/t9170.scala b/test/files/run/t9170.scala
index d6cf516615..f39467bc25 100644
--- a/test/files/run/t9170.scala
+++ b/test/files/run/t9170.scala
@@ -8,17 +8,17 @@ object Test extends SessionTest {
def session =
"""
scala> object Y { def f[A](a: => A) = 1 ; def f[A](a: => Either[Exception, A]) = 2 }
-<console>:10: error: double definition:
-def f[A](a: => A): Int at line 10 and
-def f[A](a: => Either[Exception,A]): Int at line 10
+<console>:11: error: double definition:
+def f[A](a: => A): Int at line 11 and
+def f[A](a: => Either[Exception,A]): Int at line 11
have same type after erasure: (a: Function0)Int
object Y { def f[A](a: => A) = 1 ; def f[A](a: => Either[Exception, A]) = 2 }
^
scala> object Y { def f[A](a: => A) = 1 ; def f[A](a: => Either[Exception, A]) = 2 }
-<console>:10: error: double definition:
-def f[A](a: => A): Int at line 10 and
-def f[A](a: => Either[Exception,A]): Int at line 10
+<console>:11: error: double definition:
+def f[A](a: => A): Int at line 11 and
+def f[A](a: => Either[Exception,A]): Int at line 11
have same type after erasure: (a: Function0)Int
object Y { def f[A](a: => A) = 1 ; def f[A](a: => Either[Exception, A]) = 2 }
^
@@ -27,9 +27,9 @@ scala> object Y {
| def f[A](a: => A) = 1
| def f[A](a: => Either[Exception, A]) = 2
| }
-<console>:12: error: double definition:
-def f[A](a: => A): Int at line 11 and
-def f[A](a: => Either[Exception,A]): Int at line 12
+<console>:13: error: double definition:
+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
^
@@ -44,9 +44,9 @@ object Y {
// Exiting paste mode, now interpreting.
-<console>:12: error: double definition:
-def f[A](a: => A): Int at line 11 and
-def f[A](a: => Either[Exception,A]): Int at line 12
+<console>:13: error: double definition:
+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
^
diff --git a/test/files/run/t9206.scala b/test/files/run/t9206.scala
index 872c980fe4..406798104e 100644
--- a/test/files/run/t9206.scala
+++ b/test/files/run/t9206.scala
@@ -7,14 +7,14 @@ object Test extends SessionTest {
def session =
s"""|
|scala> val i: Int = "foo"
- |<console>:10: error: type mismatch;
+ |<console>:11: error: type mismatch;
| found : String("foo")
| required: Int
| val i: Int = "foo"
| ^
|
|scala> { val j = 42 ; val i: Int = "foo" + j }
- |<console>:11: error: type mismatch;
+ |<console>:12: error: type mismatch;
| found : String
| required: Int
| { val j = 42 ; val i: Int = "foo" + j }
diff --git a/test/files/run/t9365.check b/test/files/run/t9365.check
new file mode 100644
index 0000000000..0d55bed3a3
--- /dev/null
+++ b/test/files/run/t9365.check
@@ -0,0 +1,2 @@
+foo
+foo
diff --git a/test/files/run/t9365.scala b/test/files/run/t9365.scala
new file mode 100644
index 0000000000..0c4477dda9
--- /dev/null
+++ b/test/files/run/t9365.scala
@@ -0,0 +1,18 @@
+class Test(x: => Object) extends Serializable {
+ @transient lazy val foo = x
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ import java.io._
+ val t = new Test("foo")
+ println(t.foo)
+ val baos = new ByteArrayOutputStream
+ val dos = new ObjectOutputStream(baos)
+ dos.writeObject(t)
+ dos.close()
+ val dis = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))
+ val t1 = dis.readObject().asInstanceOf[Test]
+ println(t1.foo) // was NPE
+ }
+}
diff --git a/test/files/run/t9375.check b/test/files/run/t9375.check
new file mode 100644
index 0000000000..87551dccd1
--- /dev/null
+++ b/test/files/run/t9375.check
@@ -0,0 +1,60 @@
+ konstruktor: class A
+ konstruktor: class A$O$12$
+ konstruktor: class A$$anon$1
+ konstruktor: class A$A
+ konstruktor: class A$C
+ konstruktor: class C
+ konstruktor: class T$O$15$
+ konstruktor: class T$$anon$2
+ konstruktor: class T$A
+ konstruktor: class T$C
+ konstruktor: class A$N$
+ konstruktor: class T$N$
+serializing outer objects should not initialize any nested objects
+now initializing nested objects
+ konstruktor: class A$O$
+ konstruktor: class A$Op$
+ konstruktor: class A$N$O$
+ konstruktor: class A$N$Op$
+ konstruktor: class A$A$O$
+ konstruktor: class A$A$Op$
+ konstruktor: class A$T$O$
+ konstruktor: class A$T$Op$
+ konstruktor: class A$O$11$
+ konstruktor: class A$$anonfun$1$O$13$
+ konstruktor: class A$$anon$1$O$
+ konstruktor: class A$$anon$1$Op$
+ konstruktor: class T$O$
+ konstruktor: class T$Op$
+ konstruktor: class T$N$O$
+ konstruktor: class T$N$Op$
+ konstruktor: class T$A$O$
+ konstruktor: class T$A$Op$
+ konstruktor: class T$T$O$
+ konstruktor: class T$T$Op$
+ konstruktor: class T$O$14$
+ konstruktor: class T$$anonfun$2$O$16$
+ konstruktor: class T$$anon$2$O$
+ konstruktor: class T$$anon$2$Op$
+no object konstruktors called when serializing / deserializing objects (starting at the outer or the object itself)
+deserializing outer objects with non-initialized inners again
+accessing modules triggers initialization
+ konstruktor: class A$O$
+ konstruktor: class A$Op$
+ konstruktor: class A$N$O$
+ konstruktor: class A$N$Op$
+deserializing creates a new object graph, including new scala 'object' instances, no matter where serialization starts
+init static module M and field v
+ konstruktor: class M$
+ konstruktor: class M$O$18$
+serDeser does not initialize nested static modules
+init M.O
+ konstruktor: class M$O$
+serDeser nested static module
+objects declared in field decls are not static modules, so they deserialize to new instances
+init lazy val M.w
+objects declared in lazy val are not static modules either
+ konstruktor: class M$O$19$
+object declared in a function: new instance created on each invocation
+ konstruktor: class M$$anonfun$3$O$20$
+ konstruktor: class M$$anonfun$3$O$20$
diff --git a/test/files/run/t9375.scala b/test/files/run/t9375.scala
new file mode 100644
index 0000000000..6ff4a425f8
--- /dev/null
+++ b/test/files/run/t9375.scala
@@ -0,0 +1,279 @@
+/*
+ * filter: inliner warning
+ */
+import java.io._
+
+object SerDes {
+ def serialize(obj: AnyRef): Array[Byte] = {
+ val buffer = new ByteArrayOutputStream
+ val out = new ObjectOutputStream(buffer)
+ out.writeObject(obj)
+ buffer.toByteArray
+ }
+
+ def deserialize(a: Array[Byte]): AnyRef = {
+ val in = new ObjectInputStream(new ByteArrayInputStream(a))
+ in.readObject
+ }
+
+ def serializeDeserialize[T <: AnyRef](obj: T) = deserialize(serialize(obj)).asInstanceOf[T]
+}
+
+import SerDes._
+
+// tests to make sure that de-serializing an object does not run its constructor
+
+trait S extends Serializable {
+ println(" konstruktor: " + this.getClass)
+}
+
+trait SE extends S {
+ def outer: Object
+}
+
+class A extends S {
+ object O extends SE { def outer = A.this }
+ private[this] object Op extends SE { def outer = A.this }
+ def P: SE = Op
+
+ object N extends S {
+ object O extends SE { def outer = N }
+ private[this] object Op extends SE { def outer = N }
+ def P: SE = Op
+ }
+
+ class A extends S {
+ object O extends SE { def outer = A.this }
+ private[this] object Op extends SE { def outer = A.this }
+ def P: SE = Op
+ }
+
+ trait T extends S {
+ object O extends SE { def outer = T.this }
+ private[this] object Op extends SE { def outer = T.this }
+ def P: SE = Op
+ }
+ class C extends T
+
+ def u: SE = {
+ object O extends SE { def outer = A.this }
+ O
+ }
+
+ val v: SE = {
+ object O extends SE { def outer = A.this }
+ O
+ }
+
+ val f: () => SE = () => {
+ object O extends SE { def outer = A.this }
+ O
+ }
+
+ trait GetObj { def O: SE; def P: SE }
+ val a: GetObj = new GetObj with S {
+ def anonThis = this
+ object O extends SE { def outer = anonThis }
+ private[this] object Op extends SE { def outer = anonThis }
+ def P: SE = Op
+ }
+}
+
+trait T extends S {
+ object O extends SE { def outer = T.this }
+ private[this] object Op extends SE { def outer = T.this }
+ def P: SE = Op
+
+ object N extends S {
+ object O extends SE { def outer = N }
+ private[this] object Op extends SE { def outer = N }
+ def P: SE = Op
+ }
+
+ class A extends S {
+ object O extends SE { def outer = A.this }
+ private[this] object Op extends SE { def outer = A.this }
+ def P: SE = Op
+ }
+
+ trait T extends S {
+ object O extends SE { def outer = T.this }
+ private[this] object Op extends SE { def outer = T.this }
+ def P: SE = Op
+ }
+ class C extends T
+
+ def u: SE = {
+ object O extends SE { def outer = T.this }
+ O
+ }
+
+ val v: SE = {
+ object O extends SE { def outer = T.this }
+ O
+ }
+
+ val f: () => SE = () => {
+ object O extends SE { def outer = T.this }
+ O
+ }
+
+ trait GetObj { def O: SE; def P: SE }
+ val a: GetObj = new GetObj with S {
+ def anonThis = this
+ object O extends SE { def outer = anonThis }
+ private[this] object Op extends SE { def outer = anonThis }
+ def P: SE = Op
+ }
+}
+
+class C extends T
+
+object DeserializeModuleNoConstructor {
+ def t(): Unit = {
+ val a = new A
+ val aa = new a.A
+ val ac = new a.C
+
+ val c = new C
+ val ca = new c.A
+ val cc = new c.C
+
+ val outers: List[Object] = List(
+ a, a.N, aa, ac, a.a,
+ c, c.N, ca, cc, c.a
+ )
+
+ println("serializing outer objects should not initialize any nested objects")
+
+ val serANotInit = serialize(a)
+ outers foreach serializeDeserialize
+
+ println("now initializing nested objects")
+
+ val os: List[(SE, Object)] = List(
+ a.O -> a,
+ a.P -> a,
+ a.N.O -> a.N,
+ a.N.P -> a.N,
+ aa.O -> aa,
+ aa.P -> aa,
+ ac.O -> ac,
+ ac.P -> ac,
+ a.u -> a,
+ a.v -> a,
+ a.f() -> a,
+ a.a.O -> a.a,
+ a.a.P -> a.a,
+
+ c.O -> c,
+ c.P -> c,
+ c.N.O -> c.N,
+ c.N.P -> c.N,
+ ca.O -> ca,
+ ca.P -> ca,
+ cc.O -> cc,
+ cc.P -> cc,
+ c.u -> c,
+ c.v -> c,
+ c.f() -> c,
+ c.a.O -> c.a,
+ c.a.P -> c.a
+ )
+
+ println("no object konstruktors called when serializing / deserializing objects (starting at the outer or the object itself)")
+
+ for ((obj, outer) <- os) {
+ assert(obj.outer eq outer, s"${obj.outer} of $obj -- $outer")
+ serializeDeserialize(obj)
+ serializeDeserialize(outer)
+ }
+
+ println("deserializing outer objects with non-initialized inners again")
+ val aNotInit = deserialize(serANotInit).asInstanceOf[A]
+
+ println("accessing modules triggers initialization")
+ aNotInit.O
+ aNotInit.P
+ aNotInit.N.O
+ aNotInit.N.P
+
+ println("deserializing creates a new object graph, including new scala 'object' instances, no matter where serialization starts")
+ val deserializedAs: List[A] = List(
+ serializeDeserialize(a),
+ serializeDeserialize(a.O).outer.asInstanceOf[A],
+ serializeDeserialize(a.P).outer.asInstanceOf[A],
+ serializeDeserialize(a.v).outer.asInstanceOf[A]
+ )
+ for (aSD <- deserializedAs) {
+ assert(aSD ne a)
+ assert(aSD.O ne a.O)
+ assert(aSD.P ne a.P)
+ assert(aSD.N ne a.N)
+ assert(aSD.N.O ne a.N.O)
+ assert(aSD.N.P ne a.N.P)
+ assert(aSD.v ne a.v)
+ assert(aSD.a.O ne a.a.O)
+ assert(aSD.a.P ne a.a.P)
+ }
+ }
+}
+
+// tests for serializing / deserializing static modules
+
+object M extends S {
+ object O extends S
+
+ def u: S = {
+ object O extends S
+ O
+ }
+
+ val v: S = {
+ object O extends S
+ O
+ }
+
+ lazy val w: S = {
+ object O extends S
+ O
+ }
+
+ val f: () => S = () => {
+ object O extends S
+ O
+ }
+}
+
+object SerializingStaticModules {
+ def t(): Unit = {
+ println("init static module M and field v")
+ M
+
+ println("serDeser does not initialize nested static modules")
+ assert(serializeDeserialize(M) eq M)
+
+ println("init M.O")
+ M.O
+
+ println("serDeser nested static module")
+ assert(serializeDeserialize(M.O) eq M.O)
+
+ println("objects declared in field decls are not static modules, so they deserialize to new instances")
+ assert(serializeDeserialize(M.v) ne M.v)
+
+ println("init lazy val M.w")
+
+ println("objects declared in lazy val are not static modules either")
+ assert(serializeDeserialize(M.w) ne M.w)
+
+ println("object declared in a function: new instance created on each invocation")
+ assert(M.f() ne M.f())
+ }
+}
+
+
+object Test extends App {
+ DeserializeModuleNoConstructor.t()
+ SerializingStaticModules.t()
+}
diff --git a/test/files/run/t9387.scala b/test/files/run/t9387.scala
new file mode 100644
index 0000000000..3e33d19fd2
--- /dev/null
+++ b/test/files/run/t9387.scala
@@ -0,0 +1,20 @@
+class G[T]
+object G {
+ def v[T](x: T): G[T] = null
+}
+
+class A[T]
+object A {
+ def apply[T](x: => G[T]): A[T] = null
+}
+
+object T {
+ A[Unit](G.v(() => ())) // Was VerifyError
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ T
+ }
+
+} \ No newline at end of file
diff --git a/test/files/run/t9387b.check b/test/files/run/t9387b.check
new file mode 100644
index 0000000000..6a452c185a
--- /dev/null
+++ b/test/files/run/t9387b.check
@@ -0,0 +1 @@
+()
diff --git a/test/files/run/t9387b.scala b/test/files/run/t9387b.scala
new file mode 100644
index 0000000000..6339f4caba
--- /dev/null
+++ b/test/files/run/t9387b.scala
@@ -0,0 +1,16 @@
+object T {
+ val f: Unit = () => ()
+ println(f)
+}
+
+object U {
+ def f[T](t: T): T = t
+ f[Unit](() => ())
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ T
+ U
+ }
+}
diff --git a/test/files/run/t9388-bin-compat.scala b/test/files/run/t9388-bin-compat.scala
new file mode 100644
index 0000000000..a03646612f
--- /dev/null
+++ b/test/files/run/t9388-bin-compat.scala
@@ -0,0 +1,16 @@
+class C {
+ private object N extends Serializable { override def toString = "N" }
+ def foo = N.toString
+}
+object Test {
+ def main(args: Array[String]): Unit = {
+ val c = Class.forName("C")
+ assert(c.getDeclaredFields().toList.map(_.toString) ==
+ List("private volatile C$N$ C.C$$N$module")) // field is name-mangled (C$$N$module instead of just N$module)
+ assert(c.getDeclaredMethods().toList.map(_.toString).sorted ==
+ List("private C$N$ C.C$$N$lzycompute()",
+ "public C$N$ C.C$$N()",
+ "public java.lang.String C.foo()")) // accessor is public, name-mangled
+ assert((new C).foo == "N")
+ }
+}
diff --git a/test/files/run/t9403.flags b/test/files/run/t9403.flags
new file mode 100644
index 0000000000..307668060c
--- /dev/null
+++ b/test/files/run/t9403.flags
@@ -0,0 +1 @@
+-Ybackend:GenASM -optimize
diff --git a/test/files/run/t9403/C_1.scala b/test/files/run/t9403/C_1.scala
new file mode 100644
index 0000000000..439af1a386
--- /dev/null
+++ b/test/files/run/t9403/C_1.scala
@@ -0,0 +1,5 @@
+package p
+class C {
+ @inline final def f(x: Int): Long = 10L / (if (x < 0) -2 else 2)
+ @inline final def g(x: Int): Long = 3000L / (if (x < 0) -300 else 300)
+}
diff --git a/test/files/run/t9403/Test_2.scala b/test/files/run/t9403/Test_2.scala
new file mode 100644
index 0000000000..fb2777b9a8
--- /dev/null
+++ b/test/files/run/t9403/Test_2.scala
@@ -0,0 +1,29 @@
+import p.C
+import scala.tools.asm.Opcodes
+import scala.tools.partest.BytecodeTest
+import scala.tools.partest.ASMConverters._
+
+
+object Test extends BytecodeTest {
+ def foo(c: C, x: Int) = c.f(x)
+ def goo(c: C, x: Int) = c.g(x)
+
+ def has(i: Instruction, c: String, m: String) = {
+ val cls = loadClassNode(c)
+ val mth = convertMethod(getMethod(cls, m))
+ assert(mth.instructions.contains(i))
+ }
+
+ def show(): Unit = {
+ assert(foo(new C, -2) == -5L)
+ assert(goo(new C, -2) == -10L)
+
+ val bipush2 = IntOp(Opcodes.BIPUSH, -2)
+ has(bipush2, "p.C", "f")
+ has(bipush2, "Test$", "foo")
+
+ val sipush300 = IntOp(Opcodes.SIPUSH, -300)
+ has(sipush300, "p.C", "g")
+ has(sipush300, "Test$", "goo")
+ }
+}
diff --git a/test/files/run/t9422.scala b/test/files/run/t9422.scala
new file mode 100644
index 0000000000..5ca2e8daaa
--- /dev/null
+++ b/test/files/run/t9422.scala
@@ -0,0 +1,11 @@
+class Test(val x: Long) {
+ def sameDirection(y: Long): Boolean =
+ (y == 0 || x == 0 || ((y > 0) == (x > 0)))
+}
+
+object Test {
+ def main(args: Array[String]) {
+ val b = new Test(1L)
+ assert(!b.sameDirection(-1L))
+ }
+}
diff --git a/test/files/run/t9425.scala b/test/files/run/t9425.scala
new file mode 100644
index 0000000000..f251cc8579
--- /dev/null
+++ b/test/files/run/t9425.scala
@@ -0,0 +1,8 @@
+class C { case class Foo private (x: Int); Foo.apply(0) }
+
+object Test {
+ def test(c: C) = {import c.Foo; Foo.apply(0)}
+ def main(args: Array[String]): Unit = {
+ test(new C)
+ }
+}
diff --git a/test/files/run/test-cpp.scala b/test/files/run/test-cpp.scala
index 4e00e72658..4fca67d51e 100644
--- a/test/files/run/test-cpp.scala
+++ b/test/files/run/test-cpp.scala
@@ -46,7 +46,7 @@ object TestSetterInline {
* The access of the local variable 'y' should be replaced by the
* constant.
*/
-object TestAliasChainConstat {
+object TestAliasChainConstant {
def main(args: Array[String]): Unit = {
val x = 2
diff --git a/test/files/run/toolbox_expand_macro.check b/test/files/run/toolbox_expand_macro.check
new file mode 100644
index 0000000000..d81cc0710e
--- /dev/null
+++ b/test/files/run/toolbox_expand_macro.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/toolbox_expand_macro.scala b/test/files/run/toolbox_expand_macro.scala
new file mode 100644
index 0000000000..a52e449168
--- /dev/null
+++ b/test/files/run/toolbox_expand_macro.scala
@@ -0,0 +1,23 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox}
+
+object Test extends App {
+ val toolBox = cm.mkToolBox()
+ val x = 21
+ val runtimeMacro =
+ q"""object RuntimeMacro {
+ import scala.reflect.macros.whitebox.Context
+ import scala.language.experimental.macros
+
+ def add(y: Int): Int = macro addImpl
+ def addImpl(c: Context)(y: c.Expr[Int]): c.Expr[Int] = {
+ import c.universe._
+ val x = $x
+ c.Expr[Int](q"$$x + $$y")
+ }
+ }"""
+ val s = toolBox.define(runtimeMacro)
+ println(toolBox.eval(q"$s.add(21)"))
+}
diff --git a/test/files/run/tpeCache-tyconCache.check b/test/files/run/tpeCache-tyconCache.check
index ac13d32f91..b26f1ab8a1 100644
--- a/test/files/run/tpeCache-tyconCache.check
+++ b/test/files/run/tpeCache-tyconCache.check
@@ -1,10 +1,8 @@
scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
+Power mode enabled. :phase is at typer.
+import scala.tools.nsc._, intp.global._, definitions._
+Try :help or completions for vals._ and power._
scala>
diff --git a/test/files/run/viewtest.scala b/test/files/run/viewtest.scala
index 581958e9a6..581958e9a6 100755..100644
--- a/test/files/run/viewtest.scala
+++ b/test/files/run/viewtest.scala
diff --git a/test/files/run/weakconform.scala b/test/files/run/weakconform.scala
index 30a12b9298..30a12b9298 100755..100644
--- a/test/files/run/weakconform.scala
+++ b/test/files/run/weakconform.scala
diff --git a/test/files/run/xMigration.check b/test/files/run/xMigration.check
index 79ce544493..cd860bf394 100644
--- a/test/files/run/xMigration.check
+++ b/test/files/run/xMigration.check
@@ -10,7 +10,7 @@ res1: Iterable[String] = MapLike(eis)
scala> :setting -Xmigration:any
scala> Map(1 -> "eis").values // warn
-<console>:11: warning: method values in trait MapLike has changed semantics in version 2.8.0:
+<console>:12: warning: method values in trait MapLike has changed semantics in version 2.8.0:
`values` returns `Iterable[B]` rather than `Iterator[B]`.
Map(1 -> "eis").values // warn
^
@@ -24,7 +24,7 @@ res3: Iterable[String] = MapLike(eis)
scala> :setting -Xmigration:2.7
scala> Map(1 -> "eis").values // warn
-<console>:11: warning: method values in trait MapLike has changed semantics in version 2.8.0:
+<console>:12: warning: method values in trait MapLike has changed semantics in version 2.8.0:
`values` returns `Iterable[B]` rather than `Iterator[B]`.
Map(1 -> "eis").values // warn
^
@@ -38,7 +38,7 @@ res5: Iterable[String] = MapLike(eis)
scala> :setting -Xmigration // same as :any
scala> Map(1 -> "eis").values // warn
-<console>:11: warning: method values in trait MapLike has changed semantics in version 2.8.0:
+<console>:12: warning: method values in trait MapLike has changed semantics in version 2.8.0:
`values` returns `Iterable[B]` rather than `Iterator[B]`.
Map(1 -> "eis").values // warn
^
diff --git a/test/files/scalacheck/range.scala b/test/files/scalacheck/range.scala
index 493083a51f..ac24b52f8d 100644
--- a/test/files/scalacheck/range.scala
+++ b/test/files/scalacheck/range.scala
@@ -134,7 +134,22 @@ abstract class RangeTest(kind: String) extends Properties("Range "+kind) {
val expected = r.length match {
case 0 => 0
case 1 => r.head
- case _ => ((r.head + r.last).toLong * r.length / 2).toInt
+ case x if x < 1000 =>
+ // Explicit sum, to guard against having the same mistake in both the
+ // range implementation and test implementation of sum formula.
+ // (Yes, this happened before.)
+ var i = r.head
+ var s = 0L
+ var n = x
+ while (n > 0) {
+ s += i
+ i += r.step
+ n -= 1
+ }
+ s.toInt
+ case _ =>
+ // Make sure head + last doesn't overflow!
+ ((r.head.toLong + r.last) * r.length / 2).toInt
}
// println("size: " + r.length)
// println("expected: " + expected)
diff --git a/test/junit/scala/collection/immutable/PagedSeqTest.scala b/test/junit/scala/collection/immutable/PagedSeqTest.scala
index 2b576a3655..74f8825307 100644
--- a/test/junit/scala/collection/immutable/PagedSeqTest.scala
+++ b/test/junit/scala/collection/immutable/PagedSeqTest.scala
@@ -13,6 +13,12 @@ class PagedSeqTest {
assertEquals(Seq('a'), PagedSeq.fromStrings(List.fill(5000)("a")).slice(4096, 4097))
}
+ // should not NPE, and should be empty
+ @Test
+ def test_SI9480(): Unit = {
+ assertEquals(Seq(), PagedSeq.fromStrings(List("a")).slice(1))
+ }
+
// Slices shouldn't read outside where they belong
@Test
def test_SI6519 {
diff --git a/test/junit/scala/collection/immutable/RangeConsistencyTest.scala b/test/junit/scala/collection/immutable/RangeConsistencyTest.scala
index 135796979d..760498c162 100644
--- a/test/junit/scala/collection/immutable/RangeConsistencyTest.scala
+++ b/test/junit/scala/collection/immutable/RangeConsistencyTest.scala
@@ -148,4 +148,28 @@ class RangeConsistencyTest {
val bdRange = bd(-10.0) until bd(0.0) by bd(4.5)
assert( bdRange sameElements List(bd(-10.0), bd(-5.5), bd(-1.0)) )
}
+
+ @Test
+ def test_SI9388() {
+ val possiblyNotDefaultNumeric = new scala.math.Numeric[Int] {
+ def fromInt(x: Int) = x
+ def minus(x: Int, y: Int): Int = x - y
+ def negate(x: Int): Int = -x
+ def plus(x: Int, y: Int): Int = x + y
+ def times(x: Int, y: Int): Int = x*y
+ def toDouble(x: Int): Double = x.toDouble
+ def toFloat(x: Int): Float = x.toFloat
+ def toInt(x: Int): Int = x
+ def toLong(x: Int): Long = x.toLong
+ def compare(x: Int, y: Int) = x compare y
+ }
+ val r = (Int.MinValue to Int.MaxValue by (1<<23))
+ val nr = NumericRange(Int.MinValue, Int.MaxValue, 1 << 23)
+ assert({ var i = 0; r.foreach(_ => i += 1); i } == 512)
+ assert({ var i = 0; nr.foreach(_ => i += 1); i } == 512)
+ assert(r.sum == Int.MinValue)
+ assert(nr.sum == Int.MinValue)
+ assert(r.sum(possiblyNotDefaultNumeric) == Int.MinValue)
+ assert(nr.sum(possiblyNotDefaultNumeric) == Int.MinValue)
+ }
}
diff --git a/test/junit/scala/collection/immutable/SetTests.scala b/test/junit/scala/collection/immutable/SetTests.scala
new file mode 100644
index 0000000000..28c7864359
--- /dev/null
+++ b/test/junit/scala/collection/immutable/SetTests.scala
@@ -0,0 +1,81 @@
+package scala.collection.immutable
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class SetTests {
+ @Test
+ def test_SI8346_toSet_soundness(): Unit = {
+ val any2stringadd = "Disabled string conversions so as not to get confused!"
+
+ def any[A](set: Set[A]): Set[Any] = {
+ val anyset = set.toSet[Any]
+ assert((anyset + "fish") contains "fish")
+ anyset
+ }
+
+ // Make sure default immutable Set does not rebuild itself on widening with toSet
+ // Need to cover 0, 1, 2, 3, 4 elements as special cases
+ var si = Set.empty[Int]
+ assert(si eq si.toSet[Any])
+ for (i <- 1 to 5) {
+ val s1 = Set(Array.range(1, i+1): _*)
+ val s2 = si + i
+ val s1a = any(s1)
+ val s2a = any(s2)
+ assert(s1 eq s1a)
+ assert(s2 eq s2a)
+ si = s2
+ }
+
+ // Make sure BitSet correctly rebuilds itself on widening with toSet
+ // Need to cover empty, values 0-63, values 0-127 as special cases
+ val bitsets = Seq(BitSet.empty, BitSet(23), BitSet(23, 99), BitSet(23, 99, 141))
+ bitsets.foreach{ b =>
+ val ba = any(b)
+ assert(b ne ba)
+ assertEquals(b, ba)
+ }
+
+ // Make sure HashSet (and by extension, its implementing class HashTrieSet)
+ // does not rebuild itself on widening by toSet
+ val hashset = HashSet(1, 3, 5, 7)
+ val hashseta = any(hashset)
+ assert(hashset eq hashseta)
+
+ // Make sure ListSet does not rebuild itself on widening by toSet
+ // (Covers Node also, since it subclasses ListSet)
+ val listset = ListSet(1, 3, 5, 7)
+ val listseta = any(listset)
+ assert(listset eq listseta)
+
+ // Make sure SortedSets correctly rebuild themselves on widening with toSet
+ // Covers TreeSet and keySet of SortedMap also
+ val sortedsets = Seq(
+ SortedSet.empty[Int], SortedSet(5), SortedSet(1,2,3,5,4),
+ SortedMap(1 -> "cod", 2 -> "herring").keySet
+ )
+ sortedsets.foreach{ set =>
+ val seta = any(set)
+ assert(set ne seta)
+ assertEquals(set, seta)
+ }
+
+ // Make sure ValueSets correctly rebuild themselves on widening with toSet
+ object WeekDay extends Enumeration {
+ type WeekDay = Value
+ val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
+ }
+ val valuesa = any(WeekDay.values)
+ assert(WeekDay.values ne valuesa)
+ assertEquals(WeekDay.values, valuesa)
+
+ // Make sure regular Map keySets do not rebuild themselves on widening with toSet
+ val mapset = Map(1 -> "cod", 2 -> "herring").keySet
+ val mapseta = any(mapset)
+ assert(mapset eq mapseta)
+ }
+}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala
index 9af9ef54fc..941a167114 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala
@@ -204,7 +204,7 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
def iincProdCons(): Unit = {
import Opcodes._
val m = genMethod(descriptor = "(I)I")(
- Incr(IINC, 1, 1), // producer and cosumer of local variable 1
+ Incr(IINC, 1, 1), // producer and consumer of local variable 1
VarOp(ILOAD, 1),
Op(IRETURN)
)
@@ -246,4 +246,46 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
testSingleInsn(a.consumersOfOutputsFrom(l2i), "IRETURN")
testSingleInsn(a.producersForInputsOf(ret), "L2I")
}
+
+ @Test
+ def cyclicProdCons(): Unit = {
+ import Opcodes._
+ val m = genMethod(descriptor = "(I)I")(
+ Label(1),
+ VarOp(ILOAD, 1),
+ IntOp(BIPUSH, 10),
+ Op(IADD), // consumer of the above ILOAD
+
+ Op(ICONST_0),
+ Jump(IF_ICMPNE, Label(2)),
+
+ VarOp(ILOAD, 1),
+ VarOp(ISTORE, 1),
+ Jump(GOTO, Label(1)),
+
+ Label(2),
+ IntOp(BIPUSH, 9),
+ Op(IRETURN)
+ )
+ m.maxLocals = 2
+ m.maxStack = 2
+ val a = new ProdConsAnalyzer(m, "C")
+
+ val List(iadd) = findInstr(m, "IADD")
+ val firstLoad = iadd.getPrevious.getPrevious
+ assert(firstLoad.getOpcode == ILOAD)
+ val secondLoad = findInstr(m, "ISTORE").head.getPrevious
+ assert(secondLoad.getOpcode == ILOAD)
+
+ testSingleInsn(a.producersForValueAt(iadd, 2), "ILOAD")
+ testSingleInsn(a.initialProducersForValueAt(iadd, 2), "ParameterProducer(1)")
+ testMultiInsns(a.producersForInputsOf(firstLoad), List("ParameterProducer", "ISTORE"))
+ testMultiInsns(a.producersForInputsOf(secondLoad), List("ParameterProducer", "ISTORE"))
+
+ testSingleInsn(a.ultimateConsumersOfOutputsFrom(firstLoad), "IADD")
+ testSingleInsn(a.ultimateConsumersOfOutputsFrom(secondLoad), "IADD")
+
+ testSingleInsn(a.consumersOfOutputsFrom(firstLoad), "IADD")
+ testSingleInsn(a.consumersOfOutputsFrom(secondLoad), "ISTORE")
+ }
}
diff --git a/test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala b/test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala
index 13a955b55d..d17856eb54 100644
--- a/test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala
+++ b/test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala
@@ -10,7 +10,7 @@ import scala.tools.testing.AssertUtil._
@RunWith(classOf[JUnit4])
class HtmlDocletTest {
@Test
- def testSyntaxHighlightningUnicode() {
+ def testSyntaxHighlightingUnicode() {
val in = "unicode: …"
val out = SyntaxHigh(in).toString
diff --git a/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala b/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala
new file mode 100644
index 0000000000..78ebb7cf9c
--- /dev/null
+++ b/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala
@@ -0,0 +1,180 @@
+package scala.tools.nsc.interpreter
+
+import java.io.{StringWriter, PrintWriter}
+
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+import scala.tools.nsc.Settings
+
+class CompletionTest {
+ val EmptyString = "" // def string results include the empty string so that JLine won't insert "def ..." at the cursor
+
+ def newIMain(): IMain = {
+ val settings = new Settings()
+ settings.Xnojline.value = true
+ settings.usejavacp.value = true
+
+ val writer = new StringWriter
+ val out = new PrintWriter(writer)
+ new IMain(settings, out)
+ }
+ @Test
+ def t4438_arrayCompletion(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ assert(completer.complete("Array(1, 2, 3) rev").candidates.contains("reverseMap"))
+ }
+
+ @Test
+ def completions(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ checkExact(completer, "object O { def x_y_z = 1 }; import O._; x_y")("x_y_z")
+ checkExact(completer, "object O { private def x_y_z = 1 }; import O._; x_y")()
+ checkExact(completer, "object O { private def x_y_z = 1; x_y", "}")("x_y_z")
+ checkExact(completer, "object x_y_z; import x_y")("x_y_z")
+
+ checkExact(completer, "object x_y_z { def a_b_c }; import x_y_z.a_b")("a_b_c")
+
+ checkExact(completer, "object X { private[this] def definition = 0; def")("definition")
+
+ // stable terms are offered in type completion as they might be used as a prefix
+ checkExact(completer, """object O { def x_y_z = 0; val x_z_y = ""; type T = x_""")("x_z_y")
+ checkExact(completer, """def method { def x_y_z = 0; val x_z_y = ""; type T = x_""")("x_z_y")
+
+ // We exclude inherited members of the synthetic interpreter wrapper classes
+ checkExact(completer, """asInstanceO""")()
+ checkExact(completer, """class C { asInstanceO""")("asInstanceOf")
+
+ // Output is sorted
+ assertEquals(List("prefix_aaa", "prefix_nnn", "prefix_zzz"), completer.complete( """class C { def prefix_nnn = 0; def prefix_zzz = 0; def prefix_aaa = 0; prefix_""").candidates)
+ }
+
+ @Test
+ def annotations(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ checkExact(completer, "def foo[@specialize", " A]")("specialized")
+ checkExact(completer, "def foo[@specialize")("specialized")
+ checkExact(completer, """@deprecatedN""", """ class Foo""")("deprecatedName")
+ checkExact(completer, """@deprecateN""")("deprecatedName")
+ checkExact(completer, """{@deprecateN""")("deprecatedName")
+ }
+
+ @Test
+ def incompleteStringInterpolation(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ checkExact(completer, """val x_y_z = 1; s"${x_""", "}\"")("x_y_z")
+ checkExact(completer, """val x_y_z = 1; s"${x_""", "\"")("x_y_z")
+ }
+
+ @Test
+ def symbolically(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ checkExact(completer, """class C { def +++(a: Any) = 0; def ---(a: Any) = 0; this.++""")("+++")
+ }
+
+ @Test
+ def camelCompletions(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ checkExact(completer, "object O { def theCatSatOnTheMat = 1 }; import O._; tCSO")("theCatSatOnTheMat")
+ checkExact(completer, "object O { def getBlerganator = 1 }; import O._; blerga")("getBlerganator")
+ checkExact(completer, "object O { def xxxxYyyyyZzzz = 1; def xxxxYyZeee = 1 }; import O._; xYZ")("", "xxxxYyyyyZzzz", "xxxxYyZeee")
+ checkExact(completer, "object O { def xxxxYyyyyZzzz = 1; def xxxxYyyyyZeee = 1 }; import O._; xYZ")("xxxxYyyyyZzzz", "xxxxYyyyyZeee")
+ checkExact(completer, "object O { class AbstractMetaFactoryFactory }; new O.AMFF")("AbstractMetaFactoryFactory")
+ }
+
+ @Test
+ def lenientCamelCompletions(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ checkExact(completer, "object O { def theCatSatOnTheMat = 1 }; import O._; tcso")("theCatSatOnTheMat")
+ checkExact(completer, "object O { def theCatSatOnTheMat = 1 }; import O._; sotm")("theCatSatOnTheMat")
+ checkExact(completer, "object O { def theCatSatOnTheMat = 1 }; import O._; TCSOTM")()
+ }
+
+ @Test
+ def previousLineCompletions(): Unit = {
+ val intp = newIMain()
+ intp.interpret("class C { val x_y_z = 42 }")
+ intp.interpret("object O { type T = Int }")
+
+ val completer = new PresentationCompilerCompleter(intp)
+
+ checkExact(completer, "new C().x_y")("x_y_z")
+ checkExact(completer, "(1 : O.T).toCha")("toChar")
+
+ intp.interpret("case class X_y_z()")
+ val completer1 = new PresentationCompilerCompleter(intp)
+ checkExact(completer1, "new X_y_")("X_y_z")
+ checkExact(completer1, "X_y_")("X_y_z")
+ checkExact(completer1, "X_y_z.app")("apply")
+ }
+
+ @Test
+ def previousResultInvocation(): Unit = {
+ val intp = newIMain()
+ intp.interpret("1 + 1")
+
+ val completer = new PresentationCompilerCompleter(intp)
+
+ checkExact(completer, ".toCha")("toChar")
+ }
+
+ @Test
+ def defString(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+
+ // Double Tab on a fully typed selection shows the def string
+ checkExact(completer, "(p: {def a_b_c: Int}) => p.a_b_c")()
+ checkExact(completer, "(p: {def a_b_c: Int}) => p.a_b_c")(EmptyString, "def a_b_c: Int")
+
+ // likewise for an ident
+ checkExact(completer, "(p: {def x_y_z: Int}) => {import p._; x_y_z")()
+ checkExact(completer, "(p: {def x_y_z: Int}) => {import p._; x_y_z")(EmptyString, "def x_y_z: Int")
+
+ // If the first completion only gives one alternative
+ checkExact(completer, "(p: {def x_y_z: Int; def x_y_z(a: String): Int }) => p.x_y")("x_y_z")
+ // ... it is automatically inserted into the buffer. Hitting <TAB> again is triggers the help
+ checkExact(completer, "(p: {def x_y_z: Int; def x_y_z(a: String): Int }) => p.x_y_z")(EmptyString, "def x_y_z(a: String): Int", "def x_y_z: Int")
+
+ checkExact(completer, "(p: {def x_y_z: Int; def x_z_y(a: String): Int }) => p.x_")("x_y_z", "x_z_y")
+ // By contrast, in this case the user had to type "y_z" manually, so no def string printing just yet
+ checkExact(completer, "(p: {def x_y_z: Int; def x_z_y(a: String): Int }) => p.x_y_z")()
+ // Another <TAB>, Okay, time to print.
+ checkExact(completer, "(p: {def x_y_z: Int; def x_z_y(a: String): Int }) => p.x_y_z")(EmptyString, "def x_y_z: Int")
+
+ // The def string reconstructs the source-level modifiers (rather than showing the desugarings of vals),
+ // and performs as-seen-from with respect to the prefix
+ checkExact(completer, "trait T[A]{ lazy val x_y_z: A }; class C extends T[Int] { x_y_z")()
+ checkExact(completer, "trait T[A]{ lazy val x_y_z: A }; class C extends T[Int] { x_y_z")(EmptyString, "lazy val x_y_z: Int")
+
+ checkExact(completer, "trait T[A] { def foo: A }; (t: T[Int]) => t.foo")()
+ checkExact(completer, "trait T[A] { def foo: A }; (t: T[Int]) => t.foo")(EmptyString, "def foo: Int")
+ }
+
+ @Test
+ def treePrint(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ checkExact(completer, " 1.toHexString //print")(EmptyString, "scala.Predef.intWrapper(1).toHexString // : String")
+ }
+
+ @Test
+ def firstCompletionWithNoPrefixHidesUniversalMethodsAndExtensionMethods(): Unit = {
+ val intp = newIMain()
+ val completer = new PresentationCompilerCompleter(intp)
+ checkExact(completer, "class C(val a: Int, val b: Int) { this.")("a", "b")
+ assert(Set("asInstanceOf", "==").diff(completer.complete("class C(val a: Int, val b: Int) { this.").candidates.toSet).isEmpty)
+ checkExact(completer, "case class D(a: Int, b: Int) { this.a")("a", "asInstanceOf")
+ }
+
+ def checkExact(completer: PresentationCompilerCompleter, before: String, after: String = "")(expected: String*): Unit = {
+ assertEquals(expected.toSet, completer.complete(before, after).candidates.toSet)
+ }
+}
diff --git a/test/junit/scala/tools/nsc/symtab/FlagsTest.scala b/test/junit/scala/tools/nsc/symtab/FlagsTest.scala
new file mode 100644
index 0000000000..fc0e8b0f6b
--- /dev/null
+++ b/test/junit/scala/tools/nsc/symtab/FlagsTest.scala
@@ -0,0 +1,89 @@
+package scala.tools.nsc
+package symtab
+
+import org.junit.Assert._
+import scala.tools.testing.AssertUtil._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class FlagsTest {
+ object symbolTable extends SymbolTableForUnitTesting
+ import symbolTable._
+ import Flags._
+
+ def sym = NoSymbol.newTermSymbol(nme.EMPTY)
+
+ def withFlagMask[A](mask: Long)(body: => A): A = enteringPhase(new Phase(NoPhase) {
+ override def flagMask = mask
+ def name = ""
+ def run() = ()
+ })(body)
+
+ def testTimedFlag(flag: Long, test: Symbol => Boolean, enabling: Boolean) = {
+ assertEquals(withFlagMask(InitialFlags)(test(sym.setFlag(flag))), !enabling)
+ assertEquals(withFlagMask(InitialFlags | flag)(test(sym.setFlag(flag))), enabling)
+ }
+
+ def testLate(flag: Long, test: Symbol => Boolean) = testTimedFlag(flag, test, enabling = true)
+ def testNot(flag: Long, test: Symbol => Boolean) = testTimedFlag(flag, test, enabling = false)
+
+ @Test
+ def testTimedFlags(): Unit = {
+ testLate(lateDEFERRED, _.isDeferred)
+ testLate(lateFINAL, _.isFinal)
+ testLate(lateINTERFACE, _.isInterface)
+ testLate(lateMETHOD, _.isMethod)
+ testLate(lateMODULE, _.isModule)
+ testNot(PROTECTED | notPROTECTED, _.isProtected)
+ testNot(OVERRIDE | notOVERRIDE, _.isOverride)
+ testNot(PRIVATE | notPRIVATE, _.isPrivate)
+
+ assertFalse(withFlagMask(AllFlags)(sym.setFlag(PRIVATE | notPRIVATE).isPrivate))
+
+ assertEquals(withFlagMask(InitialFlags)(sym.setFlag(PRIVATE | notPRIVATE).flags & PRIVATE), PRIVATE)
+ assertEquals(withFlagMask(AllFlags)(sym.setFlag(PRIVATE | notPRIVATE).flags & PRIVATE), 0)
+ }
+
+ @Test
+ def normalLateOverlap(): Unit = {
+ // late flags are shifted by LateShift == 47.
+ // however, the first late flag is lateDEFERRED, which is DEFERRED << 47 == (1 << 4) << 47 == 1 << 51
+ // the flags from 1 << 47 to 1 << 50 are not late flags. this is ensured by the LateFlags mask.
+
+ for (i <- 0 to 3) {
+ val f = 1L << i
+ assertEquals(withFlagMask(AllFlags)(sym.setFlag(f << LateShift).flags & f), 0) // not treated as late flag
+ }
+ for (i <- 4 to 8) {
+ val f = 1L << i
+ assertEquals(withFlagMask(AllFlags)(sym.setFlag(f << LateShift).flags & f), f) // treated as late flag
+ }
+ }
+
+ @Test
+ def normalAnti(): Unit = {
+ for (i <- 0 to 2) {
+ val f = 1L << i
+ assertEquals(withFlagMask(AllFlags)(sym.setFlag(f | (f << AntiShift)).flags & f), 0) // negated flags
+ }
+ for (i <- 3 to 7) {
+ val f = 1L << i
+ assertEquals(withFlagMask(AllFlags)(sym.setFlag(f | (f << AntiShift)).flags & f), f) // not negated
+ }
+ }
+
+ @Test
+ def lateAntiCrossCheck(): Unit = {
+ val allButNegatable = AllFlags & ~(PROTECTED | OVERRIDE | PRIVATE)
+ val lateable = 0L | DEFERRED | FINAL | INTERFACE | METHOD | MODULE
+ val lateFlags = lateable << LateShift
+ val allButLateable = AllFlags & ~lateable
+
+ assertEquals(withFlagMask(AllFlags)(sym.setFlag(AllFlags).flags), allButNegatable)
+ assertEquals(withFlagMask(AllFlags)(sym.setFlag(allButLateable).flags), allButNegatable)
+
+ assertEquals(withFlagMask(AllFlags)(sym.setFlag(lateFlags).flags), lateFlags | lateable)
+ }
+}
diff --git a/test/partest b/test/partest
index f396459c6d..8b827f276f 100755
--- a/test/partest
+++ b/test/partest
@@ -112,7 +112,6 @@ if $cygwin; then
JAVAC_CMD=`cygpath --$format "$JAVAC_CMD"`
fi
SCALA_HOME=`cygpath --$format "$SCALA_HOME"`
- PARTEST_CLASSPATH=`cygpath --path --$format "$PARTEST_CLASSPATH"`
fi
# last arg wins, so if JAVA_OPTS already contains -Xmx or -Xms the
diff --git a/test/partest.bat b/test/partest.bat
deleted file mode 100755
index 1806e80888..0000000000
--- a/test/partest.bat
+++ /dev/null
@@ -1,104 +0,0 @@
-@echo off
-
-rem ##########################################################################
-rem # Scala code runner 2.9.1.final
-rem ##########################################################################
-rem # (c) 2002-2013 LAMP/EPFL
-rem #
-rem # This is free software; see the distribution for copying conditions.
-rem # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
-rem # PARTICULAR PURPOSE.
-rem ##########################################################################
-
-rem We adopt the following conventions:
-rem - System/user environment variables start with a letter
-rem - Local batch variables start with an underscore ('_')
-
-if "%OS%"=="Windows_NT" (
- @setlocal
- call :set_home
- set _ARGS=%*
-) else (
- set _SCALA_HOME="%SCALA_HOME%"
- rem The following line tests SCALA_HOME instead of _SCALA_HOME, because
- rem the above change to _SCALA_HOME is not visible within this block.
- if "%SCALA_HOME%"=="" goto error1
- call :set_args
-)
-
-rem We use the value of the JAVACMD environment variable if defined
-set _JAVACMD=%JAVACMD%
-if "%_JAVACMD%"=="" set _JAVACMD=java
-
-rem We use the value of the JAVACCMD environment variable if defined
-set _JAVACCMD=%JAVACCMD%
-if "%_JAVACCMD%"=="" set _JAVACCMD=javac
-
-rem We use the value of the JAVA_OPTS environment variable if defined
-set _JAVA_OPTS=%JAVA_OPTS%
-if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=-Xmx1024M -Xms64M
-
-rem We use the value of the SCALAC_OPTS environment variable if defined
-set _SCALAC_OPTS=%SCALAC_OPTS%
-if "%_SCALAC_OPTS%"=="" set _SCALAC_OPTS=-deprecation
-
-set _EXTENSION_CLASSPATH=
-if "%_EXTENSION_CLASSPATH%"=="" (
- if exist "%_SCALA_HOME%\lib\scala-partest.jar" (
- for %%f in ("%_SCALA_HOME%\lib\*") do call :add_cpath "%%f"
- if "%OS%"=="Windows_NT" (
- for /d %%f in ("%_SCALA_HOME%\lib\*") do call :add_cpath "%%f"
- )
- ) else if exist "%_SCALA_HOME%\build\pack\lib\scala-partest.jar" (
- for %%f in ("%_SCALA_HOME%\build\pack\lib\*") do call :add_cpath "%%f"
- if "%OS%"=="Windows_NT" (
- for /d %%f in ("%_SCALA_HOME%\build\pack\lib\*") do call :add_cpath "%%f"
- )
- )
-)
-
-set _PROPS=-Dscala.home="%_SCALA_HOME%" -Dpartest.javacmd="%_JAVACMD%" -Dpartest.java_options="%_JAVA_OPTS%" -Dpartest.scalac_options="%_SCALAC_OPTS%" -Dpartest.javac_cmd="%_JAVACCMD%"
-
-rem echo %_JAVACMD% %_JAVA_OPTS% %_PROPS% -cp "%_EXTENSION_CLASSPATH%" scala.tools.partest.nest.NestRunner %_ARGS%
-%_JAVACMD% %_JAVA_OPTS% %_PROPS% -cp "%_EXTENSION_CLASSPATH%" scala.tools.partest.nest.NestRunner %_ARGS%
-goto end
-
-rem ##########################################################################
-rem # subroutines
-
-:add_cpath
- if "%_EXTENSION_CLASSPATH%"=="" (
- set _EXTENSION_CLASSPATH=%~1
- ) else (
- set _EXTENSION_CLASSPATH=%_EXTENSION_CLASSPATH%;%~1
- )
-goto :eof
-
-rem Variable "%~dps0" works on WinXP SP2 or newer
-rem (see http://support.microsoft.com/?kbid=833431)
-rem set _SCALA_HOME=%~dps0..
-:set_home
- set _BIN_DIR=
- for %%i in (%~sf0) do set _BIN_DIR=%_BIN_DIR%%%~dpsi
- set _SCALA_HOME=%_BIN_DIR%..
-goto :eof
-
-:set_args
- set _ARGS=
- :loop
- rem Argument %1 may contain quotes so we use parentheses here
- if (%1)==() goto :eof
- set _ARGS=%_ARGS% %1
- shift
- goto loop
-
-rem ##########################################################################
-rem # errors
-
-:error1
-echo ERROR: environment variable SCALA_HOME is undefined. It should point to your installation directory.
-goto end
-
-:end
-if "%OS%"=="Windows_NT" @endlocal
-exit /b %errorlevel%
diff --git a/test/pending/run/t3609.scala b/test/pending/run/t3609.scala
index eb25afd667..eb25afd667 100755..100644
--- a/test/pending/run/t3609.scala
+++ b/test/pending/run/t3609.scala
diff --git a/test/scaladoc/filters b/test/scaladoc/filters
index 51a7507848..e91ca0eb36 100644
--- a/test/scaladoc/filters
+++ b/test/scaladoc/filters
@@ -1,6 +1,7 @@
#
#Java HotSpot(TM) 64-Bit Server VM warning: Failed to reserve shared memory (errno = 28).
Java HotSpot\(TM\) .* warning:
+OpenJDK .* warning:
# Hotspot receiving VM options through the $_JAVA_OPTIONS
# env variable outputs them on stderr
Picked up _JAVA_OPTIONS:
diff --git a/test/scaladoc/resources/doc-root/AnyRef.scala b/test/scaladoc/resources/doc-root/AnyRef.scala
index 362fbcf0f5..7cdc3d1ada 100644
--- a/test/scaladoc/resources/doc-root/AnyRef.scala
+++ b/test/scaladoc/resources/doc-root/AnyRef.scala
@@ -45,7 +45,7 @@ trait AnyRef extends Any {
*/
def synchronized[T](body: => T): T
- /** Tests whether the argument (`arg0`) is a reference to the receiver object (`this`).
+ /** Tests whether the argument (`that`) is a reference to the receiver object (`this`).
*
* The `eq` method implements an [[http://en.wikipedia.org/wiki/Equivalence_relation equivalence relation]] on
* non-null instances of `AnyRef`, and has three additional properties:
@@ -73,7 +73,7 @@ trait AnyRef extends Any {
/** The expression `x == that` is equivalent to `if (x eq null) that eq null else x.equals(that)`.
*
- * @param arg0 the object to compare against this object for equality.
+ * @param that the object to compare against this object for equality.
* @return `true` if the receiver object is equivalent to the argument; `false` otherwise.
*/
final def ==(that: AnyRef): Boolean =
diff --git a/test/scaladoc/run/SI-191.check b/test/scaladoc/run/SI-191.check
index 3925a0d464..3925a0d464 100755..100644
--- a/test/scaladoc/run/SI-191.check
+++ b/test/scaladoc/run/SI-191.check
diff --git a/test/scaladoc/run/SI-191.scala b/test/scaladoc/run/SI-191.scala
index 29b1e7dd29..29b1e7dd29 100755..100644
--- a/test/scaladoc/run/SI-191.scala
+++ b/test/scaladoc/run/SI-191.scala
diff --git a/test/scaladoc/run/SI-7367.check b/test/scaladoc/run/SI-7367.check
index 3925a0d464..3925a0d464 100755..100644
--- a/test/scaladoc/run/SI-7367.check
+++ b/test/scaladoc/run/SI-7367.check
diff --git a/test/scaladoc/run/SI-7367.scala b/test/scaladoc/run/SI-7367.scala
index 6e5a317932..6e5a317932 100755..100644
--- a/test/scaladoc/run/SI-7367.scala
+++ b/test/scaladoc/run/SI-7367.scala
diff --git a/test/scaladoc/run/SI-8479.scala b/test/scaladoc/run/SI-8479.scala
index 3c91395025..3c91395025 100755..100644
--- a/test/scaladoc/run/SI-8479.scala
+++ b/test/scaladoc/run/SI-8479.scala
diff --git a/test/script-tests/README b/test/script-tests/README
index 7b3291c407..7b3291c407 100755..100644
--- a/test/script-tests/README
+++ b/test/script-tests/README
diff --git a/versions.properties b/versions.properties
index 529365c9f9..2253921940 100644
--- a/versions.properties
+++ b/versions.properties
@@ -5,7 +5,7 @@
# also add them to the update.versions mechanism in build.xml,
# which is used by the release script scripts/jobs/integrate/bootstrap
-# The scala version used for boostrapping. This has no impact on the final classfiles:
+# The scala version used for bootstrapping. This has no impact on the final classfiles:
# there are two stages (locker and quick), so compiler and library are always built
# with themselves. Stability is ensured by building a third stage (strap).
starr.version=2.11.7
@@ -33,10 +33,10 @@ scala-swing.version.number=1.0.2
akka-actor.version.number=2.3.10
actors-migration.version.number=1.1.0
jline.version=2.12.1
-scala-asm.version=5.0.4-scala-2
+scala-asm.version=5.0.4-scala-3
# external modules, used internally (not shipped)
-partest.version.number=1.0.7
+partest.version.number=1.0.9
scalacheck.version.number=1.11.6
# TODO: modularize the compiler