summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVojin Jovanovic <vojin.jovanovic@epfl.ch>2012-01-25 15:24:18 +0100
committerVojin Jovanovic <vojin.jovanovic@epfl.ch>2012-01-25 15:24:18 +0100
commitf814d40ea917592f78d2e8ca4c78f34ce4b5f297 (patch)
treecafac6a0d757419132fd75ab788f8163a619780b
parent85daadef89a9ed5c3901a5822221366ee6746d49 (diff)
parentde2b0c68785afc0f801fbe8d2750366e90c9fa70 (diff)
downloadscala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.tar.gz
scala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.tar.bz2
scala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.zip
Merge branch 'master' into execution-context
-rw-r--r--build.xml4
-rw-r--r--docs/examples/swing/ButtonApp.scala (renamed from src/swing/scala/swing/test/ButtonApp.scala)3
-rw-r--r--docs/examples/swing/CelsiusConverter.scala (renamed from src/swing/scala/swing/test/CelsiusConverter.scala)3
-rw-r--r--docs/examples/swing/CelsiusConverter2.scala (renamed from src/swing/scala/swing/test/CelsiusConverter2.scala)3
-rw-r--r--docs/examples/swing/ComboBoxes.scala (renamed from src/swing/scala/swing/test/ComboBoxes.scala)3
-rw-r--r--docs/examples/swing/CountButton.scala (renamed from src/swing/scala/swing/test/CountButton.scala)3
-rw-r--r--docs/examples/swing/Dialogs.scala (renamed from src/swing/scala/swing/test/Dialogs.scala)3
-rw-r--r--docs/examples/swing/GridBagDemo.scala (renamed from src/swing/scala/swing/test/GridBagDemo.scala)3
-rw-r--r--docs/examples/swing/HelloWorld.scala (renamed from src/swing/scala/swing/test/HelloWorld.scala)5
-rw-r--r--docs/examples/swing/LabelTest.scala (renamed from src/swing/scala/swing/test/LabelTest.scala)3
-rw-r--r--docs/examples/swing/LinePainting.scala (renamed from src/swing/scala/swing/test/LinePainting.scala)3
-rw-r--r--docs/examples/swing/ListViewDemo.scala (renamed from src/swing/scala/swing/test/ListViewDemo.scala)3
-rw-r--r--docs/examples/swing/SimpleApplet.scala (renamed from src/swing/scala/swing/test/SimpleApplet.scala)3
-rw-r--r--docs/examples/swing/SwingApp.scala (renamed from src/swing/scala/swing/test/SwingApp.scala)3
-rw-r--r--docs/examples/swing/TableSelection.scala (renamed from src/swing/scala/swing/test/TableSelection.scala)3
-rw-r--r--docs/examples/swing/UIDemo.scala (renamed from src/swing/scala/swing/test/UIDemo.scala)5
-rw-r--r--docs/examples/swing/images/banana.jpg (renamed from src/swing/scala/swing/test/images/banana.jpg)bin6000 -> 6000 bytes
-rw-r--r--docs/examples/swing/images/margarita1.jpg (renamed from src/swing/scala/swing/test/images/margarita1.jpg)bin14770 -> 14770 bytes
-rw-r--r--docs/examples/swing/images/margarita2.jpg (renamed from src/swing/scala/swing/test/images/margarita2.jpg)bin17310 -> 17310 bytes
-rw-r--r--docs/examples/swing/images/rose.jpg (renamed from src/swing/scala/swing/test/images/rose.jpg)bin13808 -> 13808 bytes
-rw-r--r--project/Build.scala12
-rw-r--r--project/Partest.scala2
-rwxr-xr-xpush-binary-libs.sh5
-rw-r--r--src/compiler/scala/reflect/internal/AnnotationInfos.scala6
-rw-r--r--src/compiler/scala/reflect/internal/ClassfileConstants.scala80
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala132
-rw-r--r--src/compiler/scala/reflect/internal/HasFlags.scala3
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala24
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala33
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala6
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala56
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala11
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala449
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala10
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala672
-rw-r--r--src/compiler/scala/reflect/internal/pickling/UnPickler.scala6
-rw-r--r--src/compiler/scala/reflect/internal/transform/Erasure.scala4
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala27
-rw-r--r--src/compiler/scala/reflect/runtime/Loaders.scala4
-rw-r--r--src/compiler/scala/reflect/runtime/Mirror.scala15
-rw-r--r--src/compiler/scala/reflect/runtime/ToolBoxes.scala15
-rw-r--r--src/compiler/scala/reflect/runtime/TreeBuildUtil.scala2
-rw-r--r--src/compiler/scala/tools/ant/Scalac.scala2
-rw-r--r--src/compiler/scala/tools/ant/templates/tool-windows.tmpl4
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala10
-rw-r--r--src/compiler/scala/tools/nsc/MacroContext.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala41
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala79
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala245
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Tokens.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala44
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala9
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala74
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala190
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala8
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala4
-rw-r--r--src/compiler/scala/tools/nsc/io/MsilFile.scala4
-rw-r--r--src/compiler/scala/tools/nsc/io/NoAbstractFile.scala30
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala10
-rw-r--r--src/compiler/scala/tools/nsc/matching/Matrix.scala3
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala2
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala15
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala6
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala45
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala39
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala79
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala33
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala53
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala56
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala73
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala37
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala43
-rw-r--r--src/compiler/scala/tools/nsc/transform/SampleTransform.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala244
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala52
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala29
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala66
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala69
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala136
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala40
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala98
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala43
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala64
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala99
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala23
-rw-r--r--src/compiler/scala/tools/nsc/util/Statistics.scala4
-rw-r--r--src/compiler/scala/tools/util/EditDistance.scala4
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala22
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala16
-rw-r--r--src/library/scala/Function1.scala10
-rw-r--r--src/library/scala/PartialFunction.scala30
-rw-r--r--src/library/scala/Predef.scala2
-rw-r--r--src/library/scala/StringContext.scala191
-rw-r--r--src/library/scala/collection/GenTraversableLike.scala23
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala2
-rwxr-xr-xsrc/library/scala/collection/JavaConverters.scala5
-rw-r--r--src/library/scala/collection/SeqLike.scala2
-rw-r--r--src/library/scala/collection/TraversableLike.scala5
-rw-r--r--src/library/scala/collection/TraversableOnce.scala2
-rw-r--r--src/library/scala/collection/TraversableProxyLike.scala2
-rw-r--r--src/library/scala/collection/generic/GenericTraversableTemplate.scala14
-rw-r--r--src/library/scala/collection/generic/MutableSortedSetFactory.scala33
-rw-r--r--src/library/scala/collection/generic/TraversableForwarder.scala2
-rw-r--r--src/library/scala/collection/immutable/IndexedSeq.scala2
-rw-r--r--src/library/scala/collection/immutable/List.scala21
-rw-r--r--src/library/scala/collection/immutable/Range.scala36
-rw-r--r--src/library/scala/collection/immutable/Stream.scala10
-rw-r--r--src/library/scala/collection/interfaces/TraversableOnceMethods.scala2
-rw-r--r--src/library/scala/collection/mutable/AVLTree.scala206
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala46
-rw-r--r--src/library/scala/collection/mutable/SortedSet.scala49
-rw-r--r--src/library/scala/collection/mutable/TreeSet.scala123
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala2
-rw-r--r--src/library/scala/io/Codec.scala3
-rw-r--r--src/library/scala/reflect/Manifest.scala2
-rw-r--r--src/library/scala/reflect/ReflectionUtils.scala12
-rw-r--r--src/library/scala/reflect/api/Mirror.scala6
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala4
-rw-r--r--src/library/scala/reflect/api/TreePrinters.scala41
-rw-r--r--src/library/scala/reflect/macro/Context.scala (renamed from src/library/scala/reflect/api/MacroContext.scala)6
-rw-r--r--src/library/scala/reflect/package.scala2
-rw-r--r--src/library/scala/xml/include/sax/Main.scala2
-rw-r--r--src/partest/scala/tools/partest/PartestTask.scala38
-rw-r--r--src/partest/scala/tools/partest/nest/AntRunner.scala2
-rw-r--r--src/partest/scala/tools/partest/nest/CompileManager.scala1
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleFileManager.scala4
-rw-r--r--src/partest/scala/tools/partest/nest/DirectRunner.scala11
-rw-r--r--src/partest/scala/tools/partest/nest/FileManager.scala2
-rw-r--r--src/partest/scala/tools/partest/nest/PathSettings.scala7
-rw-r--r--src/partest/scala/tools/partest/nest/ReflectiveRunner.scala15
-rw-r--r--src/partest/scala/tools/partest/nest/SBTRunner.scala32
-rw-r--r--src/partest/scala/tools/partest/nest/TestFile.scala5
-rw-r--r--src/partest/scala/tools/partest/nest/Worker.scala2
-rw-r--r--test/benchmarking/AVL-insert-random.scala67
-rw-r--r--test/benchmarking/AVL-insert.scala67
-rw-r--r--test/files/continuations-neg/t2949.check2
-rw-r--r--test/files/jvm/serialization.check8
-rw-r--r--test/files/jvm/serialization.scala7
-rw-r--r--test/files/macros/Printf.scala39
-rw-r--r--test/files/macros/Test.scala8
-rw-r--r--test/files/macros/macros_v0001.bat40
-rw-r--r--test/files/macros/macros_v0001.sh30
-rw-r--r--test/files/neg/cyclics-import.check15
-rw-r--r--test/files/neg/cyclics-import.scala17
-rw-r--r--test/files/neg/main1.check20
-rw-r--r--test/files/neg/nested-fn-print.check20
-rw-r--r--test/files/neg/nested-fn-print.scala11
-rw-r--r--test/files/neg/specification-scopes.check12
-rw-r--r--test/files/neg/specification-scopes/P_1.scala6
-rw-r--r--test/files/neg/specification-scopes/P_2.scala21
-rw-r--r--test/files/neg/t0003.check2
-rw-r--r--test/files/neg/t1845.check8
-rw-r--r--test/files/neg/t2870.check8
-rw-r--r--test/files/neg/t3240.check5
-rw-r--r--test/files/neg/t4271.check10
-rw-r--r--test/files/neg/t4271.scala12
-rw-r--r--test/files/neg/t4749.check28
-rw-r--r--test/files/neg/t4749.flags1
-rw-r--r--test/files/neg/t4749.scala44
-rw-r--r--test/files/neg/t692.check7
-rw-r--r--test/files/pos/macros.flags2
-rw-r--r--test/files/pos/macros.scala6
-rw-r--r--test/files/pos/package-implicit/ActorRef.scala7
-rw-r--r--test/files/pos/package-implicit/DataFlow.scala7
-rw-r--r--test/files/pos/package-implicit/package.scala6
-rw-r--r--test/files/pos/raw-map/J_1.java4
-rw-r--r--test/files/pos/raw-map/S_2.scala6
-rw-r--r--test/files/pos/t3999/a_1.scala9
-rw-r--r--test/files/pos/t3999/b_2.scala7
-rw-r--r--test/files/pos/t4176.scala6
-rw-r--r--test/files/pos/t4869.scala8
-rw-r--r--test/files/pos/t5120.scala26
-rw-r--r--test/files/presentation/callcc-interpreter.check2
-rw-r--r--test/files/presentation/ide-bug-1000531.check2
-rw-r--r--test/files/run/Predef.readLine.check3
-rw-r--r--test/files/run/Predef.readLine.scala10
-rw-r--r--test/files/run/interpolation.check26
-rw-r--r--test/files/run/interpolation.flags (renamed from test/files/run/stringInterpolation.flags)0
-rw-r--r--test/files/run/interpolation.scala26
-rw-r--r--test/files/run/interpolationArgs.check2
-rw-r--r--test/files/run/interpolationArgs.flags1
-rw-r--r--test/files/run/interpolationArgs.scala5
-rw-r--r--test/files/run/macro-range.check9
-rw-r--r--test/files/run/macro-range.flags1
-rw-r--r--test/files/run/macro-range/macro_range_1.scala99
-rw-r--r--test/files/run/macro-range/macro_range_2.scala99
-rw-r--r--test/files/run/range-unit.check4178
-rw-r--r--test/files/run/range-unit.scala55
-rw-r--r--test/files/run/si4147.scala36
-rw-r--r--test/files/run/si5262.check2
-rw-r--r--test/files/run/si5262.scala26
-rw-r--r--test/files/run/si5374.check3
-rw-r--r--test/files/run/si5374.scala42
-rw-r--r--test/files/run/stringInterpolation.check2
-rw-r--r--test/files/run/stringInterpolation.scala7
-rw-r--r--test/files/run/t1987.check16
-rw-r--r--test/files/run/t1987.flags1
-rw-r--r--test/files/run/t1987.scala62
-rw-r--r--test/files/run/t4835.check7
-rw-r--r--test/files/run/t4835.scala38
-rw-r--r--test/files/run/t5072.check14
-rw-r--r--test/files/run/t5072.scala8
-rw-r--r--test/files/run/t5377.check18
-rw-r--r--test/files/run/t5377.scala47
-rw-r--r--test/files/run/t5387.scala15
-rw-r--r--test/files/run/trait-renaming.check2
-rw-r--r--test/files/run/trait-renaming/A_1.scala15
-rw-r--r--test/files/run/trait-renaming/B_2.scala5
-rw-r--r--test/files/run/xml-attribute.check12
-rw-r--r--test/files/run/xml-attribute.scala24
-rw-r--r--test/files/scalacheck/si4147.scala67
-rw-r--r--test/files/specialized/spec-hlists.check2
-rw-r--r--test/files/specialized/spec-hlists.scala29
-rw-r--r--test/scaladoc/scala/html/HtmlFactoryTest.scala6
-rwxr-xr-xtools/binary-repo-lib.sh12
-rwxr-xr-xtools/epfl-publish18
232 files changed, 8738 insertions, 1921 deletions
diff --git a/build.xml b/build.xml
index 592036c67b..39e47471c6 100644
--- a/build.xml
+++ b/build.xml
@@ -941,9 +941,6 @@ PACKED QUICK BUILD (PACK)
<fileset dir="${build-quick.dir}/classes/library">
<include name="scala/swing/**"/>
</fileset>
- <fileset dir="${src.dir}/swing">
- <include name="scala/swing/test/images/**"/>
- </fileset>
</jar>
</target>
@@ -1543,7 +1540,6 @@ DOCUMENTATION
<exclude name="runtime/*$.scala"/>
<exclude name="runtime/ScalaRunTime.scala"/>
<exclude name="runtime/StringAdd.scala"/>
- <exclude name="scala/swing/test/**"/>
</scaladoc>
<touch file="${build-docs.dir}/library.complete" verbose="no"/>
<stopwatch name="docs.lib.timer" action="total"/>
diff --git a/src/swing/scala/swing/test/ButtonApp.scala b/docs/examples/swing/ButtonApp.scala
index dcf567d365..96799b24f2 100644
--- a/src/swing/scala/swing/test/ButtonApp.scala
+++ b/docs/examples/swing/ButtonApp.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import java.awt.Dimension
diff --git a/src/swing/scala/swing/test/CelsiusConverter.scala b/docs/examples/swing/CelsiusConverter.scala
index 4ead632d7a..b4a62fb366 100644
--- a/src/swing/scala/swing/test/CelsiusConverter.scala
+++ b/docs/examples/swing/CelsiusConverter.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import swing._
import event._
diff --git a/src/swing/scala/swing/test/CelsiusConverter2.scala b/docs/examples/swing/CelsiusConverter2.scala
index 5ce1b157fe..3630d61b61 100644
--- a/src/swing/scala/swing/test/CelsiusConverter2.scala
+++ b/docs/examples/swing/CelsiusConverter2.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import swing._
import event._
diff --git a/src/swing/scala/swing/test/ComboBoxes.scala b/docs/examples/swing/ComboBoxes.scala
index cf1a70d97b..c6ee19013a 100644
--- a/src/swing/scala/swing/test/ComboBoxes.scala
+++ b/docs/examples/swing/ComboBoxes.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import swing._
import event._
diff --git a/src/swing/scala/swing/test/CountButton.scala b/docs/examples/swing/CountButton.scala
index 373db785ba..5fb14681d6 100644
--- a/src/swing/scala/swing/test/CountButton.scala
+++ b/docs/examples/swing/CountButton.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import scala.swing._
import scala.swing.event._
diff --git a/src/swing/scala/swing/test/Dialogs.scala b/docs/examples/swing/Dialogs.scala
index 14fa2febf2..0b4ac258cf 100644
--- a/src/swing/scala/swing/test/Dialogs.scala
+++ b/docs/examples/swing/Dialogs.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import swing._
import swing.event._
diff --git a/src/swing/scala/swing/test/GridBagDemo.scala b/docs/examples/swing/GridBagDemo.scala
index ebb538f1c0..60cfc13acb 100644
--- a/src/swing/scala/swing/test/GridBagDemo.scala
+++ b/docs/examples/swing/GridBagDemo.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import swing._
import swing.event._
diff --git a/src/swing/scala/swing/test/HelloWorld.scala b/docs/examples/swing/HelloWorld.scala
index 6014a14b2d..e89bfedd8a 100644
--- a/src/swing/scala/swing/test/HelloWorld.scala
+++ b/docs/examples/swing/HelloWorld.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import swing._
@@ -11,4 +10,4 @@ object HelloWorld extends SimpleSwingApplication {
title = "Hello, World!"
contents = new Button("Click Me!")
}
-} \ No newline at end of file
+}
diff --git a/src/swing/scala/swing/test/LabelTest.scala b/docs/examples/swing/LabelTest.scala
index 47eedb84ac..edd7a14634 100644
--- a/src/swing/scala/swing/test/LabelTest.scala
+++ b/docs/examples/swing/LabelTest.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import scala.swing._
import scala.swing.event._
diff --git a/src/swing/scala/swing/test/LinePainting.scala b/docs/examples/swing/LinePainting.scala
index 8588665ddc..f72f8701ed 100644
--- a/src/swing/scala/swing/test/LinePainting.scala
+++ b/docs/examples/swing/LinePainting.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import scala.swing.Swing._
import scala.swing.{MainFrame, Panel}
diff --git a/src/swing/scala/swing/test/ListViewDemo.scala b/docs/examples/swing/ListViewDemo.scala
index 2b8c8c0719..5630f2871d 100644
--- a/src/swing/scala/swing/test/ListViewDemo.scala
+++ b/docs/examples/swing/ListViewDemo.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
object ListViewDemo extends SimpleSwingApplication {
def top = new MainFrame {
diff --git a/src/swing/scala/swing/test/SimpleApplet.scala b/docs/examples/swing/SimpleApplet.scala
index d5f17f8a40..502de537a3 100644
--- a/src/swing/scala/swing/test/SimpleApplet.scala
+++ b/docs/examples/swing/SimpleApplet.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import event._
diff --git a/src/swing/scala/swing/test/SwingApp.scala b/docs/examples/swing/SwingApp.scala
index b47d778d3a..b3fe7447ef 100644
--- a/src/swing/scala/swing/test/SwingApp.scala
+++ b/docs/examples/swing/SwingApp.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import swing._
import swing.event._
diff --git a/src/swing/scala/swing/test/TableSelection.scala b/docs/examples/swing/TableSelection.scala
index bbfef80277..8c8ea4ffcc 100644
--- a/src/swing/scala/swing/test/TableSelection.scala
+++ b/docs/examples/swing/TableSelection.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import java.awt.Dimension
import swing.event._
diff --git a/src/swing/scala/swing/test/UIDemo.scala b/docs/examples/swing/UIDemo.scala
index 9207c82948..6d77c049e0 100644
--- a/src/swing/scala/swing/test/UIDemo.scala
+++ b/docs/examples/swing/UIDemo.scala
@@ -1,5 +1,4 @@
-package scala.swing
-package test
+package examples.swing
import swing._
import event._
@@ -145,4 +144,4 @@ object UIDemo extends SimpleSwingApplication {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/swing/scala/swing/test/images/banana.jpg b/docs/examples/swing/images/banana.jpg
index 62267a4325..62267a4325 100644
--- a/src/swing/scala/swing/test/images/banana.jpg
+++ b/docs/examples/swing/images/banana.jpg
Binary files differ
diff --git a/src/swing/scala/swing/test/images/margarita1.jpg b/docs/examples/swing/images/margarita1.jpg
index d315f7c79f..d315f7c79f 100644
--- a/src/swing/scala/swing/test/images/margarita1.jpg
+++ b/docs/examples/swing/images/margarita1.jpg
Binary files differ
diff --git a/src/swing/scala/swing/test/images/margarita2.jpg b/docs/examples/swing/images/margarita2.jpg
index c8b076e5f9..c8b076e5f9 100644
--- a/src/swing/scala/swing/test/images/margarita2.jpg
+++ b/docs/examples/swing/images/margarita2.jpg
Binary files differ
diff --git a/src/swing/scala/swing/test/images/rose.jpg b/docs/examples/swing/images/rose.jpg
index d4a2b58062..d4a2b58062 100644
--- a/src/swing/scala/swing/test/images/rose.jpg
+++ b/docs/examples/swing/images/rose.jpg
Binary files differ
diff --git a/project/Build.scala b/project/Build.scala
index abab775666..5b09e053f0 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -383,12 +383,12 @@ object ScalaBuild extends Build with Layers {
Seq(dir / "src" / "library" / "scala", dir / "src" / "actors", dir / "src" / "swing", dir / "src" / "continuations" / "library")
},
compile := inc.Analysis.Empty,
- scaladocOptions in Compile in doc <++= (baseDirectory) map (bd =>
- Seq("-sourcepath", (bd / "src" / "library").getAbsolutePath,
- "-doc-no-compile", (bd / "src" / "library-aux").getAbsolutePath,
- "-doc-source-url", """https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/€{FILE_PATH}.scala#L1""",
- "-doc-root-content", (bd / "compiler/scala/tools/nsc/doc/html/resource/lib/rootdoc.txt").getAbsolutePath
- )),
+ // scaladocOptions in Compile <++= (baseDirectory) map (bd =>
+ // Seq("-sourcepath", (bd / "src" / "library").getAbsolutePath,
+ // "-doc-no-compile", (bd / "src" / "library-aux").getAbsolutePath,
+ // "-doc-source-url", """https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/€{FILE_PATH}.scala#L1""",
+ // "-doc-root-content", (bd / "compiler/scala/tools/nsc/doc/html/resource/lib/rootdoc.txt").getAbsolutePath
+ // )),
classpathOptions in Compile := ClasspathOptions.manual
)
lazy val documentation = (
diff --git a/project/Partest.scala b/project/Partest.scala
index 6fc5e11958..ad8047fa00 100644
--- a/project/Partest.scala
+++ b/project/Partest.scala
@@ -115,7 +115,7 @@ object partest {
}
}
- def partestRunnerTask(classpath: ScopedTask[Classpath], javacOptions: ScopedSetting[Seq[String]]): Project.Initialize[Task[PartestRunner]] =
+ def partestRunnerTask(classpath: ScopedTask[Classpath], javacOptions: ScopedTask[Seq[String]]): Project.Initialize[Task[PartestRunner]] =
(classpath, javacOptions) map ((cp, opts) => new PartestRunner(Build.data(cp), opts mkString " "))
}
diff --git a/push-binary-libs.sh b/push-binary-libs.sh
index 7592fc767a..0a1c62a1db 100755
--- a/push-binary-libs.sh
+++ b/push-binary-libs.sh
@@ -4,5 +4,10 @@
. $(dirname $0)/tools/binary-repo-lib.sh
+if test $# -lt 2; then
+ echo "Usage: $0 <username> <password>"
+ exit 1
+fi
+
# TODO - Argument parsing for username/password.
pushJarFiles $(pwd) $1 $2
diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
index 665e33e783..255e69c3c6 100644
--- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
@@ -230,10 +230,8 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
def refsSymbol(sym: Symbol) = hasArgWhich(_.symbol == sym)
/** Change all ident's with Symbol "from" to instead use symbol "to" */
- def substIdentSyms(from: Symbol, to: Symbol) = {
- val subs = new TreeSymSubstituter(List(from), List(to))
- AnnotationInfo(atp, args.map(subs(_)), assocs).setPos(pos)
- }
+ def substIdentSyms(from: Symbol, to: Symbol) =
+ AnnotationInfo(atp, args map (_ substTreeSyms (from -> to)), assocs) setPos pos
def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
diff --git a/src/compiler/scala/reflect/internal/ClassfileConstants.scala b/src/compiler/scala/reflect/internal/ClassfileConstants.scala
index 136350ebbb..f1bf41ede9 100644
--- a/src/compiler/scala/reflect/internal/ClassfileConstants.scala
+++ b/src/compiler/scala/reflect/internal/ClassfileConstants.scala
@@ -6,6 +6,8 @@
package scala.reflect
package internal
+import annotation.switch
+
object ClassfileConstants {
final val JAVA_MAGIC = 0xCAFEBABE
@@ -326,28 +328,62 @@ object ClassfileConstants {
final val impdep1 = 0xfe
final val impdep2 = 0xff
- def toScalaFlags(flags: Int, isClass: Boolean = false, isField: Boolean = false): Long = {
+ abstract class FlagTranslation {
import Flags._
- var res = 0l
- if ((flags & JAVA_ACC_PRIVATE) != 0)
- res = res | PRIVATE
- else if ((flags & JAVA_ACC_PROTECTED) != 0)
- res = res | PROTECTED
- if ((flags & JAVA_ACC_ABSTRACT) != 0 && (flags & JAVA_ACC_ANNOTATION) == 0)
- res = res | DEFERRED
- if ((flags & JAVA_ACC_FINAL) != 0)
- res = res | FINAL
- if (((flags & JAVA_ACC_INTERFACE) != 0) &&
- ((flags & JAVA_ACC_ANNOTATION) == 0))
- res = res | TRAIT | INTERFACE | ABSTRACT
- if ((flags & JAVA_ACC_SYNTHETIC) != 0)
- res = res | SYNTHETIC
- if ((flags & JAVA_ACC_STATIC) != 0)
- res = res | STATIC
- if (isClass && ((res & DEFERRED) != 0L))
- res = res & ~DEFERRED | ABSTRACT
- if (isField && (res & FINAL) == 0L)
- res = res | MUTABLE
- res | JAVA
+
+ private var isAnnotation = false
+ private var isClass = false
+ private def initFields(flags: Int) = {
+ isAnnotation = (flags & JAVA_ACC_ANNOTATION) != 0
+ isClass = false
+ }
+ private def translateFlag(jflag: Int): Long = (jflag: @switch) match {
+ case JAVA_ACC_PRIVATE => PRIVATE
+ case JAVA_ACC_PROTECTED => PROTECTED
+ case JAVA_ACC_FINAL => FINAL
+ case JAVA_ACC_SYNTHETIC => SYNTHETIC
+ 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 _ => 0L
+ }
+ private def translateFlags(jflags: Int, baseFlags: Long): Long = {
+ var res: Long = JAVA | baseFlags
+ /** fast, elegant, maintainable, pick any two... */
+ res |= translateFlag(jflags & JAVA_ACC_PRIVATE)
+ res |= translateFlag(jflags & JAVA_ACC_PROTECTED)
+ res |= translateFlag(jflags & JAVA_ACC_FINAL)
+ res |= translateFlag(jflags & JAVA_ACC_SYNTHETIC)
+ res |= translateFlag(jflags & JAVA_ACC_STATIC)
+ res |= translateFlag(jflags & JAVA_ACC_ABSTRACT)
+ res |= translateFlag(jflags & JAVA_ACC_INTERFACE)
+ res
+ }
+
+ def classFlags(jflags: Int): Long = {
+ initFields(jflags)
+ isClass = true
+ translateFlags(jflags, 0)
+ }
+ def fieldFlags(jflags: Int): Long = {
+ initFields(jflags)
+ translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0)
+ }
+ def methodFlags(jflags: Int): Long = {
+ initFields(jflags)
+ translateFlags(jflags, 0)
+ }
}
+ object FlagTranslation extends FlagTranslation { }
+
+ def toScalaMethodFlags(flags: Int): Long = FlagTranslation methodFlags flags
+ def toScalaClassFlags(flags: Int): Long = FlagTranslation classFlags flags
+ def toScalaFieldFlags(flags: Int): Long = FlagTranslation fieldFlags flags
+
+ @deprecated("Use another method in this object", "2.10.0")
+ def toScalaFlags(flags: Int, isClass: Boolean = false, isField: Boolean = false): Long = (
+ if (isClass) toScalaClassFlags(flags)
+ else if (isField) toScalaFieldFlags(flags)
+ else toScalaMethodFlags(flags)
+ )
}
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index d3af8e2623..02d6737bdb 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -14,13 +14,28 @@ import PartialFunction._
trait Definitions extends reflect.api.StandardDefinitions {
self: SymbolTable =>
+ private def newClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): Symbol = {
+ val clazz = owner.newClassSymbol(name, NoPosition, flags)
+ clazz setInfoAndEnter ClassInfoType(parents, new Scope, clazz)
+ }
+ private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol = {
+ val msym = owner.newMethod(name.encode, NoPosition, flags)
+ val params = msym.newSyntheticValueParams(formals)
+ msym setInfoAndEnter MethodType(params, restpe)
+ }
+
// the scala value classes
trait ValueClassDefinitions {
self: definitions.type =>
private[Definitions] def valueCache(name: Name) = {
- if (name.isTypeName) ScalaPackageClass.info member name
- else ScalaPackageClass.info member name suchThat (_ hasFlag MODULE)
+ val res = (
+ if (name.isTypeName) ScalaPackageClass.info member name
+ else ScalaPackageClass.info member name suchThat (_ hasFlag MODULE)
+ )
+ if (res eq NoSymbol)
+ abort("Could not find value classes! This is a catastrophic failure. scala " + scala.util.Properties.versionString)
+ else res
}
private[Definitions] def valueModuleMethod(className: Name, methodName: Name): Symbol = {
valueCache(className.toTermName).moduleClass.tpe member methodName
@@ -66,13 +81,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val boxMethod = classesMap(x => valueModuleMethod(x, nme.box))
lazy val unboxMethod = classesMap(x => valueModuleMethod(x, nme.unbox))
- private def newClass(owner: Symbol, name: TypeName, parents: List[Type]): Symbol = {
- val clazz = owner.newClass(NoPosition, name)
- clazz.setInfo(ClassInfoType(parents, new Scope, clazz))
- owner.info.decls.enter(clazz)
- clazz
- }
-
def isNumericSubClass(sub: Symbol, sup: Symbol) = (
(numericWeight contains sub)
&& (numericWeight contains sup)
@@ -124,21 +132,21 @@ trait Definitions extends reflect.api.StandardDefinitions {
// This is the package _root_. The actual root cannot be referenced at
// the source level, but _root_ is essentially a function () => <root>.
lazy val RootPackage: Symbol = {
- val rp = NoSymbol.newValue(NoPosition, nme.ROOTPKG)
- .setFlag(FINAL | MODULE | PACKAGE | JAVA)
- .setInfo(NullaryMethodType(RootClass.tpe))
+ val rp = (
+ NoSymbol.newValue(nme.ROOTPKG, NoPosition, FINAL | MODULE | PACKAGE | JAVA)
+ setInfo NullaryMethodType(RootClass.tpe)
+ )
RootClass.sourceModule = rp
rp
}
// This is the actual root of everything, including the package _root_.
lazy val RootClass: ModuleClassSymbol = (
- NoSymbol.newModuleClass(NoPosition, tpnme.ROOT)
- setFlag (FINAL | MODULE | PACKAGE | JAVA)
+ NoSymbol.newModuleClassSymbol(tpnme.ROOT, NoPosition, FINAL | MODULE | PACKAGE | JAVA)
setInfo rootLoader
)
// The empty package, which holds all top level types without given packages.
- lazy val EmptyPackage = RootClass.newPackage(NoPosition, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL)
+ lazy val EmptyPackage = RootClass.newPackage(nme.EMPTY_PACKAGE_NAME, NoPosition, FINAL)
lazy val EmptyPackageClass = EmptyPackage.moduleClass
lazy val JavaLangPackage = getModule(sn.JavaLang)
@@ -190,11 +198,11 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
// top types
- lazy val AnyClass = newClass(ScalaPackageClass, tpnme.Any, Nil) setFlag (ABSTRACT)
+ lazy val AnyClass = newClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT)
lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.typeConstructor)
lazy val ObjectClass = getClass(sn.Object)
- lazy val AnyCompanionClass = getRequiredClass("scala.AnyCompanion") setFlag (SEALED | ABSTRACT | TRAIT)
- lazy val AnyValCompanionClass = getRequiredClass("scala.AnyValCompanion") setFlag (SEALED | ABSTRACT | TRAIT)
+ lazy val AnyCompanionClass = getRequiredClass("scala.AnyCompanion") initFlags (SEALED | ABSTRACT | TRAIT)
+ lazy val AnyValCompanionClass = getRequiredClass("scala.AnyValCompanion") initFlags (SEALED | ABSTRACT | TRAIT)
// bottom types
lazy val RuntimeNothingClass = getClass(fulltpnme.RuntimeNothing)
@@ -202,9 +210,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) {
locally {
- this setFlag ABSTRACT | TRAIT | FINAL
- this setInfo ClassInfoType(List(parent.tpe), new Scope, this)
- owner.info.decls enter this
+ this initFlags ABSTRACT | TRAIT | FINAL
+ this setInfoAndEnter ClassInfoType(List(parent.tpe), new Scope, this)
}
final override def isBottomClass = true
}
@@ -296,7 +303,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// .setInfo(UnitClass.tpe)
lazy val TypeConstraintClass = getRequiredClass("scala.annotation.TypeConstraint")
- lazy val SingletonClass = newClass(ScalaPackageClass, tpnme.Singleton, anyparam) setFlag (ABSTRACT | TRAIT | FINAL)
+ lazy val SingletonClass = newClass(ScalaPackageClass, tpnme.Singleton, anyparam, ABSTRACT | TRAIT | FINAL)
lazy val SerializableClass = getRequiredClass("scala.Serializable")
lazy val JavaSerializableClass = getClass(sn.JavaSerializable)
lazy val ComparableClass = getRequiredClass("java.lang.Comparable")
@@ -391,6 +398,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// scala.reflect
lazy val ReflectApiUniverse = getRequiredClass("scala.reflect.api.Universe")
+ lazy val ReflectMacroContext = getRequiredClass("scala.reflect.macro.Context")
lazy val ReflectRuntimeMirror = getRequiredModule("scala.reflect.runtime.Mirror")
def freeValueMethod = getMember(ReflectRuntimeMirror, nme.freeValue)
lazy val ReflectPackage = getPackageObject("scala.reflect")
@@ -443,15 +451,11 @@ trait Definitions extends reflect.api.StandardDefinitions {
def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+
def isArrowAssoc(sym: Symbol) = ArrowAssocClass.tpe.decls.toList contains sym
- // The given symbol is a method with the right signature to be a runnable java program.
- def isJavaMainMethod(sym: Symbol) = sym.tpe match {
- case MethodType(param :: Nil, restpe) if restpe.typeSymbol == UnitClass =>
- param.tpe match {
- case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == StringClass
- case _ => false
- }
- case _ => false
- }
+ // The given symbol is a method with the right name and signature to be a runnable java program.
+ def isJavaMainMethod(sym: Symbol) = (sym.name == nme.main) && (sym.info match {
+ case MethodType(p :: Nil, restpe) => isArrayOfSymbol(p.tpe, StringClass) && restpe.typeSymbol == UnitClass
+ case _ => false
+ })
// The given class has a main method.
def hasJavaMainMethod(sym: Symbol): Boolean =
(sym.tpe member nme.main).alternatives exists isJavaMainMethod
@@ -595,6 +599,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
def byNameType(arg: Type) = appliedType(ByNameParamClass.typeConstructor, List(arg))
def iteratorOfType(tp: Type) = appliedType(IteratorClass.typeConstructor, List(tp))
+ lazy val StringArray = arrayType(StringClass.tpe)
+ lazy val ObjectArray = arrayType(ObjectClass.tpe)
+
def ClassType(arg: Type) =
if (phase.erasedTypes || forMSIL) ClassClass.tpe
else appliedType(ClassClass.typeConstructor, List(arg))
@@ -809,13 +816,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
*/
private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length)
- private def newClass(owner: Symbol, name: TypeName, parents: List[Type]): Symbol = {
- val clazz = owner.newClass(NoPosition, name)
- clazz.setInfo(ClassInfoType(parents, new Scope, clazz))
- owner.info.decls.enter(clazz)
- clazz
- }
-
private def newCovariantPolyClass(owner: Symbol, name: TypeName, parent: Symbol => Type): Symbol = {
val clazz = newClass(owner, name, List())
val tparam = newTypeParam(clazz, 0) setFlag COVARIANT
@@ -832,24 +832,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
ClassInfoType(List(AnyRefClass.tpe, p), new Scope, clazz)))
}
- private def newAlias(owner: Symbol, name: TypeName, alias: Type): Symbol = {
- val tpsym = owner.newAliasType(NoPosition, name)
- tpsym.setInfo(alias)
- owner.info.decls.enter(tpsym)
- tpsym
- }
-
- private def newMethod(owner: Symbol, name: TermName): Symbol = {
- val msym = owner.newMethod(NoPosition, name.encode)
- owner.info.decls.enter(msym)
- msym
- }
-
- private[Definitions] def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type): Symbol = {
- val msym = newMethod(owner, name)
- val params = msym.newSyntheticValueParams(formals)
- msym.setInfo(MethodType(params, restpe))
- }
+ private def newAlias(owner: Symbol, name: TypeName, alias: Type): Symbol =
+ owner.newAliasType(name) setInfoAndEnter alias
/** tcon receives the type parameter symbol as argument */
private def newPolyMethod(owner: Symbol, name: TermName, tcon: Symbol => Type): Symbol =
@@ -857,16 +841,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
/** tcon receives the type parameter symbol and the method symbol as arguments */
private def newPolyMethodCon(owner: Symbol, name: TermName, tcon: Symbol => Symbol => Type): Symbol = {
- val msym = newMethod(owner, name)
+ val msym = owner.info.decls enter owner.newMethod(name.encode)
val tparam = newTypeParam(msym, 0)
- msym.setInfo(polyType(List(tparam), tcon(tparam)(msym)))
- }
- private def newParameterlessMethod(owner: Symbol, name: TermName, restpe: Type) =
- newMethod(owner, name).setInfo(NullaryMethodType(restpe))
+ msym setInfo polyType(List(tparam), tcon(tparam)(msym))
+ }
private def newTypeParam(owner: Symbol, index: Int): Symbol =
- owner.newTypeParameter(NoPosition, newTypeName("T" + index)) setInfo TypeBounds.empty
+ owner.newTypeParameter(newTypeName("T" + index)) setInfo TypeBounds.empty
lazy val boxedClassValues = boxedClass.values.toSet
lazy val isUnbox = unboxMethod.values.toSet
@@ -966,12 +948,12 @@ trait Definitions extends reflect.api.StandardDefinitions {
RootClass.info.decls enter RootPackage
// members of class scala.Any
- Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype) setFlag FINAL
- Any_!= = newMethod(AnyClass, nme.NE, anyparam, booltype) setFlag FINAL
+ Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL)
+ Any_!= = newMethod(AnyClass, nme.NE, anyparam, booltype, FINAL)
Any_equals = newMethod(AnyClass, nme.equals_, anyparam, booltype)
Any_hashCode = newMethod(AnyClass, nme.hashCode_, Nil, inttype)
Any_toString = newMethod(AnyClass, nme.toString_, Nil, stringtype)
- Any_## = newMethod(AnyClass, nme.HASHHASH, Nil, inttype) setFlag FINAL
+ Any_## = newMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL)
// Any_getClass requires special handling. The return type is determined on
// a per-call-site basis as if the function being called were actually:
@@ -982,26 +964,24 @@ trait Definitions extends reflect.api.StandardDefinitions {
// Since getClass is not actually a polymorphic method, this requires compiler
// participation. At the "Any" level, the return type is Class[_] as it is in
// java.lang.Object. Java also special cases the return type.
- Any_getClass = (
- newMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType)
- setFlag DEFERRED
- )
+ Any_getClass =
+ newMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED)
Any_isInstanceOf = newPolyMethod(
AnyClass, nme.isInstanceOf_, tparam => NullaryMethodType(booltype)) setFlag FINAL
Any_asInstanceOf = newPolyMethod(
AnyClass, nme.asInstanceOf_, tparam => NullaryMethodType(tparam.typeConstructor)) setFlag FINAL
// members of class java.lang.{ Object, String }
- Object_## = newMethod(ObjectClass, nme.HASHHASH, Nil, inttype) setFlag FINAL
- Object_== = newMethod(ObjectClass, nme.EQ, anyrefparam, booltype) setFlag FINAL
- Object_!= = newMethod(ObjectClass, nme.NE, anyrefparam, booltype) setFlag FINAL
- Object_eq = newMethod(ObjectClass, nme.eq, anyrefparam, booltype) setFlag FINAL
- Object_ne = newMethod(ObjectClass, nme.ne, anyrefparam, booltype) setFlag FINAL
+ Object_## = newMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL)
+ Object_== = newMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL)
+ Object_!= = newMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL)
+ Object_eq = newMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL)
+ Object_ne = newMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL)
Object_synchronized = newPolyMethodCon(
ObjectClass, nme.synchronized_,
tparam => msym => MethodType(msym.newSyntheticValueParams(List(tparam.typeConstructor)), tparam.typeConstructor)) setFlag FINAL
- String_+ = newMethod(StringClass, nme.raw.PLUS, anyparam, stringtype) setFlag FINAL
+ String_+ = newMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL)
val forced = List( // force initialization of every symbol that is entered as a side effect
AnnotationDefaultAttr, // #2264
@@ -1038,7 +1018,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// tparam => resultType, which is the resultType of PolyType, i.e. the result type after applying the
// type parameter =-> a MethodType in this case
// TODO: set type bounds manually (-> MulticastDelegate), see newTypeParam
- val newCaller = newMethod(DelegateClass, name, paramTypes, delegateType) setFlag (FINAL | STATIC)
+ val newCaller = newMethod(DelegateClass, name, paramTypes, delegateType, FINAL | STATIC)
// val newCaller = newPolyMethod(DelegateClass, name,
// tparam => MethodType(paramTypes, tparam.typeConstructor)) setFlag (FINAL | STATIC)
Delegate_scalaCallers = Delegate_scalaCallers ::: List(newCaller)
diff --git a/src/compiler/scala/reflect/internal/HasFlags.scala b/src/compiler/scala/reflect/internal/HasFlags.scala
index 46dca0940a..ec4e919bdc 100644
--- a/src/compiler/scala/reflect/internal/HasFlags.scala
+++ b/src/compiler/scala/reflect/internal/HasFlags.scala
@@ -136,6 +136,9 @@ trait HasFlags {
/** Whether this entity has NONE of the flags in the given mask.
*/
def hasNoFlags(mask: Long): Boolean = !hasFlag(mask)
+
+ protected def isSetting(f: Long, mask: Long) = !hasFlag(f) && ((mask & f) != 0L)
+ protected def isClearing(f: Long, mask: Long) = hasFlag(f) && ((mask & f) != 0L)
// Tests which come through cleanly: both Symbol and Modifiers use these
// identically, testing for a single flag.
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 38f808cef9..53380952c0 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -22,6 +22,7 @@ trait Importers { self: SymbolTable =>
val myowner = importSymbol(sym.owner)
val mypos = importPosition(sym.pos)
val myname = importName(sym.name).toTermName
+ val myflags = sym.flags
def linkReferenced(mysym: TermSymbol, x: from.TermSymbol, op: from.Symbol => Symbol): Symbol = {
symMap(x) = mysym
mysym.referenced = op(x.referenced)
@@ -29,19 +30,20 @@ trait Importers { self: SymbolTable =>
}
val mysym = sym match {
case x: from.MethodSymbol =>
- linkReferenced(new MethodSymbol(myowner, mypos, myname), x, importSymbol)
+ linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol)
case x: from.ModuleSymbol =>
- linkReferenced(new ModuleSymbol(myowner, mypos, myname), x, doImport)
+ linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, doImport)
case x: from.FreeVar =>
- new FreeVar(importName(x.name).toTermName, importType(x.tpe), x.value)
+ newFreeVar(importName(x.name).toTermName, importType(x.tpe), x.value, myflags)
case x: from.TermSymbol =>
- linkReferenced(new TermSymbol(myowner, mypos, myname), x, importSymbol)
+ linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol)
case x: from.TypeSkolem =>
- new TypeSkolem(myowner, mypos, myname.toTypeName, x.unpackLocation match {
- case null => null
- case y: from.Tree => importTree(y)
+ val origin = x.unpackLocation match {
+ case null => null
+ case y: from.Tree => importTree(y)
case y: from.Symbol => importSymbol(y)
- })
+ }
+ myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags)
/*
case x: from.ModuleClassSymbol =>
val mysym = new ModuleClassSymbol(myowner, mypos, myname.toTypeName)
@@ -49,17 +51,17 @@ trait Importers { self: SymbolTable =>
mysym
*/
case x: from.ClassSymbol =>
- val mysym = new ClassSymbol(myowner, mypos, myname.toTypeName)
+ val mysym = myowner.newClassSymbol(myname.toTypeName, mypos, myflags)
if (sym.thisSym != sym) {
mysym.typeOfThis = importType(sym.typeOfThis)
mysym.thisSym.name = importName(sym.thisSym.name)
}
mysym
case x: from.TypeSymbol =>
- new TypeSymbol(myowner, mypos, myname.toTypeName)
+ myowner.newTypeSymbol(myname.toTypeName, mypos, myflags)
}
symMap(sym) = mysym
- mysym setFlag sym.flags | Flags.LOCKED
+ mysym setFlag Flags.LOCKED
mysym setInfo {
val mytypeParams = sym.typeParams map doImport
new LazyPolyType(mytypeParams) {
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
index ef092f16bb..97a74c2383 100644
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ b/src/compiler/scala/reflect/internal/NameManglers.scala
@@ -85,7 +85,7 @@ trait NameManglers {
def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR
def isExceptionResultName(name: Name) = name startsWith EXCEPTION_RESULT_PREFIX
- def isImplClassName(name: Name) = stripAnonNumberSuffix(name) endsWith IMPL_CLASS_SUFFIX
+ def isImplClassName(name: Name) = name endsWith IMPL_CLASS_SUFFIX
def isLocalDummyName(name: Name) = name startsWith LOCALDUMMY_PREFIX
def isLocalName(name: Name) = name endsWith LOCAL_SUFFIX_STRING
def isLoopHeaderLabel(name: Name) = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
@@ -176,25 +176,18 @@ trait NameManglers {
else name.toTermName
}
- /** !!! I'm putting this logic in place because I can witness
- * trait impls get lifted and acquiring names like 'Foo$class$1'
- * while clearly still being what they were. It's only being used on
- * isImplClassName. However, it's anyone's guess how much more
- * widely this logic actually ought to be applied. Anything which
- * tests for how a name ends is a candidate for breaking down once
- * something is lifted from a method.
- *
- * TODO: resolve this significant problem.
- */
- def stripAnonNumberSuffix(name: Name): Name = {
- val str = "" + name
- if (str == "" || !str.endChar.isDigit) name
- else {
- val idx = name.lastPos('$')
- if (idx < 0 || str.substring(idx + 1).exists(c => !c.isDigit)) name
- else name.subName(0, idx)
- }
- }
+ // This isn't needed at the moment since I fixed $class$1 but
+ // I expect it will be at some point.
+ //
+ // def anonNumberSuffix(name: Name): Name = {
+ // ("" + name) lastIndexOf '$' match {
+ // case -1 => nme.EMPTY
+ // case idx =>
+ // val s = name drop idx
+ // if (s.toString forall (_.isDigit)) s
+ // else nme.EMPTY
+ // }
+ // }
def stripModuleSuffix(name: Name): Name = (
if (isModuleName(name)) name dropRight MODULE_SUFFIX_STRING.length else name
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index b960695f51..907b564d4c 100644
--- a/src/compiler/scala/reflect/internal/Names.scala
+++ b/src/compiler/scala/reflect/internal/Names.scala
@@ -77,7 +77,11 @@ trait Names extends api.Names {
def newTermName(cs: Array[Char]): TermName = newTermName(cs, 0, cs.length)
def newTypeName(cs: Array[Char]): TypeName = newTypeName(cs, 0, cs.length)
- /** Create a term name from the characters in cs[offset..offset+len-1]. */
+ /** Create a term name from the characters in cs[offset..offset+len-1].
+ * TODO - have a mode where name validation is performed at creation time
+ * (e.g. if a name has the string "$class" in it, then fail if that
+ * string is not at the very end.)
+ */
protected def newTermName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TermName = {
val h = hashValue(cs, offset, len) & HASH_MASK
var n = termHashtable(h)
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index ea5565c581..aba00088f9 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -13,7 +13,7 @@ import annotation.switch
trait StdNames extends NameManglers { self: SymbolTable =>
def encode(str: String): TermName = newTermNameCached(NameTransformer.encode(str))
-
+
implicit def lowerTermNames(n: TermName): String = "" + n
// implicit def stringToTermName(s: String): TermName = newTermName(s)
@@ -182,7 +182,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
trait TermNames extends Keywords with CommonNames {
// Compiler internal names
val EXPAND_SEPARATOR_STRING = "$$"
-
+
val ANYNAME: NameType = "<anyname>"
val CONSTRUCTOR: NameType = "<init>"
val FAKE_LOCAL_THIS: NameType = "this$"
@@ -207,7 +207,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val Predef: NameType = "Predef"
final val ScalaRunTime: NameType = "ScalaRunTime"
final val Some: NameType = "Some"
-
+
val _1 : NameType = "_1"
val _2 : NameType = "_2"
val _3 : NameType = "_3"
@@ -230,6 +230,31 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val _20 : NameType = "_20"
val _21 : NameType = "_21"
val _22 : NameType = "_22"
+
+ val x_0 : NameType = "x$0"
+ val x_1 : NameType = "x$1"
+ val x_2 : NameType = "x$2"
+ val x_3 : NameType = "x$3"
+ val x_4 : NameType = "x$4"
+ val x_5 : NameType = "x$5"
+ val x_6 : NameType = "x$6"
+ val x_7 : NameType = "x$7"
+ val x_8 : NameType = "x$8"
+ val x_9 : NameType = "x$9"
+
+ @switch def syntheticParamName(i: Int): TermName = i match {
+ case 0 => nme.x_0
+ case 1 => nme.x_1
+ case 2 => nme.x_2
+ case 3 => nme.x_3
+ case 4 => nme.x_4
+ case 5 => nme.x_5
+ case 6 => nme.x_6
+ case 7 => nme.x_7
+ case 8 => nme.x_8
+ case 9 => nme.x_9
+ case _ => newTermName("x$" + i)
+ }
val wrapRefArray: NameType = "wrapRefArray"
val wrapByteArray: NameType = "wrapByteArray"
@@ -246,6 +271,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
// Compiler utilized names
// val productElementName: NameType = "productElementName"
val Ident: NameType = "Ident"
+ val StringContext: NameType = "StringContext"
val TYPE_ : NameType = "TYPE"
val TypeTree: NameType = "TypeTree"
val UNIT : NameType = "UNIT"
@@ -275,6 +301,8 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val classOf: NameType = "classOf"
val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure
val conforms: NameType = "conforms"
+ val context : NameType = "_context"
+ val contextImplicit : NameType = "$context"
val copy: NameType = "copy"
val delayedInit: NameType = "delayedInit"
val delayedInitArg: NameType = "delayedInit$body"
@@ -295,11 +323,9 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val find_ : NameType = "find"
val flatMap: NameType = "flatMap"
val foreach: NameType = "foreach"
- val formatted: NameType = "formatted"
val freeValue : NameType = "freeValue"
val genericArrayOps: NameType = "genericArrayOps"
val get: NameType = "get"
- val glob : NameType = "glob"
val hasNext: NameType = "hasNext"
val hashCode_ : NameType = if (forMSIL) "GetHashCode" else "hashCode"
val hash_ : NameType = "hash"
@@ -405,7 +431,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val REFINE_CLASS_NAME: NameType = "<refinement>"
val ANON_CLASS_NAME: NameType = "$anon"
}
-
+
/** For fully qualified type names.
*/
object fulltpnme extends TypeNames {
@@ -425,11 +451,11 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val RuntimeNothing = toBinary(fulltpnme.RuntimeNothing).toTypeName
val RuntimeNull = toBinary(fulltpnme.RuntimeNull).toTypeName
}
-
+
object fullnme extends TermNames {
type NameType = TermName
protected implicit def createNameType(name: String): TermName = newTermNameCached(name)
-
+
val MirrorPackage: NameType = "scala.reflect.mirror"
}
@@ -491,7 +517,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
def moduleVarName(name: TermName): TermName =
newTermNameCached("" + name + MODULE_VAR_SUFFIX)
-
+
val ROOTPKG: TermName = "_root_"
/** Base strings from which synthetic names are derived. */
@@ -506,7 +532,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val INTERPRETER_VAR_PREFIX = "res"
val INTERPRETER_WRAPPER_SUFFIX = "$object"
val WHILE_PREFIX = "while$"
-
+
val EQEQ_LOCAL_VAR: TermName = newTermName(EQEQ_LOCAL_VAR_STRING)
def getCause = sn.GetCause
@@ -543,18 +569,18 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val UNARY_+ = encode("unary_+")
val UNARY_- = encode("unary_-")
val UNARY_! = encode("unary_!")
-
+
// Grouped here so Cleanup knows what tests to perform.
val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE)
val ConversionNames = Set[Name](toByte, toChar, toDouble, toFloat, toInt, toLong, toShort)
val BooleanOpNames = Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames
val NumberOpNames = (
- Set[Name](ADD, SUB, MUL, DIV, MOD, LSL, LSR, ASR, LT, LE, GE, GT)
- ++ Set(UNARY_+, UNARY_-, UNARY_!)
+ Set[Name](ADD, SUB, MUL, DIV, MOD, LSL, LSR, ASR, LT, LE, GE, GT)
+ ++ Set(UNARY_+, UNARY_-, UNARY_!)
++ ConversionNames
++ CommonOpNames
)
-
+
val add: NameType = "add"
val complement: NameType = "complement"
val divide: NameType = "divide"
@@ -645,7 +671,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
reflMethodName
)
def isReflectionCacheName(name: Name) = reflectionCacheNames exists (name startsWith _)
-
+
@switch def productAccessorName(j: Int): TermName = j match {
case 1 => nme._1
case 2 => nme._2
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index 5be69e06ad..ace4d55b90 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -40,6 +40,15 @@ abstract class SymbolTable extends api.Universe
def debuglog(msg: => String): Unit = if (settings.debug.value) log(msg)
def debugwarn(msg: => String): Unit = if (settings.debug.value) Console.err.println(msg)
+ private[scala] def printResult[T](msg: String)(result: T) = {
+ Console.err.println(msg + ": " + result)
+ result
+ }
+ private[scala] def logResult[T](msg: String)(result: T): T = {
+ log(msg + ": " + result)
+ result
+ }
+
/** Are we compiling for Java SE? */
// def forJVM: Boolean
@@ -149,7 +158,7 @@ abstract class SymbolTable extends api.Universe
}
}
// enter decls of parent classes
- for (pt <- container.info.parents; p = pt.typeSymbol) {
+ for (p <- container.parentSymbols) {
if (p != definitions.ObjectClass && p != definitions.ScalaObjectClass) {
openPackageModule(p, dest)
}
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 6ee061392c..a943b6fe24 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -35,6 +35,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
nextexid += 1
newTypeName("_" + nextexid + suffix)
}
+
+ // Set the fields which point companions at one another. Returns the module.
+ def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = {
+ moduleClass.sourceModule = m
+ m setModuleClass moduleClass
+ m
+ }
+ /** Create a new free variable. Its owner is NoSymbol.
+ */
+ def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar =
+ new FreeVar(name, value) initFlags newFlags setInfo tpe
/** The original owner of a class. Used by the backend to generate
* EnclosingMethod attributes.
@@ -42,9 +53,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
val originalOwner = perRunCaches.newMap[Symbol, Symbol]()
abstract class AbsSymbolImpl extends AbsSymbol { this: Symbol =>
- def newNestedSymbol(pos: Position, name: Name) = name match {
- case n: TermName => newValue(pos, n)
- case n: TypeName => newAliasType(pos, n)
+ def newNestedSymbol(name: Name, pos: Position, newFlags: Long) = name match {
+ case n: TermName => newTermSymbol(n, pos, newFlags)
+ case n: TypeName => newTypeSymbol(n, pos, newFlags)
}
def typeSig: Type = info
def typeSigIn(site: Type): Type = site.memberInfo(this)
@@ -72,7 +83,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private var rawpos = initPos
val id = { ids += 1; ids } // identity displayed when -uniqid
- //assert(id != 3204, initName)
var validTo: Period = NoPeriod
@@ -89,64 +99,95 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ------ creators -------------------------------------------------------------------
- final def newValue(pos: Position, name: TermName) =
- new TermSymbol(this, pos, name)
- final def newValue(name: TermName, pos: Position = NoPosition) =
- new TermSymbol(this, pos, name)
- final def newVariable(pos: Position, name: TermName) =
- newValue(pos, name).setFlag(MUTABLE)
- final def newValueParameter(pos: Position, name: TermName) =
- newValue(pos, name).setFlag(PARAM)
+ final def newValue(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol =
+ newTermSymbol(name, pos, newFlags)
+ final def newVariable(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol =
+ newTermSymbol(name, pos, MUTABLE | newFlags)
+ final def newValueParameter(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol =
+ newTermSymbol(name, pos, PARAM | newFlags)
+
/** Create local dummy for template (owner of local blocks) */
final def newLocalDummy(pos: Position) =
- newValue(pos, nme.localDummyName(this)).setInfo(NoType)
- final def newMethod(pos: Position, name: TermName) =
- new MethodSymbol(this, pos, name).setFlag(METHOD)
- final def newMethod(name: TermName, pos: Position = NoPosition) =
- new MethodSymbol(this, pos, name).setFlag(METHOD)
- final def newLabel(pos: Position, name: TermName) =
- newMethod(pos, name).setFlag(LABEL)
+ newTermSymbol(nme.localDummyName(this), pos) setInfo NoType
+ final def newMethod(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol =
+ newMethodSymbol(name, pos, METHOD | newFlags)
+ final def newLabel(name: TermName, pos: Position = NoPosition): MethodSymbol =
+ newMethod(name, pos, LABEL)
/** Propagates ConstrFlags (JAVA, specifically) from owner to constructor. */
- final def newConstructor(pos: Position) =
- newMethod(pos, nme.CONSTRUCTOR) setFlag getFlag(ConstrFlags)
+ final def newConstructor(pos: Position, newFlags: Long = 0L) =
+ newMethod(nme.CONSTRUCTOR, pos, getFlag(ConstrFlags) | newFlags)
+
/** Static constructor with info set. */
def newStaticConstructor(pos: Position) =
- newConstructor(pos) setFlag STATIC setInfo UnitClass.tpe
+ newConstructor(pos, STATIC) setInfo UnitClass.tpe
/** Instance constructor with info set. */
def newClassConstructor(pos: Position) =
newConstructor(pos) setInfo MethodType(Nil, this.tpe)
- private def finishModule(m: ModuleSymbol, clazz: ClassSymbol): ModuleSymbol = {
- // Top-level objects can be automatically marked final, but others
- // must be explicitly marked final if overridable objects are enabled.
- val flags = if (isPackage || !settings.overrideObjects.value) MODULE | FINAL else MODULE
- m setFlag flags
- m setModuleClass clazz
- m
+ // Top-level objects can be automatically marked final, but others
+ // must be explicitly marked final if overridable objects are enabled.
+ private def ModuleFlags = (
+ if (isPackage || !settings.overrideObjects.value) MODULE | FINAL
+ else MODULE
+ )
+ def newLinkedModule(clazz: Symbol, newFlags: Long = 0L): ModuleSymbol = {
+ val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, ModuleFlags | newFlags)
+ connectModuleToClass(m, clazz.asInstanceOf[ClassSymbol])
+ }
+ final def newModule(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = {
+ val m = newModuleSymbol(name, pos, newFlags | ModuleFlags)
+ val clazz = newModuleClassSymbol(name.toTypeName, pos, (m getFlag ModuleToClassFlags) | MODULE)
+ connectModuleToClass(m, clazz)
}
- private def finishModule(m: ModuleSymbol): ModuleSymbol =
- finishModule(m, new ModuleClassSymbol(m))
-
- final def newModule(pos: Position, name: TermName, clazz: ClassSymbol): ModuleSymbol =
- finishModule(new ModuleSymbol(this, pos, name), clazz)
-
- final def newModule(name: TermName, clazz: Symbol, pos: Position = NoPosition): ModuleSymbol =
- newModule(pos, name, clazz.asInstanceOf[ClassSymbol])
-
- final def newModule(pos: Position, name: TermName): ModuleSymbol =
- finishModule(new ModuleSymbol(this, pos, name))
- final def newPackage(pos: Position, name: TermName): ModuleSymbol = {
- assert(name == nme.ROOT || isPackageClass)
- val m = newModule(pos, name).setFlag(JAVA | PACKAGE)
- m.moduleClass setFlag (JAVA | PACKAGE)
- m
+ final def newPackage(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = {
+ assert(name == nme.ROOT || isPackageClass, this)
+ newModule(name, pos, JAVA | PACKAGE | newFlags)
}
final def newThisSym(pos: Position) =
- newValue(pos, nme.this_).setFlag(SYNTHETIC)
+ newTermSymbol(nme.this_, pos, SYNTHETIC)
final def newImport(pos: Position) =
- newValue(pos, nme.IMPORT)
+ newTermSymbol(nme.IMPORT, pos)
+
+ /** Direct symbol factories.
+ * For internal use; these are unlikely to be what you want.
+ */
+ def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol =
+ new TermSymbol(this, pos, name) initFlags newFlags
+
+ def newAbstractTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol =
+ new AbstractTypeSymbol(this, pos, name) initFlags newFlags
+
+ def newAliasTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol =
+ new AliasTypeSymbol(this, pos, name) initFlags newFlags
+
+ def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
+ new ModuleSymbol(this, pos, name) initFlags newFlags
+
+ def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol =
+ new MethodSymbol(this, pos, name) initFlags newFlags
+
+ def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol =
+ new ClassSymbol(this, pos, name) initFlags newFlags
+
+ def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol =
+ new ModuleClassSymbol(this, pos, name) initFlags newFlags
+
+ /** Derive whether it is an abstract type from the flags; after creation
+ * the DEFERRED flag will be ignored.
+ */
+ def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
+ if ((newFlags & DEFERRED) == 0L)
+ newAliasTypeSymbol(name, pos, newFlags)
+ else
+ newAbstractTypeSymbol(name, pos, newFlags)
+
+ def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem =
+ if ((newFlags & DEFERRED) == 0L)
+ new TypeSkolem(this, pos, name, origin) initFlags newFlags
+ else
+ new TypeSkolem(this, pos, name, origin) with AbstractTypeMixin initFlags newFlags
/** @param pre type relative to which alternatives are seen.
* for instance:
@@ -166,58 +207,50 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*
* pre.memberType(m)
*/
- final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol =
- newValue(alternatives.head.pos, alternatives.head.name.toTermName)
- .setFlag(OVERLOADED)
- .setInfo(OverloadedType(pre, alternatives))
-
- /** for explicit outer phase */
- final def newOuterAccessor(pos: Position) = {
- val sym = newMethod(pos, nme.OUTER)
- sym setFlag (STABLE | SYNTHETIC)
- if (isTrait) sym setFlag DEFERRED
- sym.expandName(this)
- sym.referenced = this
- sym
- }
+ final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol = (
+ newTermSymbol(alternatives.head.name.toTermName, alternatives.head.pos, OVERLOADED)
+ setInfo OverloadedType(pre, alternatives)
+ )
final def newErrorValue(name: TermName) =
- newValue(pos, name).setFlag(SYNTHETIC | IS_ERROR).setInfo(ErrorType)
+ newTermSymbol(name, pos, SYNTHETIC | IS_ERROR) setInfo ErrorType
/** Symbol of a type definition type T = ...
*/
- final def newAliasType(pos: Position, name: TypeName) =
- new TypeSymbol(this, pos, name)
- final def newAliasType(name: TypeName, pos: Position = NoPosition) =
- new TypeSymbol(this, pos, name)
-
+ final def newAliasType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol =
+ newAliasTypeSymbol(name, pos, newFlags)
+
/** Symbol of an abstract type type T >: ... <: ...
*/
- final def newAbstractType(pos: Position, name: TypeName) =
- new TypeSymbol(this, pos, name).setFlag(DEFERRED)
- final def newAbstractType(name: TypeName, pos: Position = NoPosition) =
- new TypeSymbol(this, pos, name).setFlag(DEFERRED)
+ final def newAbstractType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol =
+ newAbstractTypeSymbol(name, pos, DEFERRED | newFlags)
/** Symbol of a type parameter
*/
- final def newTypeParameter(pos: Position, name: TypeName) =
- newAbstractType(pos, name).setFlag(PARAM)
+ final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) =
+ newAbstractType(name, pos, PARAM | newFlags)
/** Synthetic value parameters when parameter symbols are not available
*/
final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[Symbol]] = {
var cnt = 0
- def freshName() = { cnt += 1; newTermName("x$" + cnt) }
- def param(tp: Type) =
- newValueParameter(focusPos(owner.pos), freshName()).setFlag(SYNTHETIC).setInfo(tp)
- argtypess map (_.map(param))
+ def freshName() = { cnt += 1; nme.syntheticParamName(cnt) }
+ mmap(argtypess)(tp => newValueParameter(freshName(), focusPos(owner.pos), SYNTHETIC) setInfo tp)
}
- final def newExistential(pos: Position, name: TypeName): Symbol =
- newAbstractType(pos, name).setFlag(EXISTENTIAL)
+ /** Create a new existential type skolem with this symbol its owner,
+ * based on the given symbol and origin.
+ */
+ def newExistentialSkolem(basis: Symbol, origin: AnyRef): TypeSkolem = {
+ val skolem = newTypeSkolemSymbol(basis.name.toTypeName, origin, basis.pos, (basis.flags | EXISTENTIAL) & ~PARAM)
+ skolem setInfo (basis.info cloneInfo skolem)
+ }
+
+ final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol =
+ newAbstractType(name, pos, EXISTENTIAL | newFlags)
final def freshExistential(suffix: String): Symbol =
- newExistential(pos, freshExistentialName(suffix))
+ newExistential(freshExistentialName(suffix), pos)
/** Synthetic value parameters when parameter symbols are not available.
* Calling this method multiple times will re-use the same parameter names.
@@ -237,52 +270,67 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* body of the method, there's a local copy of `T` which is a TypeSkolem.
*/
final def newTypeSkolem: Symbol =
- new TypeSkolem(owner, pos, name.toTypeName, this)
- .setFlag(flags)
+ owner.newTypeSkolemSymbol(name.toTypeName, this, pos, flags)
- final def newClass(pos: Position, name: TypeName) =
- new ClassSymbol(this, pos, name)
- final def newClass(name: TypeName, pos: Position = NoPosition) =
- new ClassSymbol(this, pos, name)
+ final def newClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) =
+ newClassSymbol(name, pos, newFlags)
+
+ /** A new class with its info set to a ClassInfoType with given scope and parents. */
+ def newClassWithInfo(name: TypeName, parents: List[Type], scope: Scope, pos: Position = NoPosition, newFlags: Long = 0L) = {
+ val clazz = newClass(name, pos, newFlags)
+ clazz setInfo ClassInfoType(parents, scope, clazz)
+ }
+ final def newErrorClass(name: TypeName) =
+ newClassWithInfo(name, Nil, new ErrorScope(this), pos, SYNTHETIC | IS_ERROR)
- final def newModuleClass(pos: Position, name: TypeName) =
- new ModuleClassSymbol(this, pos, name)
final def newModuleClass(name: TypeName, pos: Position = NoPosition) =
- new ModuleClassSymbol(this, pos, name)
+ newModuleClassSymbol(name, pos)
final def newAnonymousClass(pos: Position) =
- newClass(pos, tpnme.ANON_CLASS_NAME)
- final def newAnonymousFunctionClass(pos: Position) =
- newClass(pos, tpnme.ANON_FUN_NAME)
+ newClassSymbol(tpnme.ANON_CLASS_NAME, pos)
+
+ final def newAnonymousFunctionClass(pos: Position, newFlags: Long = 0L) =
+ newClassSymbol(tpnme.ANON_FUN_NAME, pos, FINAL | SYNTHETIC | newFlags)
+
+ final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L) =
+ newTermSymbol(nme.ANON_FUN_NAME, pos, SYNTHETIC | newFlags) setInfo NoType
/** Refinement types P { val x: String; type T <: Number }
* also have symbols, they are refinementClasses
*/
final def newRefinementClass(pos: Position) =
- newClass(pos, tpnme.REFINE_CLASS_NAME)
+ newClass(tpnme.REFINE_CLASS_NAME, pos)
/** Create a new getter for current symbol (which must be a field)
*/
final def newGetter: Symbol = (
- owner.newMethod(focusPos(pos), nme.getterName(name.toTermName))
- setFlag getterFlags(flags)
+ owner.newMethod(nme.getterName(name.toTermName), NoPosition, getterFlags(flags))
setPrivateWithin privateWithin
setInfo MethodType(Nil, tpe)
)
- final def newErrorClass(name: TypeName) = {
- val clazz = newClass(pos, name)
- ( clazz
- setFlag (SYNTHETIC | IS_ERROR)
- setInfo ClassInfoType(Nil, new ErrorScope(this), clazz)
- )
- }
-
final def newErrorSymbol(name: Name): Symbol = name match {
case x: TypeName => newErrorClass(x)
case x: TermName => newErrorValue(x)
}
+ @deprecated("Use the other signature", "2.10.0")
+ def newClass(pos: Position, name: TypeName): Symbol = newClass(name, pos)
+ @deprecated("Use the other signature", "2.10.0")
+ def newModuleClass(pos: Position, name: TypeName): Symbol = newModuleClass(name, pos)
+ @deprecated("Use the other signature", "2.10.0")
+ def newLabel(pos: Position, name: TermName): MethodSymbol = newLabel(name, pos)
+ @deprecated("Use the other signature", "2.10.0")
+ def newValue(pos: Position, name: TermName): TermSymbol = newTermSymbol(name, pos)
+ @deprecated("Use the other signature", "2.10.0")
+ def newAliasType(pos: Position, name: TypeName): Symbol = newAliasType(name, pos)
+ @deprecated("Use the other signature", "2.10.0")
+ def newAbstractType(pos: Position, name: TypeName): Symbol = newAbstractType(name, pos)
+ @deprecated("Use the other signature", "2.10.0")
+ def newExistential(pos: Position, name: TypeName): Symbol = newExistential(name, pos)
+ @deprecated("Use the other signature", "2.10.0")
+ def newMethod(pos: Position, name: TermName): MethodSymbol = newMethod(name, pos)
+
// ----- locking and unlocking ------------------------------------------------------
// True if the symbol is unlocked.
@@ -424,9 +472,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
// A package object or its module class
- final def isPackageObjectOrClass = name == nme.PACKAGE || name == tpnme.PACKAGE
- final def isPackageObject = name == nme.PACKAGE && owner.isPackageClass
- final def isPackageObjectClass = name == tpnme.PACKAGE && owner.isPackageClass
+ final def isPackageObjectOrClass = (this ne NoSymbol) && owner.isPackageClass && (name == nme.PACKAGE || name == tpnme.PACKAGE)
+ final def isPackageObject = (this ne NoSymbol) && owner.isPackageClass && name == nme.PACKAGE
+ final def isPackageObjectClass = (this ne NoSymbol) && owner.isPackageClass && name == tpnme.PACKAGE
final def isDefinedInPackage = effectiveOwner.isPackageClass
final def isJavaInterface = isJavaDefined && isTrait
@@ -437,7 +485,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The owner, skipping package objects.
*/
- def effectiveOwner = owner.skipPackageObject
+ def effectiveOwner = if (owner.isPackageObjectClass) owner.skipPackageObject else owner
/** If this is a package object or its implementing class, its owner: otherwise this.
*/
@@ -808,8 +856,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
(fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift)
}
final def flags_=(fs: Long) = rawflags = fs
- final def setFlag(mask: Long): this.type = { rawflags = rawflags | mask; this }
- final def resetFlag(mask: Long): this.type = { rawflags = rawflags & ~mask; this }
+
+ /** Set the symbol's flags to the given value, asserting
+ * that the previous value was 0.
+ */
+ def initFlags(mask: Long): this.type = {
+ assert(rawflags == 0L, this)
+ rawflags = mask
+ this
+ }
+ def setFlag(mask: Long): this.type = { rawflags = rawflags | mask ; this }
+ def resetFlag(mask: Long): this.type = { rawflags = rawflags & ~mask ; this }
final def getFlag(mask: Long): Long = flags & mask
final def resetFlags() { rawflags = rawflags & TopLevelCreationFlags }
@@ -937,6 +994,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Substitute second list of symbols for first in current info. */
def substInfo(syms0: List[Symbol], syms1: List[Symbol]) = modifyInfo(_.substSym(syms0, syms1))
def setInfoOwnerAdjusted(info: Type): this.type = setInfo(info atOwner this)
+
+ /** Set the info and enter this symbol into the owner's scope. */
+ def setInfoAndEnter(info: Type): this.type = {
+ setInfo(info)
+ owner.info.decls enter this
+ this
+ }
/** Set new info valid from start of this phase. */
final def updateInfo(info: Type): Symbol = {
@@ -1124,7 +1188,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
oldsymbuf += sym
newsymbuf += (
if (sym.isClass)
- tp.typeSymbol.newAbstractType(sym.pos, sym.name.toTypeName).setInfo(sym.existentialBound)
+ tp.typeSymbol.newAbstractType(sym.name.toTypeName, sym.pos).setInfo(sym.existentialBound)
else
sym.cloneSymbol(tp.typeSymbol))
}
@@ -1141,15 +1205,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* the bound of the type variable that stands for it
* pre: symbol is a term, a class, or an abstract type (no alias type allowed)
*/
- def existentialBound: Type =
- if (this.isClass)
- polyType(this.typeParams, TypeBounds.upper(this.classBound))
- else if (this.isAbstractType)
- this.info
- else if (this.isTerm)
- singletonBounds(this.tpe)
- else
- abort("unexpected alias type: "+this)
+ def existentialBound: Type
/** Reset symbol to initial state
*/
@@ -1282,18 +1338,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
cloneSymbol(owner)
/** A clone of this symbol, but with given owner. */
- final def cloneSymbol(owner: Symbol): Symbol = {
- val newSym = cloneSymbolImpl(owner)
+ final def cloneSymbol(owner: Symbol): Symbol = cloneSymbol(owner, this.rawflags)
+ final def cloneSymbol(owner: Symbol, newFlags: Long): Symbol = {
+ val newSym = cloneSymbolImpl(owner, newFlags)
( newSym
setPrivateWithin privateWithin
setInfo (info cloneInfo newSym)
- setFlag this.rawflags
setAnnotations this.annotations
)
}
-
- /** Internal method to clone a symbol's implementation without flags or type. */
- def cloneSymbolImpl(owner: Symbol): Symbol
+ /** Internal method to clone a symbol's implementation with the given flags and no info. */
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol
+ def cloneSymbolImpl(owner: Symbol): Symbol = cloneSymbolImpl(owner, 0L)
// ------ access to related symbols --------------------------------------------------
@@ -1369,7 +1425,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def sourceModule: Symbol = NoSymbol
- /** The implementation class of a trait. */
+ /** The implementation class of a trait. If available it will be the
+ * symbol with the same owner, and the name of this symbol with $class
+ * appended to it.
+ */
final def implClass: Symbol = owner.info.decl(nme.implClassName(name))
/** The class that is logically an outer class of given `clazz`.
@@ -1402,6 +1461,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The superclass of this class. */
def superClass: Symbol = if (info.parents.isEmpty) NoSymbol else info.parents.head.typeSymbol
+ def parentSymbols: List[Symbol] = info.parents map (_.typeSymbol)
/** The directly or indirectly inherited mixins of this class
* except for mixin classes inherited by the superclass. Mixin classes appear
@@ -1997,9 +2057,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
privateWithin = NoSymbol
var referenced: Symbol = NoSymbol
+
+ def existentialBound = singletonBounds(this.tpe)
- def cloneSymbolImpl(owner: Symbol): Symbol =
- new TermSymbol(owner, pos, name).copyAttrsFrom(this)
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newTermSymbol(name, pos, newFlags).copyAttrsFrom(this)
def copyAttrsFrom(original: TermSymbol): this.type = {
referenced = original.referenced
@@ -2029,13 +2091,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (hasFlag(MODULE)) referenced else NoSymbol
def setModuleClass(clazz: Symbol): TermSymbol = {
- assert(hasFlag(MODULE))
+ assert(hasFlag(MODULE), this)
referenced = clazz
this
}
def setLazyAccessor(sym: Symbol): TermSymbol = {
- assert(isLazy && (referenced == NoSymbol || referenced == sym), this)
+ assert(isLazy && (referenced == NoSymbol || referenced == sym), (this, hasFlagsToString(-1L), referenced, sym))
referenced = sym
this
}
@@ -2095,8 +2157,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else rawname.toTermName
)
- override def cloneSymbolImpl(owner: Symbol): Symbol =
- new ModuleSymbol(owner, pos, name).copyAttrsFrom(this)
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newModuleSymbol(name, pos, newFlags).copyAttrsFrom(this)
}
/** A class for method symbols */
@@ -2107,8 +2169,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private var mtpeResult: Type = _
private var mtpeInfo: Type = _
- override def cloneSymbolImpl(owner: Symbol): Symbol =
- new MethodSymbol(owner, pos, name).copyAttrsFrom(this)
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newMethodSymbol(name, pos, newFlags).copyAttrsFrom(this)
def typeAsMemberOf(pre: Type): Type = {
if (mtpePeriod == currentPeriod) {
@@ -2125,24 +2187,71 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
res
}
}
+
+ class AliasTypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
+ extends TypeSymbol(initOwner, initPos, initName) {
+ // Temporary programmatic help tracking down who might do such a thing
+ override def setFlag(mask: Long): this.type = {
+ if (isSetting(DEFERRED, mask)) {
+ println("Setting DEFERRED on alias at")
+ (new Throwable).printStackTrace
+ }
+ super.setFlag(mask)
+ }
+ final override def isAliasType = true
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): AliasTypeSymbol =
+ owner.newAliasTypeSymbol(name, pos, newFlags)
+ }
+
+ class AbstractTypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
+ extends TypeSymbol(initOwner, initPos, initName) with AbstractTypeMixin {
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): AbstractTypeSymbol =
+ owner.newAbstractTypeSymbol(name, pos, newFlags)
+ }
+
+ /** Might be mixed into TypeSymbol or TypeSkolem.
+ */
+ trait AbstractTypeMixin extends TypeSymbol {
+ override def resetFlag(mask: Long): this.type = {
+ // Temporary programmatic help tracking down who might do such a thing
+ if (settings.debug.value) {
+ if (isClearing(DEFERRED, mask)) {
+ println("Clearing DEFERRED on abstract type at")
+ (new Throwable).printStackTrace
+ }
+ }
+ super.resetFlag(mask)
+ }
+ final override def isAbstractType = true
+ override def existentialBound = this.info
+ }
/** A class of type symbols. Alias and abstract types are direct instances
* of this class. Classes are instances of a subclass.
*/
- class TypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
- extends Symbol(initOwner, initPos, initName) {
+ sealed abstract class TypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName) extends Symbol(initOwner, initPos, initName) {
privateWithin = NoSymbol
private var tyconCache: Type = null
private var tyconRunId = NoRunId
private var tpeCache: Type = _
private var tpePeriod = NoPeriod
+ /** Overridden in subclasses for which it makes sense.
+ */
+ def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+this.fullLocationString+ " " + hasFlagsToString(-1L))
+
override def name: TypeName = super.name.asInstanceOf[TypeName]
final override def isType = true
override def isNonClassType = true
- override def isAbstractType = isDeferred
- override def isAliasType = !isDeferred
-
+ override def isAbstractType = {
+ if (settings.debug.value) {
+ if (isDeferred) {
+ println("TypeSymbol claims to be abstract type: " + this.getClass + " " + hasFlagsToString(-1L) + " at ")
+ (new Throwable).printStackTrace
+ }
+ }
+ isDeferred
+ }
private def newTypeRef(targs: List[Type]) = {
val pre = if (hasFlag(PARAM | EXISTENTIAL)) NoPrefix else owner.thisType
typeRef(pre, this, targs)
@@ -2198,9 +2307,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
override def tpeHK = typeConstructor // @M! used in memberType
- // needed for experimental code for early types as type parameters
- // def refreshType() { tpePeriod = NoPeriod }
-
override def typeConstructor: Type = {
if ((tyconCache eq null) || tyconRunId != currentRunId) {
tyconCache = newTypeRef(Nil)
@@ -2242,8 +2348,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
- def cloneSymbolImpl(owner: Symbol): Symbol =
- new TypeSymbol(owner, pos, name)
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newTypeSymbol(name, pos, newFlags)
incCounter(typeSymbolCount)
}
@@ -2281,8 +2387,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
//@M! (not deSkolemize.typeParams!!), also can't leave superclass definition: use info, not rawInfo
override def typeParams = info.typeParams
- override def cloneSymbolImpl(owner: Symbol): Symbol =
- new TypeSkolem(owner, pos, name, origin)
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newTypeSkolemSymbol(name, origin, pos, newFlags)
override def nameString: String =
if (settings.debug.value) (super.nameString + "&" + level)
@@ -2300,6 +2406,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final override def isNonClassType = false
final override def isAbstractType = false
final override def isAliasType = false
+
+ override def existentialBound = polyType(this.typeParams, TypeBounds.upper(this.classBound))
override def sourceFile =
if (owner.isPackageClass) source
@@ -2362,8 +2470,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
thissym = newThisSym(pos).setInfo(tp)
}
- override def cloneSymbolImpl(owner: Symbol): Symbol = {
- val clone = new ClassSymbol(owner, pos, name)
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = {
+ val clone = owner.newClassSymbol(name, pos, newFlags)
if (thisSym != this) {
clone.typeOfThis = typeOfThis
clone.thisSym.name = thisSym.name
@@ -2388,35 +2496,32 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
class ModuleClassSymbol(owner: Symbol, pos: Position, name: TypeName)
extends ClassSymbol(owner, pos, name) {
private var module: Symbol = null
- def this(module: TermSymbol) = {
- this(module.owner, module.pos, module.name.toTypeName)
- setFlag(module.getFlag(ModuleToClassFlags) | MODULE)
- sourceModule = module
- }
- override def sourceModule = module
private var implicitMembersCacheValue: List[Symbol] = List()
private var implicitMembersCacheKey1: Type = NoType
private var implicitMembersCacheKey2: ScopeEntry = null
+
def implicitMembers: List[Symbol] = {
val tp = info
if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) {
- implicitMembersCacheKey1 = tp
- implicitMembersCacheKey2 = tp.decls.elems
- implicitMembersCacheValue = tp.implicitMembers
+ // Skip a package object class, because the members are also in
+ // the package and we wish to avoid spurious ambiguities as in pos/t3999.
+ if (!isPackageObjectClass) {
+ implicitMembersCacheKey1 = tp
+ implicitMembersCacheKey2 = tp.decls.elems
+ implicitMembersCacheValue = tp.implicitMembers
+ }
}
implicitMembersCacheValue
}
+ override def sourceModule = module
override def sourceModule_=(module: Symbol) { this.module = module }
}
- class FreeVar(name0: TermName, tpe: Type, val value: Any) extends TermSymbol(definitions.RootClass, NoPosition, name0) {
- setInfo(tpe)
-
+ class FreeVar(name0: TermName, val value: Any) extends TermSymbol(NoSymbol, NoPosition, name0) {
override def hashCode = value.hashCode
-
override def equals(other: Any): Boolean = other match {
case that: FreeVar => this.value.asInstanceOf[AnyRef] eq that.value.asInstanceOf[AnyRef]
- case _ => false
+ case _ => false
}
}
@@ -2436,18 +2541,23 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def enclClass: Symbol = this
override def toplevelClass: Symbol = this
override def enclMethod: Symbol = this
- override def owner: Symbol = abort("no-symbol does not have owner")
override def sourceFile: AbstractFileType = null
override def ownerChain: List[Symbol] = List()
override def ownersIterator: Iterator[Symbol] = Iterator.empty
override def alternatives: List[Symbol] = List()
override def reset(completer: Type) {}
override def info: Type = NoType
+ override def existentialBound: Type = NoType
override def rawInfo: Type = NoType
protected def doCookJavaRawInfo() {}
override def accessBoundary(base: Symbol): Symbol = RootClass
- def cloneSymbolImpl(owner: Symbol): Symbol = abort()
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = abort()
override def originalEnclosingMethod = this
+
+ override def owner: Symbol =
+ abort("no-symbol does not have an owner (this is a bug: scala " + scala.util.Properties.versionString + ")")
+ override def typeConstructor: Type =
+ abort("no-symbol does not have a type constructor (this may indicate scalac cannot find fundamental classes)")
}
/** Derives a new list of symbols from the given list by mapping the given
@@ -2518,17 +2628,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f)
- /** Create a new existential type skolem with the given owner and origin.
- */
- def newExistentialSkolem(sym: Symbol, owner: Symbol, origin: AnyRef): TypeSkolem = {
- val skolem = new TypeSkolem(owner, sym.pos, sym.name.toTypeName, origin)
- ( skolem
- setInfo (sym.info cloneInfo skolem)
- setFlag (sym.flags | EXISTENTIAL)
- resetFlag PARAM
- )
- }
-
/** An exception for cyclic references of symbol definitions */
case class CyclicReference(sym: Symbol, info: Type)
extends TypeError("illegal cyclic reference involving " + sym) {
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 96f2c5cc45..a2c55a89d6 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -121,7 +121,12 @@ trait Trees extends api.Trees { self: SymbolTable =>
new ChangeOwnerTraverser(oldOwner, newOwner) apply t
}
}
-
+
+ def substTreeSyms(pairs: (Symbol, Symbol)*): Tree = {
+ val list = pairs.toList
+ val subst = new TreeSymSubstituter(list map (_._1), list map (_._2))
+ subst(tree)
+ }
def shallowDuplicate: Tree = new ShallowDuplicator(tree) transform tree
def shortClass: String = tree.getClass.getName split "[.$]" last
/** When you want to know a little more than the class, but a lot
@@ -198,9 +203,8 @@ trait Trees extends api.Trees { self: SymbolTable =>
def DefDef(sym: Symbol, rhs: Tree): DefDef =
DefDef(sym, Modifiers(sym.flags), rhs)
- def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = {
+ def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef =
DefDef(sym, rhs(sym.info.paramss))
- }
/** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */
def TypeDef(sym: Symbol, rhs: Tree): TypeDef =
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 4630733db4..1df60f32d9 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -322,13 +322,20 @@ trait Types extends api.Types { self: SymbolTable =>
/** The type symbol associated with the type
* Note that the symbol of the normalized type is returned (@see normalize)
+ * A type's typeSymbol should if possible not be inspected directly, due to
+ * the likelihood that what is true for tp.typeSymbol is not true for
+ * tp.sym, due to normalization.
*/
def typeSymbol: Symbol = NoSymbol
- /** The term symbol ''directly'' associated with the type. */
+ /** The term symbol ''directly'' associated with the type.
+ */
def termSymbolDirect: Symbol = termSymbol
- /** The type symbol ''directly'' associated with the type. */
+ /** The type symbol ''directly'' associated with the type.
+ * In other words, no normalization is performed: if this is an alias type,
+ * the symbol returned is that of the alias, not the underlying type.
+ */
def typeSymbolDirect: Symbol = typeSymbol
/** The base type underlying a type proxy, identity on all other types */
@@ -412,6 +419,11 @@ trait Types extends api.Types { self: SymbolTable =>
/** For a typeref, its arguments. The empty list for all other types */
def typeArgs: List[Type] = List()
+
+ /** A list of placeholder types derived from the type parameters.
+ * Used by RefinedType and TypeRef.
+ */
+ protected def dummyArgs: List[Type] = typeParams map (_.typeConstructor)
/** For a (nullary) method or poly type, its direct result type,
* the type itself for all other types. */
@@ -931,30 +943,12 @@ trait Types extends api.Types { self: SymbolTable =>
*/
//TODO: use narrow only for modules? (correct? efficiency gain?)
def findMember(name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean): Symbol = {
- var suspension: mutable.HashSet[TypeVar] = null
// if this type contains type variables, put them to sleep for a while -- don't just wipe them out by
// replacing them by the corresponding type parameter, as that messes up (e.g.) type variables in type refinements
// without this, the matchesType call would lead to type variables on both sides
// of a subtyping/equality judgement, which can lead to recursive types being constructed.
// See (t0851) for a situation where this happens.
- if (!this.isGround) {
- // PP: The foreach below was formerly expressed as:
- // for(tv @ TypeVar(_, _) <- this) { suspension suspend tv }
- //
- // The tree checker failed this saying a TypeVar is required, but a (Type @unchecked) was found.
- // This is a consequence of using a pattern match and variable binding + ticket #1503, which
- // was addressed by weakening the type of bindings in pattern matches if they occur on the right.
- // So I'm not quite sure why this works at all, as the checker is right that it is mistyped.
- // For now I modified it as below, which achieves the same without error.
- //
- // make each type var in this type use its original type for comparisons instead of collecting constraints
- val susp = new mutable.HashSet[TypeVar] // use a local val so it remains unboxed
- this foreach {
- case tv: TypeVar => tv.suspended = true; susp += tv
- case _ =>
- }
- suspension = susp
- }
+ val suspension: List[TypeVar] = if (this.isGround) null else suspendTypeVarsInType(this)
incCounter(findMemberCount)
val start = startTimer(findMemberNanos)
@@ -1504,8 +1498,6 @@ trait Types extends api.Types { self: SymbolTable =>
override def typeConstructor =
copyRefinedType(this, parents map (_.typeConstructor), decls)
- private def dummyArgs = typeParams map (_.typeConstructor)
-
/* MO to AM: This is probably not correct
* If they are several higher-kinded parents with different bounds we need
* to take the intersection of their bounds
@@ -1650,11 +1642,12 @@ trait Types extends api.Types { self: SymbolTable =>
def apply(tp: Type): Type = {
tp match {
- case TypeRef(_, sym, args) if args.nonEmpty =>
- if (settings.debug.value && !sameLength(sym.info.typeParams, args))
+ case tr @ TypeRef(_, sym, args) if args.nonEmpty =>
+ val tparams = tr.initializedTypeParams
+ if (settings.debug.value && !sameLength(tparams, args))
debugwarn("Mismatched zip in computeRefs(): " + sym.info.typeParams + ", " + args)
- foreach2(sym.info.typeParams, args) { (tparam1, arg) =>
+ foreach2(tparams, args) { (tparam1, arg) =>
if (arg contains tparam) {
addRef(NonExpansive, tparam, tparam1)
if (arg.typeSymbol != tparam)
@@ -1759,134 +1752,282 @@ trait Types extends api.Types { self: SymbolTable =>
private var volatileRecursions: Int = 0
private val pendingVolatiles = new mutable.HashSet[Symbol]
+
+ class ArgsTypeRef(pre0: Type, sym0: Symbol, args0: List[Type]) extends TypeRef(pre0, sym0, args0) with UniqueType {
+ require(args0.nonEmpty, this)
- /** A class for named types of the form
- * `<prefix>.<sym.name>[args]`
- * Cannot be created directly; one should always use `typeRef`
- * for creation. (@M: Otherwise hashing breaks)
- *
- * @M: a higher-kinded type is represented as a TypeRef with sym.info.typeParams.nonEmpty, but args.isEmpty
- * @param pre ...
- * @param sym ...
- * @param args ...
- */
- abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type {
-// assert(!sym.isAbstractType || pre.isStable || pre.isError)
-// assert(!pre.isInstanceOf[ClassInfoType], this)
-// assert(!(sym hasFlag (PARAM | EXISTENTIAL)) || pre == NoPrefix, this)
-// assert(args.isEmpty || !sym.info.typeParams.isEmpty, this)
-// assert(args.isEmpty || ((sym ne AnyClass) && (sym ne NothingClass))
+ /** No unapplied type params size it has (should have) equally as many args. */
+ override def isHigherKinded = false
+ override def typeParams = Nil
- private var parentsCache: List[Type] = _
- private var parentsPeriod = NoPeriod
+ override def transform(tp: Type): Type = {
+ // This situation arises when a typevar is encountered for which
+ // too little information is known to determine its kind, and
+ // it later turns out not to have kind *. See SI-4070. Only
+ // logging it for now.
+ if (sym.typeParams.size != args.size)
+ log("!!! %s.transform(%s), but tparams.isEmpty and args=".format(this, tp, args))
- private var baseTypeSeqCache: BaseTypeSeq = _
- private var baseTypeSeqPeriod = NoPeriod
+ asSeenFromOwner(tp).instantiateTypeParams(sym.typeParams, args)
+ }
+
+ // note: does not go through typeRef. There's no need to because
+ // neither `pre` nor `sym` changes. And there's a performance
+ // advantage to call TypeRef directly.
+ override def typeConstructor = TypeRef(pre, sym, Nil)
+ }
+ class NoArgsTypeRef(pre0: Type, sym0: Symbol) extends TypeRef(pre0, sym0, Nil) with UniqueType {
+ // A reference (in a Scala program) to a type that has type parameters, but where the reference
+ // does not include type arguments. Note that it doesn't matter whether the symbol refers
+ // to a java or scala symbol, but it does matter whether it occurs in java or scala code.
+ // TypeRefs w/o type params that occur in java signatures/code are considered raw types, and are
+ // represented as existential types.
+ override def isHigherKinded = typeParams.nonEmpty
+ override def typeParams = if (isDefinitionsInitialized) sym.typeParams else sym.unsafeTypeParams
+ private def isRaw = !phase.erasedTypes && isRawIfWithoutArgs(sym)
+
+ override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type =
+ if (isHigherKinded) {
+ if (sameLength(formals intersect typeParams, typeParams))
+ copyTypeRef(this, pre, sym, actuals)
+ // partial application (needed in infer when bunching type arguments from classes and methods together)
+ else
+ copyTypeRef(this, pre, sym, dummyArgs).instantiateTypeParams(formals, actuals)
+ }
+ else
+ super.instantiateTypeParams(formals, actuals)
- private var symInfoCache: Type = _
- private var memberInfoCache: Type = _
- private var thisInfoCache: Type = _
- private var relativeInfoCache: Type = _
+ override def transform(tp: Type): Type = {
+ val res = asSeenFromOwner(tp)
+ if (isHigherKinded && !isRaw)
+ res.instantiateTypeParams(typeParams, dummyArgs)
+ else
+ res
+ }
- private var normalized: Type = null
+ override def transformInfo(tp: Type): Type =
+ appliedType(asSeenFromOwner(tp), dummyArgs)
+
+ override def narrow =
+ if (sym.isModuleClass) singleType(pre, sym.sourceModule)
+ else super.narrow
- override def isStable: Boolean = {
- sym == NothingClass ||
- sym == SingletonClass ||
- sym.isAliasType && normalize.isStable ||
- sym.isAbstractType && (bounds.hi.typeSymbol isSubClass SingletonClass)
- }
+ override def typeConstructor = this
+ // eta-expand, subtyping relies on eta-expansion of higher-kinded types
- override def isVolatile: Boolean = {
- sym.isAliasType && normalize.isVolatile ||
- sym.isAbstractType && {
- // need to be careful not to fall into an infinite recursion here
- // because volatile checking is done before all cycles are detected.
- // the case to avoid is an abstract type directly or
- // indirectly upper-bounded by itself. See #2918
- try {
- volatileRecursions += 1
- if (volatileRecursions < LogVolatileThreshold)
- bounds.hi.isVolatile
- else if (pendingVolatiles(sym))
- true // we can return true here, because a cycle will be detected
- // here afterwards and an error will result anyway.
- else
- try {
- pendingVolatiles += sym
- bounds.hi.isVolatile
- } finally {
- pendingVolatiles -= sym
- }
- } finally {
- volatileRecursions -= 1
- }
- }
- }
+ override protected def normalizeImpl: Type =
+ if (isHigherKinded) etaExpand else super.normalizeImpl
+ }
+
+ trait ClassTypeRef extends TypeRef {
+ // !!! There are scaladoc-created symbols arriving which violate this require.
+ // require(sym.isClass, sym)
+
+ override protected def normalizeImpl: Type =
+ if (sym.isRefinementClass) sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
+ else super.normalizeImpl
- override lazy val isTrivial: Boolean =
- !sym.isTypeParameter && pre.isTrivial && args.forall(_.isTrivial)
+ override def baseType(clazz: Symbol): Type =
+ if (sym == clazz) this
+ else transform(sym.info.baseType(clazz))
+ }
+ trait NonClassTypeRef extends TypeRef {
+ require(sym.isNonClassType, sym)
- override def isNotNull =
- sym.isModuleClass || sym == NothingClass || isValueClass(sym) || super.isNotNull
+ private var relativeInfoCache: Type = _
+ private var memberInfoCache: Type = _
- // @M: propagate actual type params (args) to `tp`, by replacing formal type parameters with actual ones
- // if tp is higher kinded, the "actual" type arguments are types that simply reference the corresponding type parameters (unbound type variables)
- def transform(tp: Type): Type = {
- val res = tp.asSeenFrom(pre, sym.owner)
- if (sym.typeParams.isEmpty || (args exists (_.isError)) || isRaw(sym, args)/*#2266/2305*/) res
- else res.instantiateTypeParams(sym.typeParams, typeArgsOrDummies)
+ private def relativeInfo = {
+ val memberInfo = pre.memberInfo(sym)
+ if (relativeInfoCache == null || (memberInfo ne memberInfoCache)) {
+ memberInfoCache = memberInfo
+ relativeInfoCache = transformInfo(memberInfo)
+ }
+ relativeInfoCache
}
+
+ override def baseType(clazz: Symbol): Type = (
+ if (sym == clazz) this else try {
+ basetypeRecursions += 1
+ if (basetypeRecursions < LogPendingBaseTypesThreshold)
+ relativeInfo.baseType(clazz)
+ else if (pendingBaseTypes contains this)
+ if (clazz == AnyClass) clazz.tpe else NoType
+ else
+ try {
+ pendingBaseTypes += this
+ relativeInfo.baseType(clazz)
+ } finally {
+ pendingBaseTypes -= this
+ }
+ } finally {
+ basetypeRecursions -= 1
+ }
+ )
+ }
+ trait AliasTypeRef extends NonClassTypeRef {
+ require(sym.isAliasType, sym)
+
+ override def dealias = if (typeParamsMatchArgs) betaReduce.dealias else super.dealias
+ override def isStable = normalize.isStable
+ override def isVolatile = normalize.isVolatile
+ override def narrow = normalize.narrow
+ override def thisInfo = normalize
+ override def prefix = if (this ne normalize) normalize.prefix else pre
+ override def termSymbol = if (this ne normalize) normalize.termSymbol else super.termSymbol
+ override def typeSymbol = if (this ne normalize) normalize.typeSymbol else sym
+
+ // beta-reduce, but don't do partial application -- cycles have been checked in typeRef
+ override protected def normalizeImpl =
+ if (typeParamsMatchArgs) betaReduce.normalize
+ else if (isHigherKinded) super.normalizeImpl
+ else ErrorType
+
+ // isHKSubType0 introduces synthetic type params so that
+ // betaReduce can first apply sym.info to typeArgs before calling
+ // asSeenFrom. asSeenFrom then skips synthetic type params, which
+ // are used to reduce HO subtyping to first-order subtyping, but
+ // which can't be instantiated from the given prefix and class.
+ //
+ // this crashes pos/depmet_implicit_tpbetareduce.scala
+ // appliedType(sym.info, typeArgs).asSeenFrom(pre, sym.owner)
+ def betaReduce = transform(sym.info.resultType)
+
+ // #3731: return sym1 for which holds: pre bound sym.name to sym and
+ // pre1 now binds sym.name to sym1, conceptually exactly the same
+ // symbol as sym. The selection of sym on pre must be updated to the
+ // selection of sym1 on pre1, since sym's info was probably updated
+ // by the TypeMap to yield a new symbol, sym1 with transformed info.
+ // @returns sym1
+ override def coevolveSym(pre1: Type): Symbol =
+ if (pre eq pre1) sym else (pre, pre1) match {
+ // don't look at parents -- it would be an error to override alias types anyway
+ case (RefinedType(_, _), RefinedType(_, decls1)) => decls1 lookup sym.name
+ // TODO: is there another way a typeref's symbol can refer to a symbol defined in its pre?
+ case _ => sym
+ }
+
+ }
- //@M! use appliedType on the polytype that represents the bounds (or if aliastype, the rhs)
- def transformInfo(tp: Type): Type = appliedType(tp.asSeenFrom(pre, sym.owner), typeArgsOrDummies)
+ trait AbstractTypeRef extends NonClassTypeRef {
+ require(sym.isAbstractType, sym)
+
+ private var symInfoCache: Type = _
+ private var thisInfoCache: Type = _
- def thisInfo: Type =
- if (sym.isAliasType) normalize
- else if (!sym.isNonClassType) sym.info
- else {
- val symInfo = sym.info
- if (thisInfoCache == null || (symInfo ne symInfoCache)) {
- symInfoCache = symInfo
- thisInfoCache = transformInfo(symInfo) match {
- // If a subtyping cycle is not detected here, we'll likely enter an infinite
- // loop before a sensible error can be issued. SI-5093 is one example.
- case x: SubType if x.supertype eq this =>
- throw new TypeError("illegal cyclic reference involving " + sym)
- case tp => tp
+ override def isVolatile = {
+ // need to be careful not to fall into an infinite recursion here
+ // because volatile checking is done before all cycles are detected.
+ // the case to avoid is an abstract type directly or
+ // indirectly upper-bounded by itself. See #2918
+ try {
+ volatileRecursions += 1
+ if (volatileRecursions < LogVolatileThreshold)
+ bounds.hi.isVolatile
+ else if (pendingVolatiles(sym))
+ true // we can return true here, because a cycle will be detected
+ // here afterwards and an error will result anyway.
+ else
+ try {
+ pendingVolatiles += sym
+ bounds.hi.isVolatile
+ } finally {
+ pendingVolatiles -= sym
}
+ } finally {
+ volatileRecursions -= 1
+ }
+ }
+ override def thisInfo = {
+ val symInfo = sym.info
+ if (thisInfoCache == null || (symInfo ne symInfoCache)) {
+ symInfoCache = symInfo
+ thisInfoCache = transformInfo(symInfo) match {
+ // If a subtyping cycle is not detected here, we'll likely enter an infinite
+ // loop before a sensible error can be issued. SI-5093 is one example.
+ case x: SubType if x.supertype eq this =>
+ throw new TypeError("illegal cyclic reference involving " + sym)
+ case tp => tp
}
- thisInfoCache
}
+ thisInfoCache
+ }
+ override def isStable = bounds.hi.typeSymbol isSubClass SingletonClass
+ override def bounds = thisInfo.bounds
+ // def transformInfo(tp: Type): Type = appliedType(tp.asSeenFrom(pre, sym.owner), typeArgsOrDummies)
+ override protected def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this
+ }
- def relativeInfo: Type =
- if (!sym.isNonClassType) pre.memberInfo(sym)
+ /** A class for named types of the form
+ * `<prefix>.<sym.name>[args]`
+ * Cannot be created directly; one should always use `typeRef`
+ * for creation. (@M: Otherwise hashing breaks)
+ *
+ * @M: a higher-kinded type is represented as a TypeRef with sym.typeParams.nonEmpty, but args.isEmpty
+ */
+ abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type {
+ private var parentsCache: List[Type] = _
+ private var parentsPeriod = NoPeriod
+ private var baseTypeSeqCache: BaseTypeSeq = _
+ private var baseTypeSeqPeriod = NoPeriod
+ private var normalized: Type = _
+
+ // @M: propagate actual type params (args) to `tp`, by replacing
+ // formal type parameters with actual ones. If tp is higher kinded,
+ // the "actual" type arguments are types that simply reference the
+ // corresponding type parameters (unbound type variables)
+ def transform(tp: Type): Type
+
+ // eta-expand, subtyping relies on eta-expansion of higher-kinded types
+ protected def normalizeImpl: Type = if (isHigherKinded) etaExpand else super.normalize
+
+ // TODO: test case that is compiled in a specific order and in different runs
+ final override def normalize: Type = {
+ // arises when argument-dependent types are approximated (see def depoly in implicits)
+ if (pre eq WildcardType) WildcardType
+ else if (phase.erasedTypes) normalizeImpl
else {
- val memberInfo = pre.memberInfo(sym)
- if (relativeInfoCache == null || (memberInfo ne memberInfoCache)) {
- memberInfoCache = memberInfo
- relativeInfoCache = transformInfo(memberInfo)
- }
- relativeInfoCache
+ if (normalized eq null)
+ normalized = normalizeImpl
+ normalized
}
+ }
+
+ def etaExpand: Type = {
+ // must initialise symbol, see test/files/pos/ticket0137.scala
+ val tpars = initializedTypeParams
+ if (tpars.isEmpty) this
+ else typeFunAnon(tpars, copyTypeRef(this, pre, sym, tpars map (_.tpeHK))) // todo: also beta-reduce?
+ }
- override def typeSymbol = if (sym.isAliasType && (this ne normalize)) normalize.typeSymbol else sym
- override def termSymbol = if (sym.isAliasType && (this ne normalize)) normalize.termSymbol else super.termSymbol
- override def typeSymbolDirect = sym
- override def termSymbolDirect = super.termSymbol
+ // only need to rebind type aliases, as typeRef already handles abstract types
+ // (they are allowed to be rebound more liberally)
+ def coevolveSym(pre1: Type): Symbol = sym
-/* @MAT
-whenever you see `tp.typeSymbol.isXXXX` and then act on tp based on that predicate, you're on thin ice,
-as `typeSymbol` (and `prefix`) automatically normalize, but the other inspectors don't.
-In other words, even if `tp.normalize.sym.isXXX` is true, `tp.sym.isXXX` may be false (if sym were a public method to access the non-normalized typeSymbol)...
+ //@M! use appliedType on the polytype that represents the bounds (or if aliastype, the rhs)
+ def transformInfo(tp: Type): Type = appliedType(asSeenFromOwner(tp), args)
+
+ def thisInfo = sym.info
+ def initializedTypeParams = sym.info.typeParams
+ def typeParamsMatchArgs = sameLength(initializedTypeParams, args)
+ def asSeenFromOwner(tp: Type) = tp.asSeenFrom(pre, sym.owner)
+
+ override def baseClasses = thisInfo.baseClasses
+ override def baseTypeSeqDepth = baseTypeSeq.maxDepth
+ override def isStable = (sym eq NothingClass) || (sym eq SingletonClass)
+ override def prefix = pre
+ override def termSymbol = super.termSymbol
+ override def termSymbolDirect = super.termSymbol
+ override def typeArgs = args
+ override def typeOfThis = transform(sym.typeOfThis)
+ override def typeSymbol = sym
+ override def typeSymbolDirect = sym
-In retrospect, I think `tp.typeSymbol.isXXX` or (worse) `tp.typeSymbol==XXX` should be replaced by `val tp = tp0.asXXX`.
-A type's typeSymbol should never be inspected directly.
-*/
+ override lazy val isTrivial: Boolean =
+ !sym.isTypeParameter && pre.isTrivial && args.forall(_.isTrivial)
- override def bounds: TypeBounds =
- if (sym.isAbstractType) thisInfo.bounds // transform(thisInfo.bounds).asInstanceOf[TypeBounds] // ??? seems to be doing asSeenFrom twice
- else super.bounds
+ override def isNotNull =
+ sym.isModuleClass || sym == NothingClass || isValueClass(sym) || super.isNotNull
override def parents: List[Type] = {
val period = parentsPeriod
@@ -1894,118 +2035,12 @@ A type's typeSymbol should never be inspected directly.
parentsPeriod = currentPeriod
if (!isValidForBaseClasses(period)) {
parentsCache = thisInfo.parents map transform
- } else if (parentsCache == null) { // seems this can happen if things are currupted enough, see #2641
+ } else if (parentsCache == null) { // seems this can happen if things are corrupted enough, see #2641
parentsCache = List(AnyClass.tpe)
}
}
parentsCache
}
- override def typeOfThis = transform(sym.typeOfThis)
-
-/*
- override def narrow =
- if (sym.isModuleClass) transform(sym.thisType)
- else if (sym.isAliasType) normalize.narrow
- else super.narrow
-*/
- override def narrow =
- if (sym.isModuleClass) singleType(pre, sym.sourceModule)
- else if (sym.isAliasType) normalize.narrow
- else super.narrow
-
- override def prefix: Type =
- if (sym.isAliasType) normalize.prefix
- else pre
-
- override def typeArgs: List[Type] = args
- private def typeArgsOrDummies = if (!isHigherKinded) args else dummyArgs
- // def hasFishyArgs = args == dummyArgs
- private def argsMatchTypeParams = sameLength(sym.info.typeParams, args)
-
- // @MAT was typeSymbol.unsafeTypeParams, but typeSymbol normalizes now
- private def typeParamsDirect =
- if (isDefinitionsInitialized) sym.typeParams
- else sym.unsafeTypeParams
-
- // placeholders derived from type params
- private def dummyArgs = {
- // @PP to @AM: this appears to me a place where
- // higher-order tparams are going off the beam.
- // if (sym.isAbstractType) { something goes wrong }
-
- //@M must be .typeConstructor
- typeParamsDirect map (_.typeConstructor)
- }
-
- // (!result.isEmpty) IFF isHigherKinded
- override def typeParams: List[Symbol] = if (isHigherKinded) typeParamsDirect else List()
-
- // note: does not go through typeRef. There's no need to because
- // neither `pre` nor `sym` changes. And there's a performance
- // advantage to call TypeRef directly.
- override def typeConstructor = if (args.isEmpty) this else TypeRef(pre, sym, Nil)
-
- // A reference (in a Scala program) to a type that has type
- // parameters, but where the reference does not include type
- // arguments. Note that it doesn't matter whether the symbol refers
- // to a java or scala symbol, but it does matter whether it occurs in
- // java or scala code. TypeRefs w/o type params that occur in java
- // signatures/code are considered raw types, and are represented as
- // existential types.
- override def isHigherKinded = args.isEmpty && typeParamsDirect.nonEmpty
-
- override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type =
- if (isHigherKinded) {
- if (sameLength(formals intersect typeParams, typeParams))
- copyTypeRef(this, pre, sym, actuals)
- // partial application (needed in infer when bunching type arguments from classes and methods together)
- else
- copyTypeRef(this, pre, sym, dummyArgs).instantiateTypeParams(formals, actuals)
- }
- else
- super.instantiateTypeParams(formals, actuals)
-
- /** @pre: argsMatchTypeParams */
- @inline private def betaReduce: Type = {
- // isHKSubType0 introduces synthetic type params so that
- // betaReduce can first apply sym.info to typeArgs before calling
- // asSeenFrom. asSeenFrom then skips synthetic type params, which
- // are used to reduce HO subtyping to first-order subtyping, but
- // which can't be instantiated from the given prefix and class.
- transform(sym.info.resultType)
- // this crashes pos/depmet_implicit_tpbetareduce.scala
- // appliedType(sym.info, typeArgs).asSeenFrom(pre, sym.owner)
- }
- private def isBetaReducible = sym.isAliasType && argsMatchTypeParams
-
- // @M: initialize (by sym.info call) needed (see test/files/pos/ticket0137.scala)
- @inline private def etaExpand: Type = {
- val tpars = sym.info.typeParams // must go through sym.info for typeParams to initialise symbol
- if (tpars.isEmpty) this
- else typeFunAnon(tpars, copyTypeRef(this, pre, sym, tpars map (_.tpeHK))) // todo: also beta-reduce?
- }
-
- override def dealias = if (isBetaReducible) betaReduce.dealias else this
-
- private def normalize0: Type = (
- if (pre eq WildcardType) WildcardType // arises when argument-dependent types are approximated (see def depoly in implicits)
- else if (isHigherKinded) etaExpand // eta-expand, subtyping relies on eta-expansion of higher-kinded types
- else if (isBetaReducible) betaReduce.normalize // beta-reduce, but don't do partial application -- cycles have been checked in typeRef
- else if (sym.isRefinementClass) sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
- else if (sym.isAliasType) ErrorType //println("!!error: "+(pre, sym, sym.info, sym.info.typeParams, args))
- else super.normalize
- )
-
- // TODO: test case that is compiled in a specific order and in different runs
- override def normalize: Type = {
- if (phase.erasedTypes) normalize0
- else {
- if (normalized == null)
- normalized = normalize0
-
- normalized
- }
- }
override def decls: Scope = {
sym.info match {
@@ -2015,27 +2050,8 @@ A type's typeSymbol should never be inspected directly.
}
thisInfo.decls
}
-
- override def baseType(clazz: Symbol): Type =
- if (sym == clazz) this
- else if (sym.isClass) transform(sym.info.baseType(clazz))
- else
- try {
- basetypeRecursions += 1
- if (basetypeRecursions < LogPendingBaseTypesThreshold)
- relativeInfo.baseType(clazz)
- else if (pendingBaseTypes contains this)
- if (clazz == AnyClass) clazz.tpe else NoType
- else
- try {
- pendingBaseTypes += this
- relativeInfo.baseType(clazz)
- } finally {
- pendingBaseTypes -= this
- }
- } finally {
- basetypeRecursions -= 1
- }
+
+ protected def baseTypeSeqImpl: BaseTypeSeq = sym.info.baseTypeSeq map transform
override def baseTypeSeq: BaseTypeSeq = {
val period = baseTypeSeqPeriod
@@ -2044,9 +2060,7 @@ A type's typeSymbol should never be inspected directly.
if (!isValidForBaseClasses(period)) {
incCounter(typerefBaseTypeSeqCount)
baseTypeSeqCache = undetBaseTypeSeq
- baseTypeSeqCache =
- if (sym.isAbstractType) transform(bounds.hi).baseTypeSeq prepend this
- else sym.info.baseTypeSeq map transform
+ baseTypeSeqCache = baseTypeSeqImpl
}
}
if (baseTypeSeqCache == undetBaseTypeSeq)
@@ -2054,11 +2068,6 @@ A type's typeSymbol should never be inspected directly.
baseTypeSeqCache
}
- override def baseTypeSeqDepth: Int = baseTypeSeq.maxDepth
-
- override def baseClasses: List[Symbol] = thisInfo.baseClasses
-
- // override def isNullable: Boolean = sym.info.isNullable
private def preString = (
// ensure that symbol is not a local copy with a name coincidence
if (!settings.debug.value && shorthands(sym.fullName) && sym.ownerChain.forall(_.isClass)) ""
@@ -2073,7 +2082,6 @@ A type's typeSymbol should never be inspected directly.
)
else ""
)
-
private def finishPrefix(rest: String) = (
if (sym.isPackageClass) packagePrefix + rest
else if (sym.isModuleClass) objectPrefix + rest
@@ -2093,8 +2101,11 @@ A type's typeSymbol should never be inspected directly.
// ...but only if it's not a tuple, so ((T1, T2)) => R is distinguishable
// from (T1, T2) => R.
targs match {
- case in :: out :: Nil if !isTupleTypeOrSubtype(in) =>
- "" + in + " => " + out
+ case in :: out :: Nil if !isTupleTypeOrSubtype(in) =>
+ // A => B => C should be (A => B) => C or A => (B => C)
+ val in_s = if (isFunctionType(in)) "(" + in + ")" else "" + in
+ val out_s = if (isFunctionType(out)) "(" + out + ")" else "" + out
+ in_s + " => " + out_s
case xs =>
xs.init.mkString("(", ", ", ")") + " => " + xs.last
}
@@ -2126,12 +2137,19 @@ A type's typeSymbol should never be inspected directly.
override def kind = "TypeRef"
}
- final class UniqueTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends TypeRef(pre, sym, args) with UniqueType { }
-
object TypeRef extends TypeRefExtractor {
- def apply(pre: Type, sym: Symbol, args: List[Type]): Type = {
- unique(new UniqueTypeRef(pre, sym, args))
- }
+ def apply(pre: Type, sym: Symbol, args: List[Type]): Type = unique({
+ if (args.nonEmpty) {
+ if (sym.isAliasType) new ArgsTypeRef(pre, sym, args) with AliasTypeRef
+ else if (sym.isAbstractType) new ArgsTypeRef(pre, sym, args) with AbstractTypeRef
+ else new ArgsTypeRef(pre, sym, args) with ClassTypeRef
+ }
+ else {
+ if (sym.isAliasType) new NoArgsTypeRef(pre, sym) with AliasTypeRef
+ else if (sym.isAbstractType) new NoArgsTypeRef(pre, sym) with AbstractTypeRef
+ else new NoArgsTypeRef(pre, sym) with ClassTypeRef
+ }
+ })
}
/** A class representing a method type with parameters.
@@ -2320,7 +2338,7 @@ A type's typeSymbol should never be inspected directly.
override def isHigherKinded = false
override def skolemizeExistential(owner: Symbol, origin: AnyRef) =
- deriveType(quantified, tparam => newExistentialSkolem(tparam, owner orElse tparam.owner, origin))(underlying)
+ deriveType(quantified, tparam => (owner orElse tparam.owner).newExistentialSkolem(tparam, origin))(underlying)
private def wildcardArgsString(available: Set[Symbol], args: List[Type]): List[String] = args match {
case TypeRef(_, sym, _) :: args1 if (available contains sym) =>
@@ -2410,7 +2428,7 @@ A type's typeSymbol should never be inspected directly.
object HasTypeMember {
def apply(name: TypeName, tp: Type): Type = {
val bound = refinedType(List(WildcardType), NoSymbol)
- val bsym = bound.typeSymbol.newAliasType(NoPosition, name)
+ val bsym = bound.typeSymbol.newAliasType(name)
bsym setInfo tp
bound.decls enter bsym
bound
@@ -3248,6 +3266,20 @@ A type's typeSymbol should never be inspected directly.
mapOver(tp)
}
}
+
+ /** Type with all top-level occurrences of abstract types replaced by their bounds */
+ def abstractTypesToBounds(tp: Type): Type = tp match { // @M don't normalize here (compiler loops on pos/bug1090.scala )
+ case TypeRef(_, sym, _) if sym.isAbstractType =>
+ abstractTypesToBounds(tp.bounds.hi)
+ case TypeRef(_, sym, _) if sym.isAliasType =>
+ abstractTypesToBounds(tp.normalize)
+ case rtp @ RefinedType(parents, decls) =>
+ copyRefinedType(rtp, parents mapConserve abstractTypesToBounds, decls)
+ case AnnotatedType(_, underlying, _) =>
+ abstractTypesToBounds(underlying)
+ case _ =>
+ tp
+ }
// Set to true for A* => Seq[A]
// (And it will only rewrite A* in method result types.)
@@ -3298,8 +3330,8 @@ A type's typeSymbol should never be inspected directly.
case DeBruijnBinder(pnames, ptypes, restpe) =>
val isType = pnames.head.isTypeName
val newParams = for (name <- pnames) yield
- if (isType) owner.newTypeParameter(NoPosition, name.toTypeName)
- else owner.newValueParameter(NoPosition, name.toTermName)
+ if (isType) owner.newTypeParameter(name.toTypeName)
+ else owner.newValueParameter(name.toTermName)
paramStack = newParams :: paramStack
try {
(newParams, ptypes).zipped foreach ((p, t) => p setInfo this(t))
@@ -3347,7 +3379,9 @@ A type's typeSymbol should never be inspected directly.
/** Guard these lists against AnyClass and NothingClass appearing,
* else loBounds.isEmpty will have different results for an empty
- * constraint and one with Nothing as a lower bound.
+ * constraint and one with Nothing as a lower bound. [Actually
+ * guarding addLoBound/addHiBound somehow broke raw types so it
+ * only guards against being created with them.]
*/
private var lobounds = lo0 filterNot (_.typeSymbolDirect eq NothingClass)
private var hibounds = hi0 filterNot (_.typeSymbolDirect eq AnyClass)
@@ -3366,8 +3400,7 @@ A type's typeSymbol should never be inspected directly.
else if (!isNumericSubType(tp, numlo))
numlo = numericLoBound
}
- else if (tp.typeSymbolDirect ne NothingClass)
- lobounds ::= tp
+ else lobounds ::= tp
}
def checkWidening(tp: Type) {
@@ -3386,8 +3419,7 @@ A type's typeSymbol should never be inspected directly.
else if (!isNumericSubType(numhi, tp))
numhi = numericHiBound
}
- else if (tp.typeSymbolDirect ne AnyClass)
- hibounds ::= tp
+ else hibounds ::= tp
}
def isWithinBounds(tp: Type): Boolean =
@@ -3482,7 +3514,7 @@ A type's typeSymbol should never be inspected directly.
val hi1 = this(hi)
if ((lo1 eq lo) && (hi1 eq hi)) tp
else TypeBounds(lo1, hi1)
- case TypeRef(pre, sym, args) =>
+ case tr @ TypeRef(pre, sym, args) =>
val pre1 = this(pre)
val args1 =
if (args.isEmpty)
@@ -3495,7 +3527,7 @@ A type's typeSymbol should never be inspected directly.
else mapOverArgs(args, tparams)
}
if ((pre1 eq pre) && (args1 eq args)) tp
- else copyTypeRef(tp, pre1, coevolveSym(pre, pre1, sym), args1)
+ else copyTypeRef(tp, pre1, tr.coevolveSym(pre1), args1)
case _ =>
super.mapOver(tp)
}
@@ -3510,37 +3542,13 @@ A type's typeSymbol should never be inspected directly.
*/
def variance = 0
- // #3731: return sym1 for which holds: pre bound sym.name to sym and
- // pre1 now binds sym.name to sym1, conceptually exactly the same
- // symbol as sym. The selection of sym on pre must be updated to the
- // selection of sym1 on pre1, since sym's info was probably updated
- // by the TypeMap to yield a new symbol, sym1 with transformed info.
- // @returns sym1
- protected def coevolveSym(pre: Type, pre1: Type, sym: Symbol): Symbol =
- if((pre ne pre1) && sym.isAliasType) // only need to rebind type aliases here, as typeRef already handles abstract types (they are allowed to be rebound more liberally)
- (pre, pre1) match {
- case (RefinedType(_, decls), RefinedType(_, decls1)) => // don't look at parents -- it would be an error to override alias types anyway
- //val sym1 =
- decls1.lookup(sym.name)
-// assert(decls.lookupAll(sym.name).toList.length == 1)
-// assert(decls1.lookupAll(sym.name).toList.length == 1)
-// assert(sym1.isAliasType)
-// println("coevolved "+ sym +" : "+ sym.info +" to "+ sym1 +" : "+ sym1.info +" with "+ pre +" -> "+ pre1)
-// sym1
- case _ => // TODO: is there another way a typeref's symbol can refer to a symbol defined in its pre?
-// val sym1 = pre1.nonPrivateMember(sym.name).suchThat(sym => sym.isAliasType)
-// println("??coevolve "+ sym +" : "+ sym.info +" to "+ sym1 +" : "+ sym1.info +" with "+ pre +" -> "+ pre1)
- sym
- }
- else sym
-
/** Map this function over given type */
def mapOver(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args) =>
+ case tr @ TypeRef(pre, sym, args) =>
val pre1 = this(pre)
val args1 = args mapConserve this
if ((pre1 eq pre) && (args1 eq args)) tp
- else copyTypeRef(tp, pre1, coevolveSym(pre, pre1, sym), args1)
+ else copyTypeRef(tp, pre1, tr.coevolveSym(pre1), args1)
case ThisType(_) => tp
case SingleType(pre, sym) =>
if (sym.isPackageClass) tp // short path
@@ -3732,7 +3740,7 @@ A type's typeSymbol should never be inspected directly.
def typeParamsToExistentials(clazz: Symbol, tparams: List[Symbol]): List[Symbol] = {
val eparams = mapWithIndex(tparams)((tparam, i) =>
- clazz.newExistential(clazz.pos, newTypeName("?"+i)) setInfo tparam.info.bounds)
+ clazz.newExistential(newTypeName("?"+i), clazz.pos) setInfo tparam.info.bounds)
eparams map (_ substInfo (tparams, eparams))
}
@@ -3854,10 +3862,10 @@ A type's typeSymbol should never be inspected directly.
if (tree.symbol isNonBottomSubClass clazz) &&
(pre.widen.typeSymbol isNonBottomSubClass tree.symbol) =>
if (pre.isStable) { // XXX why is this in this method? pull it out and guard the call `annotationArgRewriter.transform(tree)`?
- val termSym =
- pre.typeSymbol.owner.newValue(
- pre.typeSymbol.pos,
- pre.typeSymbol.name.toTermName).setInfo(pre) // what symbol should really be used?
+ val termSym = (
+ pre.typeSymbol.owner.newValue(pre.typeSymbol.name.toTermName, pre.typeSymbol.pos) // what symbol should really be used?
+ setInfo pre
+ )
gen.mkAttributedQualifier(pre, termSym)
} else
giveup()
@@ -4211,7 +4219,7 @@ A type's typeSymbol should never be inspected directly.
val symowner = oldSym.owner
val bound = singletonBounds(actualsIndexed(actualIdx))
- val sym = symowner.newExistential(oldSym.pos, newTypeName(oldSym.name + ".type"))
+ val sym = symowner.newExistential(newTypeName(oldSym.name + ".type"), oldSym.pos)
sym.setInfo(bound)
sym.setFlag(oldSym.flags)
@@ -4599,7 +4607,7 @@ A type's typeSymbol should never be inspected directly.
*/
def needsOuterTest(patType: Type, selType: Type, currentOwner: Symbol) = {
def createDummyClone(pre: Type): Type = {
- val dummy = currentOwner.enclClass.newValue(NoPosition, nme.ANYNAME).setInfo(pre.widen)
+ val dummy = currentOwner.enclClass.newValue(nme.ANYNAME).setInfo(pre.widen)
singleType(ThisType(currentOwner.enclClass), dummy)
}
def maybeCreateDummyClone(pre: Type, sym: Symbol): Type = pre match {
@@ -5539,10 +5547,6 @@ A type's typeSymbol should never be inspected directly.
}
/** Do type arguments `targs` conform to formal parameters `tparams`?
- *
- * @param tparams ...
- * @param targs ...
- * @return ...
*/
def isWithinBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): Boolean = {
var bounds = instantiatedBounds(pre, owner, tparams, targs)
@@ -5902,7 +5906,7 @@ A type's typeSymbol should never be inspected directly.
else {
def lubBounds(bnds: List[TypeBounds]): TypeBounds =
TypeBounds(glb(bnds map (_.lo), decr(depth)), lub(bnds map (_.hi), decr(depth)))
- lubRefined.typeSymbol.newAbstractType(proto.pos, proto.name.toTypeName)
+ lubRefined.typeSymbol.newAbstractType(proto.name.toTypeName, proto.pos)
.setInfoOwnerAdjusted(lubBounds(symtypes map (_.bounds)))
}
}
@@ -6102,6 +6106,26 @@ A type's typeSymbol should never be inspected directly.
if (ts exists (_.isNotNull)) res.notNull else res
}
+
+ /** A list of the typevars in a type. */
+ def typeVarsInType(tp: Type): List[TypeVar] = {
+ var tvs: List[TypeVar] = Nil
+ tp foreach {
+ case t: TypeVar => tvs ::= t
+ case _ =>
+ }
+ tvs.reverse
+ }
+ /** Make each type var in this type use its original type for comparisons instead
+ * of collecting constraints.
+ */
+ def suspendTypeVarsInType(tp: Type): List[TypeVar] = {
+ val tvs = typeVarsInType(tp)
+ // !!! Is it somehow guaranteed that this will not break under nesting?
+ // In general one has to save and restore the contents of the field...
+ tvs foreach (_.suspended = true)
+ tvs
+ }
/** Compute lub (if `variance == 1`) or glb (if `variance == -1`) of given list
* of types `tps`. All types in `tps` are typerefs or singletypes
diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
index 0789f9c774..b21b33e138 100644
--- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
@@ -297,11 +297,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
case MODULEsym =>
val clazz = at(inforef, () => readType()).typeSymbol // after the NMT_TRANSITION period, we can leave off the () => ... ()
if (isModuleRoot) moduleRoot
- else {
- val m = owner.newModule(name.toTermName, clazz)
- clazz.sourceModule = m
- m
- }
+ else owner.newLinkedModule(clazz)
case VALsym =>
if (isModuleRoot) { assert(false); NoSymbol }
else if (isMethodFlag) owner.newMethod(name.toTermName)
diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala
index c8cb6febfa..d59fc6d564 100644
--- a/src/compiler/scala/reflect/internal/transform/Erasure.scala
+++ b/src/compiler/scala/reflect/internal/transform/Erasure.scala
@@ -59,7 +59,7 @@ trait Erasure {
// included (use pre.baseType(cls.owner)).
//
// This requires that cls.isClass.
- @inline protected def rebindInnerClass(pre: Type, cls: Symbol): Type = {
+ protected def rebindInnerClass(pre: Type, cls: Symbol): Type = {
if (cls.owner.isClass) cls.owner.tpe else pre // why not cls.isNestedClass?
}
@@ -75,7 +75,7 @@ trait Erasure {
case TypeRef(pre, sym, args) =>
if (sym == ArrayClass)
if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe
- else if (args.head.typeSymbol.isBottomClass) arrayType(ObjectClass.tpe)
+ else if (args.head.typeSymbol.isBottomClass) ObjectArray
else typeRef(apply(pre), sym, args map this)
else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) erasedTypeRef(ObjectClass)
else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass)
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
index 9da75bf2b0..bc5d616ae3 100644
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala
@@ -45,7 +45,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
def javaClass(path: String): jClass[_] =
javaClass(path, defaultReflectiveClassLoader())
def javaClass(path: String, classLoader: JClassLoader): jClass[_] =
- classLoader.loadClass(path)
+ Class.forName(path, true, classLoader)
/** Does `path` correspond to a Java class with that fully qualified name? */
def isJavaClass(path: String): Boolean =
@@ -115,7 +115,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
* @param jtvar The Java type variable
*/
private def createTypeParameter(jtvar: jTypeVariable[_ <: GenericDeclaration]): Symbol = {
- val tparam = sOwner(jtvar).newTypeParameter(NoPosition, newTypeName(jtvar.getName))
+ val tparam = sOwner(jtvar).newTypeParameter(newTypeName(jtvar.getName))
.setInfo(new TypeParamCompleter(jtvar))
tparamCache enter (jtvar, tparam)
tparam
@@ -154,7 +154,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
override def load(sym: Symbol) = {
debugInfo("completing from Java " + sym + "/" + clazz.fullName)//debug
assert(sym == clazz || (module != NoSymbol && (sym == module || sym == module.moduleClass)), sym)
- val flags = toScalaFlags(jclazz.getModifiers, isClass = true)
+ val flags = toScalaClassFlags(jclazz.getModifiers)
clazz setFlag (flags | JAVA)
if (module != NoSymbol) {
module setFlag (flags & PRIVATE | JAVA)
@@ -335,10 +335,9 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
val name = newTermName(fullname drop (split + 1))
var pkg = owner.info decl name
if (pkg == NoSymbol) {
- pkg = owner.newPackage(NoPosition, name)
+ pkg = owner.newPackage(name)
pkg.moduleClass setInfo new LazyPackageType
- pkg setInfo pkg.moduleClass.tpe
- owner.info.decls enter pkg
+ pkg setInfoAndEnter pkg.moduleClass.tpe
info("made Scala "+pkg)
} else if (!pkg.isPackage)
throw new ReflectError(pkg+" is not a package")
@@ -407,7 +406,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
val tparams = new ListBuffer[Symbol]
def targToScala(arg: jType): Type = arg match {
case jwild: WildcardType =>
- val tparam = owner.newExistential(NoPosition, newTypeName("T$" + tparams.length))
+ val tparam = owner.newExistential(newTypeName("T$" + tparams.length))
.setInfo(TypeBounds(
lub(jwild.getLowerBounds.toList map typeToScala),
glb(jwild.getUpperBounds.toList map typeToScala map objToAny)))
@@ -468,9 +467,11 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
* @return A Scala value symbol that wraps all reflection info of `jfield`
*/
private def jfieldAsScala(jfield: jField): Symbol = fieldCache.toScala(jfield) {
- val field = sOwner(jfield).newValue(NoPosition, newTermName(jfield.getName))
- .setFlag(toScalaFlags(jfield.getModifiers, isField = true) | JAVA)
- .setInfo(typeToScala(jfield.getGenericType))
+ val field = (
+ sOwner(jfield)
+ newValue(newTermName(jfield.getName), NoPosition, toScalaFieldFlags(jfield.getModifiers))
+ setInfo typeToScala(jfield.getGenericType)
+ )
fieldCache enter (jfield, field)
copyAnnotations(field, jfield)
field
@@ -488,8 +489,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
*/
private def jmethodAsScala(jmeth: jMethod): Symbol = methodCache.toScala(jmeth) {
val clazz = sOwner(jmeth)
- val meth = clazz.newMethod(NoPosition, newTermName(jmeth.getName))
- .setFlag(toScalaFlags(jmeth.getModifiers) | JAVA)
+ val meth = clazz.newMethod(newTermName(jmeth.getName), NoPosition, toScalaMethodFlags(jmeth.getModifiers))
methodCache enter (jmeth, meth)
val tparams = jmeth.getTypeParameters.toList map createTypeParameter
val paramtpes = jmeth.getGenericParameterTypes.toList map typeToScala
@@ -511,8 +511,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
private def jconstrAsScala(jconstr: jConstructor[_]): Symbol = {
// [Martin] Note: I know there's a lot of duplication wrt jmethodAsScala, but don't think it's worth it to factor this out.
val clazz = sOwner(jconstr)
- val constr = clazz.newMethod(NoPosition, nme.CONSTRUCTOR)
- .setFlag(toScalaFlags(jconstr.getModifiers) | JAVA)
+ val constr = clazz.newConstructor(NoPosition, toScalaMethodFlags(jconstr.getModifiers))
constructorCache enter (jconstr, constr)
val tparams = jconstr.getTypeParameters.toList map createTypeParameter
val paramtpes = jconstr.getGenericParameterTypes.toList map typeToScala
diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala
index 35b3a16dc2..7aca052fa9 100644
--- a/src/compiler/scala/reflect/runtime/Loaders.scala
+++ b/src/compiler/scala/reflect/runtime/Loaders.scala
@@ -63,8 +63,8 @@ trait Loaders { self: SymbolTable =>
*/
protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = {
assert(!(name.toString endsWith "[]"), name)
- val clazz = owner.newClass(NoPosition, name)
- val module = owner.newModule(NoPosition, name.toTermName)
+ val clazz = owner.newClass(name)
+ val module = owner.newModule(name.toTermName)
owner.info.decls enter clazz
owner.info.decls enter module
initClassModule(clazz, module, completer(clazz, module))
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
index 9490dc4ad7..09a4bbe198 100644
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ b/src/compiler/scala/reflect/runtime/Mirror.scala
@@ -12,7 +12,16 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe
import definitions._
- def classWithName(name: String): Symbol = classToScala(javaClass(name))
+ def classWithName(name: String): Symbol = {
+ val clazz = javaClass(name, defaultReflectiveClassLoader())
+ classToScala(clazz)
+ }
+
+ def getCompanionObject(clazz: Symbol): AnyRef = {
+ val singleton = ReflectionUtils.singletonInstance(clazz.fullName, defaultReflectiveClassLoader())
+ singleton
+ }
+
def getClass(obj: AnyRef): Symbol = classToScala(obj.getClass)
def getType(obj: AnyRef): Type = typeToScala(obj.getClass)
// to do add getClass/getType for instances of primitive types, probably like this:
@@ -32,7 +41,9 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe
case nme.update => return Array.set(receiver, args(0).asInstanceOf[Int], args(1))
}
}
- methodToJava(meth).invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
+
+ val jmeth = methodToJava(meth)
+ jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
}
override def classToType(jclazz: java.lang.Class[_]): Type = typeToScala(jclazz)
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
index 231bcdbc0e..8afd6d2231 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
@@ -41,9 +41,12 @@ trait ToolBoxes extends { self: Universe =>
private def isFree(t: Tree) = t.isInstanceOf[Ident] && t.symbol.isInstanceOf[FreeVar]
def typedTopLevelExpr(tree: Tree, pt: Type): Tree = {
- val ownerClass = EmptyPackageClass.newClass(newTypeName("<expression-owner>"))
- ownerClass.setInfo(new ClassInfoType(List(ObjectClass.tpe), newScope, ownerClass))
- val owner = ownerClass.newLocalDummy(tree.pos)
+ // !!! Why is this is in the empty package? If it's only to make
+ // it inaccessible then please put it somewhere designed for that
+ // rather than polluting the empty package with synthetics.
+ val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName("<expression-owner>"), List(ObjectClass.tpe), newScope)
+ val owner = ownerClass.newLocalDummy(tree.pos)
+
typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt)
}
@@ -53,12 +56,12 @@ trait ToolBoxes extends { self: Universe =>
}
def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = {
- val obj = EmptyPackageClass.newModule(NoPosition, nextWrapperModuleName())
+ val obj = EmptyPackageClass.newModule(nextWrapperModuleName())
val minfo = ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), new Scope, obj.moduleClass)
obj.moduleClass setInfo minfo
obj setInfo obj.moduleClass.tpe
- val meth = obj.moduleClass.newMethod(NoPosition, newTermName(wrapperMethodName))
- def makeParam(fv: Symbol) = meth.newValueParameter(NoPosition, fv.name.toTermName) setInfo fv.tpe
+ val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName))
+ def makeParam(fv: Symbol) = meth.newValueParameter(fv.name.toTermName) setInfo fv.tpe
meth setInfo MethodType(fvs map makeParam, expr.tpe)
minfo.decls enter meth
trace("wrapping ")(defOwner(expr) -> meth)
diff --git a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
index 9d66ca6c6e..fc4177e956 100644
--- a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
+++ b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
@@ -39,7 +39,7 @@ trait TreeBuildUtil extends Universe with api.TreeBuildUtil {
selectIn(owner.info, idx)
}
- def freeVar(name: String, info: Type, value: Any) = new FreeVar(newTermName(name), info, value)
+ def freeVar(name: String, info: Type, value: Any) = newFreeVar(newTermName(name), info, value)
def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers =
Modifiers(flags, privateWithin, annotations)
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala
index 7aff4e3e8e..04ff0c440d 100644
--- a/src/compiler/scala/tools/ant/Scalac.scala
+++ b/src/compiler/scala/tools/ant/Scalac.scala
@@ -608,7 +608,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
if (!deprecation.isEmpty) settings.deprecation.value = deprecation.get
if (!nobootcp.isEmpty) settings.nobootcp.value = nobootcp.get
if (!nowarn.isEmpty) settings.nowarn.value = nowarn.get
- if (!optimise.isEmpty) settings.XO.value = optimise.get
+ if (!optimise.isEmpty) settings.optimise.value = optimise.get
if (!unchecked.isEmpty) settings.unchecked.value = unchecked.get
if (!usejavacp.isEmpty) settings.usejavacp.value = usejavacp.get
diff --git a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
index 9f1fbc4524..5949689b24 100644
--- a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
+++ b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
@@ -86,4 +86,6 @@ goto :eof
:end
@@endlocal
-exit /b %errorlevel%
+
+REM exit code fix, see http://stackoverflow.com/questions/4632891/exiting-batch-with-exit-b-x-where-x-1-acts-as-if-command-completed-successfu
+@@%COMSPEC% /C exit %errorlevel% >nul
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index c388a62644..e805b4e75e 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -193,10 +193,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def inform[T](msg: String, value: T): T = returning(value)(x => inform(msg + x))
def informTime(msg: String, start: Long) = informProgress(elapsedMessage(msg, start))
- def logResult[T](msg: String)(result: T): T = {
- log(msg + ": " + result)
- result
- }
def logError(msg: String, t: Throwable): Unit = ()
// Over 200 closure objects are eliminated by inlining this.
@inline final def log(msg: => AnyRef): Unit =
@@ -905,6 +901,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** Counts for certain classes of warnings during this run. */
var deprecationWarnings: List[(Position, String)] = Nil
var uncheckedWarnings: List[(Position, String)] = Nil
+
+ /** A flag whether macro expansions failed */
+ var macroExpansionFailed = false
/** Progress tracking. Measured in "progress units" which are 1 per
* compilation unit per phase completed.
@@ -1087,6 +1086,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
)
warn(deprecationWarnings.size, "deprecation", settings.deprecation)
warn(uncheckedWarnings.size, "unchecked", settings.unchecked)
+ if (macroExpansionFailed)
+ warning("some macros could not be expanded and code fell back to overridden methods;"+
+ "\nrecompiling with generated classfiles on the classpath might help.")
// todo: migrationWarnings
}
}
diff --git a/src/compiler/scala/tools/nsc/MacroContext.scala b/src/compiler/scala/tools/nsc/MacroContext.scala
index e739eade3a..72662291f8 100644
--- a/src/compiler/scala/tools/nsc/MacroContext.scala
+++ b/src/compiler/scala/tools/nsc/MacroContext.scala
@@ -2,7 +2,7 @@ package scala.tools.nsc
import symtab.Flags._
-trait MacroContext extends reflect.api.MacroContext { self: Global =>
+trait MacroContext extends reflect.macro.Context { self: Global =>
def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index e69c463e71..265d017653 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -30,6 +30,25 @@ abstract class TreeGen extends reflect.internal.TreeGen {
else
tree
}
+
+ /** Builds a fully attributed wildcard import node.
+ */
+ def mkWildcardImport(pkg: Symbol): Import = {
+ assert(pkg ne null, this)
+ val qual = gen.mkAttributedStableRef(pkg)
+ val importSym = (
+ NoSymbol
+ newImport NoPosition
+ setFlag SYNTHETIC
+ setInfo analyzer.ImportType(qual)
+ )
+ val importTree = (
+ Import(qual, List(ImportSelector(nme.WILDCARD, -1, null, -1)))
+ setSymbol importSym
+ setType NoType
+ )
+ importTree
+ }
// wrap the given expression in a SoftReference so it can be gc-ed
def mkSoftRef(expr: Tree): Tree = atPos(expr.pos) {
@@ -77,17 +96,17 @@ abstract class TreeGen extends reflect.internal.TreeGen {
}
def mkModuleVarDef(accessor: Symbol) = {
+ val inClass = accessor.owner.isClass
+ val extraFlags = if (inClass) PrivateLocal | SYNTHETIC else 0
+
val mval = (
- accessor.owner.newVariable(accessor.pos.focus, nme.moduleVarName(accessor.name))
- setInfo accessor.tpe.finalResultType
- setFlag (MODULEVAR)
+ accessor.owner.newVariable(nme.moduleVarName(accessor.name), accessor.pos.focus, MODULEVAR | extraFlags)
+ setInfo accessor.tpe.finalResultType
+ addAnnotation VolatileAttr
)
+ if (inClass)
+ mval.owner.info.decls enter mval
- mval addAnnotation VolatileAttr
- if (mval.owner.isClass) {
- mval setFlag (PrivateLocal | SYNTHETIC)
- mval.owner.info.decls.enter(mval)
- }
ValDef(mval)
}
@@ -199,11 +218,7 @@ abstract class TreeGen extends reflect.internal.TreeGen {
*/
private def mkPackedValDef(expr: Tree, owner: Symbol, name: Name): (ValDef, () => Ident) = {
val packedType = typer.packedType(expr, owner)
- val sym = (
- owner.newValue(expr.pos.makeTransparent, name)
- setFlag SYNTHETIC
- setInfo packedType
- )
+ val sym = owner.newValue(name, expr.pos.makeTransparent, SYNTHETIC) setInfo packedType
(ValDef(sym, expr), () => Ident(sym) setPos sym.pos.focus setType expr.tpe)
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
index 7388ecf163..46ade7d889 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
@@ -117,7 +117,7 @@ trait MarkupParsers {
* | `{` scalablock `}`
*/
def xAttributes = {
- val aMap = mutable.HashMap[String, Tree]()
+ val aMap = mutable.LinkedHashMap[String, Tree]()
while (isNameStart(ch)) {
val start = curOffset
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index d7bfcfc314..fe6dcc9138 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -28,14 +28,17 @@ trait ParsersCommon extends ScannersCommon {
val global : Global
import global._
- trait ParserCommon {
+ /** This is now an abstract class, only to work around the optimizer:
+ * methods in traits are never inlined.
+ */
+ abstract class ParserCommon {
val in: ScannerCommon
def freshName(prefix: String): Name
def freshTermName(prefix: String): TermName
def freshTypeName(prefix: String): TypeName
def deprecationWarning(off: Int, msg: String): Unit
def accept(token: Int): Int
-
+
/** Methods inParensOrError and similar take a second argument which, should
* the next token not be the expected opener (e.g. LPAREN) will be returned
* instead of the contents of the groupers. However in all cases accept(LPAREN)
@@ -123,8 +126,6 @@ self =>
val global: Global
import global._
- private val glob: global.type = global
-
case class OpInfo(operand: Tree, operator: Name, offset: Offset)
class SourceFileParser(val source: SourceFile) extends Parser {
@@ -616,7 +617,7 @@ self =>
def isLiteralToken(token: Int) = token match {
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT |
- STRINGLIT | STRINGPART | SYMBOLLIT | TRUE | FALSE | NULL => true
+ STRINGLIT | INTERPOLATIONID | SYMBOLLIT | TRUE | FALSE | NULL => true
case _ => false
}
def isLiteral = isLiteralToken(in.token)
@@ -1102,7 +1103,7 @@ self =>
* }}}
* @note The returned tree does not yet have a position
*/
- def literal(isNegated: Boolean): Tree = {
+ def literal(isNegated: Boolean = false): Tree = {
def finish(value: Any): Tree = {
val t = Literal(Constant(value))
in.nextToken()
@@ -1110,19 +1111,19 @@ self =>
}
if (in.token == SYMBOLLIT)
Apply(scalaDot(nme.Symbol), List(finish(in.strVal)))
- else if (in.token == STRINGPART)
+ else if (in.token == INTERPOLATIONID)
interpolatedString()
else finish(in.token match {
- case CHARLIT => in.charVal
- case INTLIT => in.intVal(isNegated).toInt
- case LONGLIT => in.intVal(isNegated)
- case FLOATLIT => in.floatVal(isNegated).toFloat
- case DOUBLELIT => in.floatVal(isNegated)
- case STRINGLIT => in.strVal.intern()
- case TRUE => true
- case FALSE => false
- case NULL => null
- case _ =>
+ case CHARLIT => in.charVal
+ case INTLIT => in.intVal(isNegated).toInt
+ case LONGLIT => in.intVal(isNegated)
+ case FLOATLIT => in.floatVal(isNegated).toFloat
+ case DOUBLELIT => in.floatVal(isNegated)
+ case STRINGLIT | STRINGPART => in.strVal.intern()
+ case TRUE => true
+ case FALSE => false
+ case NULL => null
+ case _ =>
syntaxErrorOrIncomplete("illegal literal", true)
null
})
@@ -1137,16 +1138,27 @@ self =>
}
}
- private def interpolatedString(): Tree = {
- var t = atPos(o2p(in.offset))(New(TypeTree(definitions.StringBuilderClass.tpe), List(List())))
+ private def interpolatedString(): Tree = atPos(in.offset) {
+ val start = in.offset
+ val interpolator = in.name
+
+ val partsBuf = new ListBuffer[Tree]
+ val exprBuf = new ListBuffer[Tree]
+ in.nextToken()
while (in.token == STRINGPART) {
- t = stringOp(t, nme.append)
- var e = expr()
- if (in.token == STRINGFMT) e = stringOp(e, nme.formatted)
- t = atPos(t.pos.startOrPoint)(Apply(Select(t, nme.append), List(e)))
+ partsBuf += literal()
+ exprBuf += {
+ if (in.token == IDENTIFIER) atPos(in.offset)(Ident(ident()))
+ else expr()
+ }
}
- if (in.token == STRINGLIT) t = stringOp(t, nme.append)
- atPos(t.pos)(Select(t, nme.toString_))
+ if (in.token == STRINGLIT) partsBuf += literal()
+
+ val t1 = atPos(o2p(start)) { Ident(nme.StringContext) }
+ val t2 = atPos(start) { Apply(t1, partsBuf.toList) }
+ t2 setPos t2.pos.makeTransparent
+ val t3 = Select(t2, interpolator) setPos t2.pos
+ atPos(start) { Apply(t3, exprBuf.toList) }
}
/* ------------- NEW LINES ------------------------------------------------- */
@@ -1468,7 +1480,7 @@ self =>
atPos(in.offset) {
val name = nme.toUnaryName(rawIdent())
// val name = nme.toUnaryName(ident()) // val name: Name = "unary_" + ident()
- if (name == nme.UNARY_- && isNumericLit) simpleExprRest(atPos(in.offset)(literal(true)), true)
+ if (name == nme.UNARY_- && isNumericLit) simpleExprRest(atPos(in.offset)(literal(isNegated = true)), true)
else Select(stripParens(simpleExpr()), name)
}
}
@@ -1492,7 +1504,7 @@ self =>
def simpleExpr(): Tree = {
var canApply = true
val t =
- if (isLiteral) atPos(in.offset)(literal(false))
+ if (isLiteral) atPos(in.offset)(literal())
else in.token match {
case XMLSTART =>
xmlLiteral()
@@ -1826,7 +1838,7 @@ self =>
case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT =>
t match {
case Ident(nme.MINUS) =>
- return atPos(start) { literal(true) }
+ return atPos(start) { literal(isNegated = true) }
case _ =>
}
case _ =>
@@ -1843,8 +1855,8 @@ self =>
in.nextToken()
atPos(start, start) { Ident(nme.WILDCARD) }
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT |
- STRINGLIT | STRINGPART | SYMBOLLIT | TRUE | FALSE | NULL =>
- atPos(start) { literal(false) }
+ STRINGLIT | INTERPOLATIONID | SYMBOLLIT | TRUE | FALSE | NULL =>
+ atPos(start) { literal() }
case LPAREN =>
atPos(start)(makeParens(noSeq.patterns()))
case XMLSTART =>
@@ -2437,7 +2449,7 @@ self =>
else {
val nameOffset = in.offset
val name = ident()
- if (name == nme.macro_ && isIdent && settings.Xexperimental.value)
+ if (name == nme.macro_ && isIdent && settings.Xmacros.value)
funDefRest(start, in.offset, mods | Flags.MACRO, ident())
else
funDefRest(start, nameOffset, mods, name)
@@ -2468,6 +2480,9 @@ self =>
restype = scalaUnitConstr
blockExpr()
} else {
+ if (name == nme.macro_ && isIdent && in.token != EQUALS) {
+ warning("this syntactically invalid code resembles a macro definition. have you forgotten to enable -Xmacros?")
+ }
equalsExpr()
}
DefDef(newmods, name, tparams, vparamss, restype, rhs)
@@ -2527,7 +2542,7 @@ self =>
newLinesOpt()
atPos(start, in.offset) {
val name = identForType()
- if (name == nme.macro_.toTypeName && isIdent && settings.Xexperimental.value) {
+ if (name == nme.macro_.toTypeName && isIdent && settings.Xmacros.value) {
funDefRest(start, in.offset, mods | Flags.MACRO, identForType())
} else {
// @M! a type alias as well as an abstract type may declare type parameters
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index a25b3afbc6..a2a577a7ab 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -161,12 +161,25 @@ trait Scanners extends ScannersCommon {
* RBRACKET if region starts with '['
* RBRACE if region starts with '{'
* ARROW if region starts with `case'
- * STRINGFMT if region is a string interpolation expression starting with '\{'
+ * 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).
*/
var sepRegions: List[Int] = List()
// Get next token ------------------------------------------------------------
+ /** Are we directly in a string interpolation expression?
+ */
+ @inline private def inStringInterpolation =
+ sepRegions.nonEmpty && sepRegions.head == STRINGLIT
+
+ /** Are we directly in a multiline string interpolation expression?
+ * @pre: inStringInterpolation
+ */
+ @inline private def inMultiLineInterpolation =
+ sepRegions.tail.nonEmpty && sepRegions.tail.head == STRINGPART
+
/** read next token and return last offset
*/
def skipToken(): Offset = {
@@ -189,29 +202,31 @@ trait Scanners extends ScannersCommon {
sepRegions = RBRACE :: sepRegions
case CASE =>
sepRegions = ARROW :: sepRegions
- case STRINGPART =>
- sepRegions = STRINGFMT :: sepRegions
case RBRACE =>
- sepRegions = sepRegions dropWhile (_ != RBRACE)
+ while (!sepRegions.isEmpty && sepRegions.head != RBRACE)
+ sepRegions = sepRegions.tail
if (!sepRegions.isEmpty) sepRegions = sepRegions.tail
- case RBRACKET | RPAREN | ARROW | STRINGFMT =>
+ docBuffer = null
+ case RBRACKET | RPAREN =>
if (!sepRegions.isEmpty && sepRegions.head == lastToken)
sepRegions = sepRegions.tail
- case _ =>
- }
- (lastToken: @switch) match {
- case RBRACE | RBRACKET | RPAREN =>
docBuffer = null
+ case ARROW =>
+ if (!sepRegions.isEmpty && sepRegions.head == lastToken)
+ sepRegions = sepRegions.tail
+ case STRINGLIT =>
+ if (inStringInterpolation)
+ sepRegions = sepRegions.tail
case _ =>
}
-
+
// Read a token or copy it from `next` tokenData
if (next.token == EMPTY) {
lastOffset = charOffset - 1
- if(lastOffset > 0 && buf(lastOffset) == '\n' && buf(lastOffset - 1) == '\r') {
+ if (lastOffset > 0 && buf(lastOffset) == '\n' && buf(lastOffset - 1) == '\r') {
lastOffset -= 1
}
- fetchToken()
+ if (inStringInterpolation) fetchStringPart() else fetchToken()
} else {
this copyFrom next
next.token = EMPTY
@@ -308,7 +323,9 @@ trait Scanners extends ScannersCommon {
'z' =>
putChar(ch)
nextChar()
- getIdentRest() // scala-mode: wrong indent for multi-line case blocks
+ getIdentRest()
+ if (ch == '"' && token == IDENTIFIER && settings.Xexperimental.value)
+ token = INTERPOLATIONID
case '<' => // is XMLSTART?
val last = if (charOffset >= 2) buf(charOffset - 2) else ' '
nextChar()
@@ -360,18 +377,37 @@ trait Scanners extends ScannersCommon {
case '`' =>
getBackquotedIdent()
case '\"' =>
- nextChar()
- if (ch == '\"') {
- nextChar()
+ if (token == INTERPOLATIONID) {
+ nextRawChar()
if (ch == '\"') {
nextRawChar()
- getMultiLineStringLit()
+ if (ch == '\"') {
+ nextRawChar()
+ getStringPart(multiLine = true)
+ sepRegions = STRINGLIT :: sepRegions // indicate string part
+ sepRegions = STRINGLIT :: sepRegions // once more to indicate multi line string part
+ } else {
+ token = STRINGLIT
+ strVal = ""
+ }
} else {
- token = STRINGLIT
- strVal = ""
+ getStringPart(multiLine = false)
+ sepRegions = STRINGLIT :: sepRegions // indicate single line string part
}
} else {
- getStringPart()
+ nextChar()
+ if (ch == '\"') {
+ nextChar()
+ if (ch == '\"') {
+ nextRawChar()
+ getRawStringLit()
+ } else {
+ token = STRINGLIT
+ strVal = ""
+ }
+ } else {
+ getStringLit()
+ }
}
case '\'' =>
nextChar()
@@ -397,9 +433,7 @@ trait Scanners extends ScannersCommon {
token = DOT
}
case ';' =>
- nextChar()
- if (inStringInterpolation) getFormatString()
- else token = SEMI
+ nextChar(); token = SEMI
case ',' =>
nextChar(); token = COMMA
case '(' =>
@@ -409,16 +443,7 @@ trait Scanners extends ScannersCommon {
case ')' =>
nextChar(); token = RPAREN
case '}' =>
- if (token == STRINGFMT) {
- nextChar()
- getStringPart()
- } else if (inStringInterpolation) {
- strVal = "";
- token = STRINGFMT
- } else {
- nextChar();
- token = RBRACE
- }
+ nextChar(); token = RBRACE
case '[' =>
nextChar(); token = LBRACKET
case ']' =>
@@ -506,11 +531,6 @@ trait Scanners extends ScannersCommon {
}
}
- /** Are we directly in a string interpolation expression?
- */
- private def inStringInterpolation =
- sepRegions.nonEmpty && sepRegions.head == STRINGFMT
-
/** Can token start a statement? */
def inFirstOfStat(token: Int) = token match {
case EOF | CATCH | ELSE | EXTENDS | FINALLY | FORSOME | MATCH | WITH | YIELD |
@@ -608,71 +628,110 @@ trait Scanners extends ScannersCommon {
else finishNamed()
}
}
+
+
+// Literals -----------------------------------------------------------------
- def getFormatString() = {
- getLitChars('}', '"', ' ', '\t')
- if (ch == '}') {
- setStrVal()
- if (strVal.length > 0) strVal = "%" + strVal
- token = STRINGFMT
- } else {
- syntaxError("unclosed format string")
- }
- }
-
- def getStringPart() = {
- while (ch != '"' && (ch != CR && ch != LF && ch != SU || isUnicodeEscape) && maybeGetLitChar()) {}
+ private def getStringLit() = {
+ getLitChars('"')
if (ch == '"') {
setStrVal()
nextChar()
token = STRINGLIT
- } else if (ch == '{' && settings.Xexperimental.value) {
- setStrVal()
- nextChar()
- token = STRINGPART
- } else {
- syntaxError("unclosed string literal")
- }
+ } else syntaxError("unclosed string literal")
}
- private def getMultiLineStringLit() {
+ private def getRawStringLit(): Unit = {
if (ch == '\"') {
nextRawChar()
- if (ch == '\"') {
+ if (isTripleQuote()) {
+ setStrVal()
+ token = STRINGLIT
+ } else
+ getRawStringLit()
+ } else if (ch == SU) {
+ incompleteInputError("unclosed multi-line string literal")
+ } else {
+ putChar(ch)
+ nextRawChar()
+ getRawStringLit()
+ }
+ }
+
+ @annotation.tailrec private def getStringPart(multiLine: Boolean): Unit = {
+ def finishStringPart() = {
+ setStrVal()
+ token = STRINGPART
+ next.lastOffset = charOffset - 1
+ next.offset = charOffset - 1
+ }
+ if (ch == '"') {
+ nextRawChar()
+ if (!multiLine || isTripleQuote()) {
+ setStrVal()
+ token = STRINGLIT
+ } else
+ getStringPart(multiLine)
+ } else if (ch == '$') {
+ nextRawChar()
+ if (ch == '$') {
+ putChar(ch)
nextRawChar()
- if (ch == '\"') {
- nextChar()
- while (ch == '\"') {
- putChar('\"')
- nextChar()
- }
- token = STRINGLIT
- setStrVal()
- } else {
- putChar('\"')
- putChar('\"')
- getMultiLineStringLit()
- }
+ getStringPart(multiLine)
+ } else if (ch == '{') {
+ finishStringPart()
+ nextRawChar()
+ next.token = LBRACE
+ } else if (Character.isUnicodeIdentifierStart(ch)) {
+ finishStringPart()
+ do {
+ putChar(ch)
+ nextRawChar()
+ } while (Character.isUnicodeIdentifierPart(ch))
+ next.token = IDENTIFIER
+ next.name = newTermName(cbuf.toString)
+ cbuf.clear()
} else {
- putChar('\"')
- getMultiLineStringLit()
+ syntaxError("invalid string interpolation")
}
- } else if (ch == SU) {
- incompleteInputError("unclosed multi-line string literal")
+ } else if ((ch == CR || ch == LF || ch == SU) && !isUnicodeEscape) {
+ syntaxError("unclosed string literal")
} else {
putChar(ch)
nextRawChar()
- getMultiLineStringLit()
+ getStringPart(multiLine)
}
}
+
+ private def fetchStringPart() = {
+ offset = charOffset - 1
+ getStringPart(multiLine = inMultiLineInterpolation)
+ }
+
+ private def isTripleQuote(): Boolean =
+ if (ch == '"') {
+ nextRawChar()
+ if (ch == '"') {
+ nextChar()
+ while (ch == '"') {
+ putChar('"')
+ nextChar()
+ }
+ true
+ } else {
+ putChar('"')
+ putChar('"')
+ false
+ }
+ } else {
+ putChar('"')
+ false
+ }
-// Literals -----------------------------------------------------------------
-
- /** read next character in character or string literal:
- * if character sequence is a \{ escape, do not copy it into the string and return false.
- * otherwise return true.
+ /** copy current character into cbuf, interpreting any escape sequences,
+ * and advance to next character.
*/
- protected def maybeGetLitChar(): Boolean = {
+ protected def getLitChar(): Unit =
if (ch == '\\') {
nextChar()
if ('0' <= ch && ch <= '7') {
@@ -698,7 +757,6 @@ trait Scanners extends ScannersCommon {
case '\"' => putChar('\"')
case '\'' => putChar('\'')
case '\\' => putChar('\\')
- case '{' => return false
case _ => invalidEscape()
}
nextChar()
@@ -707,22 +765,16 @@ trait Scanners extends ScannersCommon {
putChar(ch)
nextChar()
}
- true
- }
protected def invalidEscape(): Unit = {
syntaxError(charOffset - 1, "invalid escape character")
putChar(ch)
}
- protected def getLitChar(): Unit =
- if (!maybeGetLitChar()) invalidEscape()
-
- private def getLitChars(delimiters: Char*) {
- while (!(delimiters contains ch) && (ch != CR && ch != LF && ch != SU || isUnicodeEscape)) {
+ private def getLitChars(delimiter: Char) =
+ while (ch != delimiter && (ch != CR && ch != LF && ch != SU || isUnicodeEscape)) {
getLitChar()
}
- }
/** read fractional part and exponent of floating point number
* if one is present.
@@ -971,8 +1023,8 @@ trait Scanners extends ScannersCommon {
"string(" + strVal + ")"
case STRINGPART =>
"stringpart(" + strVal + ")"
- case STRINGFMT =>
- "stringfmt(" + strVal + ")"
+ case INTERPOLATIONID =>
+ "interpolationid(" + name + ")"
case SEMI =>
";"
case NEWLINE =>
@@ -1088,8 +1140,7 @@ trait Scanners extends ScannersCommon {
case LONGLIT => "long literal"
case FLOATLIT => "float literal"
case DOUBLELIT => "double literal"
- case STRINGLIT | STRINGPART => "string literal"
- case STRINGFMT => "format string"
+ case STRINGLIT | STRINGPART | INTERPOLATIONID => "string literal"
case SYMBOLLIT => "symbol literal"
case LPAREN => "'('"
case RPAREN => "')'"
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
index 07970bb36e..091f333c27 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
@@ -45,18 +45,20 @@ abstract class Tokens {
}
object Tokens extends Tokens {
- final val STRINGPART = 7
+ final val STRINGPART = 7 // a part of an interpolated string
final val SYMBOLLIT = 8
- final val STRINGFMT = 9
+ final val INTERPOLATIONID = 9 // the lead identifier of an interpolated string
+
def isLiteral(code: Int) =
- code >= CHARLIT && code <= SYMBOLLIT
+ code >= CHARLIT && code <= INTERPOLATIONID
+
/** identifiers */
final val IDENTIFIER = 10
final val BACKQUOTED_IDENT = 11
def isIdentifier(code: Int) =
code >= IDENTIFIER && code <= BACKQUOTED_IDENT
-
+
@switch def canBeginExpression(code: Int) = code match {
case IDENTIFIER|BACKQUOTED_IDENT|USCORE => true
case LBRACE|LPAREN|LBRACKET|COMMENT => true
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 803bd05031..badf5d70d1 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -1528,7 +1528,7 @@ abstract class GenICode extends SubComponent {
if (mustUseAnyComparator) {
// when -optimise is on we call the @inline-version of equals, found in ScalaRunTime
val equalsMethod =
- if (!settings.XO.value) {
+ if (!settings.optimise.value) {
def default = platform.externalEquals
platform match {
case x: JavaPlatform =>
@@ -1550,7 +1550,7 @@ abstract class GenICode extends SubComponent {
val ctx1 = genLoad(l, ctx, ObjectReference)
val ctx2 = genLoad(r, ctx1, ObjectReference)
- ctx2.bb.emit(CALL_METHOD(equalsMethod, if (settings.XO.value) Dynamic else Static(false)))
+ ctx2.bb.emit(CALL_METHOD(equalsMethod, if (settings.optimise.value) Dynamic else Static(false)))
ctx2.bb.emit(CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL))
ctx2.bb.close
}
@@ -1755,7 +1755,7 @@ abstract class GenICode extends SubComponent {
val sym = t.symbol
def getLabel(pos: Position, name: Name) =
labels.getOrElseUpdate(sym,
- method.newLabel(sym.pos, unit.freshTermName(name.toString)) setInfo sym.tpe
+ method.newLabel(unit.freshTermName(name.toString), sym.pos) setInfo sym.tpe
)
t match {
@@ -2005,9 +2005,7 @@ abstract class GenICode extends SubComponent {
/** Make a fresh local variable. It ensures the 'name' is unique. */
def makeLocal(pos: Position, tpe: Type, name: String): Local = {
- val sym = method.symbol.newVariable(pos, unit.freshTermName(name))
- .setInfo(tpe)
- .setFlag(Flags.SYNTHETIC)
+ val sym = method.symbol.newVariable(unit.freshTermName(name), pos, Flags.SYNTHETIC) setInfo tpe
this.method.addLocal(new Local(sym, toTypeKind(tpe), false))
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
index 937b0bdc3d..6421d6c8ef 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
@@ -619,6 +619,50 @@ abstract class TypeFlowAnalysis {
}
}
+ class MTFAGrowable extends MethodTFA {
+
+ import icodes._
+
+ /** discards what must be discarded, blanks what needs to be blanked out, and keeps the rest. */
+ def reinit(m: icodes.IMethod, staleOut: List[BasicBlock], inlined: collection.Set[BasicBlock], staleIn: collection.Set[BasicBlock]) {
+ if (this.method == null || this.method.symbol != m.symbol) {
+ init(m)
+ return
+ } else if(staleOut.isEmpty && inlined.isEmpty && staleIn.isEmpty) {
+ // this promotes invoking reinit if in doubt, no performance degradation will ensue!
+ return;
+ }
+
+ reinit {
+ // asserts conveying an idea what CFG shapes arrive here.
+ // staleIn foreach (p => assert( !in.isDefinedAt(p), p))
+ // staleIn foreach (p => assert(!out.isDefinedAt(p), p))
+ // inlined foreach (p => assert( !in.isDefinedAt(p), p))
+ // inlined foreach (p => assert(!out.isDefinedAt(p), p))
+ // inlined foreach (p => assert(!p.successors.isEmpty || p.lastInstruction.isInstanceOf[icodes.opcodes.THROW], p))
+ // staleOut foreach (p => assert( in.isDefinedAt(p), p))
+
+ // never rewrite in(m.startBlock)
+ staleOut foreach { b =>
+ if(!inlined.contains(b)) { worklist += b }
+ out(b) = typeFlowLattice.bottom
+ }
+ // nothing else is added to the worklist, bb's reachable via succs will be tfa'ed
+ blankOut(inlined)
+ blankOut(staleIn)
+ // no need to add startBlocks from m.exh
+ }
+ }
+
+ private def blankOut(blocks: collection.Set[BasicBlock]) {
+ blocks foreach { b =>
+ in(b) = typeFlowLattice.bottom
+ out(b) = typeFlowLattice.bottom
+ }
+ }
+
+ }
+
class Timer {
var millis = 0L
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
index e7cf716add..1ba5b155fc 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
@@ -30,13 +30,14 @@ trait GenAndroid {
def isAndroidParcelableClass(sym: Symbol) =
(AndroidParcelableInterface != NoSymbol) &&
- (sym.info.parents contains AndroidParcelableInterface.tpe)
+ (sym.parentSymbols contains AndroidParcelableInterface)
def addCreatorCode(codegen: BytecodeGenerator, block: BasicBlock) {
import codegen._
- val fieldSymbol = clasz.symbol.newValue(NoPosition, newTermName(fieldName))
- .setFlag(Flags.STATIC | Flags.FINAL)
- .setInfo(AndroidCreatorClass.tpe)
+ val fieldSymbol = (
+ clasz.symbol.newValue(newTermName(fieldName), NoPosition, Flags.STATIC | Flags.FINAL)
+ setInfo AndroidCreatorClass.tpe
+ )
val methodSymbol = definitions.getMember(clasz.symbol.companionModule, fieldName)
clasz addField new IField(fieldSymbol)
block emit CALL_METHOD(methodSymbol, Static(false))
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 03d1bc3ad2..b5232fff09 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -30,13 +30,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
import global._
import icodes._
import icodes.opcodes._
- import definitions.{
- AnyClass, ObjectClass, ThrowsClass, ThrowableClass, ClassfileAnnotationClass,
- SerializableClass, StringClass, ClassClass, FunctionClass,
- DeprecatedAttr, SerializableAttr, SerialVersionUIDAttr, VolatileAttr,
- TransientAttr, CloneableAttr, RemoteAttr, JavaCloneableClass,
- RemoteInterfaceClass, RemoteExceptionClass, hasJavaMainMethod
- }
+ import definitions._
val phaseName = "jvm"
@@ -68,10 +62,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
def isJavaEntryPoint(clasz: IClass) = {
val sym = clasz.symbol
- def fail(msg: String) = {
+ def fail(msg: String, pos: Position = sym.pos) = {
clasz.cunit.warning(sym.pos,
- sym.name + " has a main method, but " + sym.fullName('.') + " will not be a runnable program.\n" +
- " " + msg + ", which means no static forwarder can be generated.\n"
+ sym.name + " has a main method with parameter type Array[String], but " + sym.fullName('.') + " will not be a runnable program.\n" +
+ " Reason: " + msg
// TODO: make this next claim true, if possible
// by generating valid main methods as static in module classes
// not sure what the jvm allows here
@@ -79,19 +73,47 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
)
false
}
- sym.hasModuleFlag && hasJavaMainMethod(sym) && {
- // At this point we've seen a module with a main method, so if this
- // doesn't turn out to be a valid entry point, issue a warning.
- val companion = sym.linkedClassOfClass
- if (companion.isTrait)
- fail("Its companion is a trait")
- else if (hasJavaMainMethod(companion) && !(sym isSubClass companion))
- fail("Its companion contains its own main method")
- // this is only because forwarders aren't smart enough yet
- else if (companion.tpe.member(nme.main) != NoSymbol)
- fail("Its companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)")
- else
- true
+ def failNoForwarder(msg: String) = {
+ fail(msg + ", which means no static forwarder can be generated.\n")
+ }
+ val possibles = if (sym.hasModuleFlag) (sym.tpe nonPrivateMember nme.main).alternatives else Nil
+ val hasApproximate = possibles exists { m =>
+ m.info match {
+ case MethodType(p :: Nil, _) => p.tpe.typeSymbol == ArrayClass
+ case _ => false
+ }
+ }
+ // At this point it's a module with a main-looking method, so either
+ // succeed or warn that it isn't.
+ hasApproximate && {
+ // Before erasure so we can identify generic mains.
+ atPhase(currentRun.erasurePhase) {
+ val companion = sym.linkedClassOfClass
+ val companionMain = companion.tpe.member(nme.main)
+
+ if (hasJavaMainMethod(companion))
+ failNoForwarder("companion contains its own main method")
+ else if (companion.tpe.member(nme.main) != NoSymbol)
+ // this is only because forwarders aren't smart enough yet
+ failNoForwarder("companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)")
+ else if (companion.isTrait)
+ failNoForwarder("companion is a trait")
+ // Now either succeeed, or issue some additional warnings for things which look like
+ // attempts to be java main methods.
+ else possibles exists { m =>
+ m.info match {
+ case PolyType(_, _) =>
+ fail("main methods cannot be generic.")
+ case MethodType(params, res) =>
+ if (res.typeSymbol :: params exists (_.isAbstractType))
+ fail("main methods cannot refer to type parameters or abstract types.", m.pos)
+ else
+ isJavaMainMethod(m) || fail("main method must have exact signature (Array[String])Unit", m.pos)
+ case tp =>
+ fail("don't know what this is: " + tp, m.pos)
+ }
+ }
+ }
}
}
@@ -854,7 +876,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (outerField != NoSymbol) {
log("Adding fake local to represent outer 'this' for closure " + clasz)
val _this = new Local(
- method.symbol.newVariable(NoPosition, nme.FAKE_LOCAL_THIS), toTypeKind(outerField.tpe), false)
+ method.symbol.newVariable(nme.FAKE_LOCAL_THIS), toTypeKind(outerField.tpe), false)
m.locals = m.locals ::: List(_this)
computeLocalVarsIndex(m) // since we added a new local, we need to recompute indexes
@@ -944,9 +966,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
serialVUID foreach { value =>
import Flags._, definitions._
val fieldName = "serialVersionUID"
- val fieldSymbol = clasz.symbol.newValue(NoPosition, newTermName(fieldName))
- .setFlag(STATIC | FINAL)
- .setInfo(longType)
+ val fieldSymbol = clasz.symbol.newValue(newTermName(fieldName), NoPosition, STATIC | FINAL) setInfo longType
clasz addField new IField(fieldSymbol)
lastBlock emit CONSTANT(Constant(value))
lastBlock emit STORE_FIELD(fieldSymbol, true)
diff --git a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
index a37a3406a8..ec137203bf 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
@@ -203,7 +203,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
// Here we could create a single local for all exceptions of a certain type. TODO: try that.
val localName = currentClass.cunit.freshTermName("exception$")
val localType = exceptionType
- val localSymbol = bblock.method.symbol.newValue(NoPosition, localName).setInfo(localType.toType)
+ val localSymbol = bblock.method.symbol.newValue(localName).setInfo(localType.toType)
val local = new Local(localSymbol, localType, false)
bblock.method.addLocal(local)
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index e3d21011d1..66f802f74f 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -62,6 +62,15 @@ abstract class Inliners extends SubComponent {
override def apply(c: IClass) {
inliner analyzeClass c
}
+
+ override def run() {
+ try {
+ super.run()
+ } finally {
+ inliner.NonPublicRefs.usesNonPublics.clear()
+ inliner.recentTFAs.clear
+ }
+ }
}
def isBottomType(sym: Symbol) = sym == NullClass || sym == NothingClass
@@ -79,17 +88,10 @@ abstract class Inliners extends SubComponent {
val Private, Protected, Public = Value
/** Cache whether a method calls private members. */
- val usesNonPublics: mutable.Map[IMethod, Value] = perRunCaches.newMap()
+ val usesNonPublics = mutable.Map.empty[IMethod, Value]
}
import NonPublicRefs._
- /* fresh name counter */
- val fresh = perRunCaches.newMap[String, Int]() withDefaultValue 0
- def freshName(s: String): TermName = {
- fresh(s) += 1
- newTermName(s + fresh(s))
- }
-
private def hasInline(sym: Symbol) = sym hasAnnotation ScalaInlineClass
private def hasNoInline(sym: Symbol) = sym hasAnnotation ScalaNoInlineClass
@@ -97,27 +99,60 @@ abstract class Inliners extends SubComponent {
private var currentIClazz: IClass = _
private def warn(pos: Position, msg: String) = currentIClazz.cunit.warning(pos, msg)
+ val recentTFAs = mutable.Map.empty[Symbol, Tuple2[Boolean, analysis.MethodTFA]]
+ private def getRecentTFA(incm: IMethod): (Boolean, analysis.MethodTFA) = {
+
+ def containsRETURN(blocks: List[BasicBlock]) = blocks exists { bb => bb.lastInstruction.isInstanceOf[RETURN] }
+
+ val opt = recentTFAs.get(incm.symbol)
+ if(opt.isDefined) {
+ // FYI val cachedBBs = opt.get._2.in.keySet
+ // FYI assert(incm.blocks.toSet == cachedBBs)
+ // incm.code.touched plays no role here
+ return opt.get
+ }
+
+ val hasRETURN = containsRETURN(incm.code.blocksList) || (incm.exh exists { eh => containsRETURN(eh.blocks) })
+ var a: analysis.MethodTFA = null
+ if(hasRETURN) { a = new analysis.MethodTFA(incm); a.run }
+
+ if(hasInline(incm.symbol)) { recentTFAs.put(incm.symbol, (hasRETURN, a)) }
+
+ (hasRETURN, a)
+ }
+
def analyzeClass(cls: IClass): Unit =
if (settings.inline.value) {
debuglog("Analyzing " + cls)
this.currentIClazz = cls
- cls.methods filterNot (_.symbol.isConstructor) foreach analyzeMethod
+ val ms = cls.methods filterNot { _.symbol.isConstructor }
+ ms foreach { im =>
+ if(hasInline(im.symbol)) {
+ log("Not inlining into " + im.symbol.originalName.decode + " because it is marked @inline.")
+ } else if(im.hasCode && !im.symbol.isBridge) {
+ analyzeMethod(im)
+ }
+ }
}
- val tfa = new analysis.MethodTFA()
+ val tfa = new analysis.MTFAGrowable()
tfa.stat = global.opt.printStats
-
- // how many times have we already inlined this method here?
- private val inlinedMethodCount = perRunCaches.newMap[Symbol, Int]() withDefaultValue 0
+ val staleOut = new mutable.ListBuffer[BasicBlock]
+ val splicedBlocks = mutable.Set.empty[BasicBlock]
+ val staleIn = mutable.Set.empty[BasicBlock]
def analyzeMethod(m: IMethod): Unit = {
- var sizeBeforeInlining = if (m.hasCode) m.code.blockCount else 0
- var instrBeforeInlining = if (m.hasCode) m.code.instructionCount else 0
+ var sizeBeforeInlining = m.code.blockCount
+ var instrBeforeInlining = m.code.instructionCount
var retry = false
var count = 0
- fresh.clear()
- inlinedMethodCount.clear()
+
+ // fresh name counter
+ val fresh = mutable.HashMap.empty[String, Int] withDefaultValue 0
+ // how many times have we already inlined this method here?
+ val inlinedMethodCount = mutable.HashMap.empty[Symbol, Int] withDefaultValue 0
+
val caller = new IMethodInfo(m)
var info: tfa.lattice.Elem = null
@@ -136,17 +171,20 @@ abstract class Inliners extends SubComponent {
warn(i.pos, "Could not inline required method %s because %s.".format(msym.originalName.decode, reason))
}
- if (shouldLoadImplFor(concreteMethod, receiver)) {
+ def isAvailable = icodes available concreteMethod.enclClass
+
+ if (!isAvailable && shouldLoadImplFor(concreteMethod, receiver)) {
// Until r22824 this line was:
// icodes.icode(concreteMethod.enclClass, true)
//
- // Changing it to the below was the proximate cause for SI-3882:
+ // Changing it to
+ // icodes.load(concreteMethod.enclClass)
+ // was the proximate cause for SI-3882:
// error: Illegal index: 0 overlaps List((variable par1,LONG))
// error: Illegal index: 0 overlaps List((variable par1,LONG))
icodes.load(concreteMethod.enclClass)
}
- def isAvailable = icodes available concreteMethod.enclClass
def isCandidate = (
isClosureClass(receiver)
|| concreteMethod.isEffectivelyFinal
@@ -169,7 +207,7 @@ abstract class Inliners extends SubComponent {
lookupIMethod(concreteMethod, receiver) match {
case Some(callee) =>
val inc = new IMethodInfo(callee)
- val pair = new CallerCalleeInfo(caller, inc)
+ val pair = new CallerCalleeInfo(caller, inc, fresh, inlinedMethodCount)
if (pair isStampedForInlining info.stack) {
retry = true
@@ -186,6 +224,7 @@ abstract class Inliners extends SubComponent {
* might have changed after the inlining.
*/
usesNonPublics -= m
+ recentTFAs -= m.symbol
}
else {
if (settings.debug.value)
@@ -208,34 +247,35 @@ abstract class Inliners extends SubComponent {
import scala.util.control.Breaks._
do {
retry = false
- if (caller.inline) {
- log("Not inlining into " + caller.sym.originalName.decode + " because it is marked @inline.")
- }
- else if (caller.m.hasCode) {
- log("Analyzing " + m + " count " + count + " with " + caller.length + " blocks")
- tfa init m
- tfa.run
- caller.m.linearizedBlocks() foreach { bb =>
- info = tfa in bb
-
- breakable {
- for (i <- bb) {
- i match {
- // Dynamic == normal invocations
- // Static(true) == calls to private members
- case CALL_METHOD(msym, Dynamic | Static(true)) if !msym.isConstructor =>
- if (analyzeInc(msym, i, bb))
- break
- case _ => ()
- }
- info = tfa.interpret(info, i)
+ log("Analyzing " + m + " count " + count + " with " + caller.length + " blocks")
+ tfa.reinit(m, staleOut.toList, splicedBlocks, staleIn)
+ tfa.run
+ staleOut.clear()
+ splicedBlocks.clear()
+ staleIn.clear()
+
+ caller.m.linearizedBlocks() foreach { bb =>
+ info = tfa in bb
+
+ breakable {
+ for (i <- bb) {
+ i match {
+ // Dynamic == normal invocations
+ // Static(true) == calls to private members
+ case CALL_METHOD(msym, Dynamic | Static(true)) if !msym.isConstructor =>
+ if (analyzeInc(msym, i, bb)) {
+ break
+ }
+ case _ => ()
}
+ info = tfa.interpret(info, i)
}
}
- if (tfa.stat)
- log(m.symbol.fullName + " iterations: " + tfa.iterations + " (size: " + caller.length + ")")
}
+
+ if (tfa.stat)
+ log(m.symbol.fullName + " iterations: " + tfa.iterations + " (size: " + caller.length + ")")
}
while (retry && count < MAX_INLINE_RETRY)
@@ -304,11 +344,10 @@ abstract class Inliners extends SubComponent {
def inline = hasInline(sym)
def noinline = hasNoInline(sym)
- def numInlined = inlinedMethodCount(sym)
def isBridge = sym.isBridge
def isInClosure = isClosureClass(owner)
- def isHigherOrder = isHigherOrderMethod(sym)
+ val isHigherOrder = isHigherOrderMethod(sym)
def isMonadic = isMonadicMethod(sym)
def handlers = m.exh
@@ -317,7 +356,7 @@ abstract class Inliners extends SubComponent {
def length = blocks.length
def openBlocks = blocks filterNot (_.closed)
def instructions = m.code.instructions
- def linearized = linearizer linearize m
+ // def linearized = linearizer linearize m
def isSmall = (length <= SMALL_METHOD_SIZE) && blocks(0).length < 10
def isLarge = length > MAX_INLINE_SIZE
@@ -336,21 +375,29 @@ abstract class Inliners extends SubComponent {
def addHandlers(exhs: List[ExceptionHandler]) = m.exh = exhs ::: m.exh
}
- class CallerCalleeInfo(val caller: IMethodInfo, val inc: IMethodInfo) {
+ class CallerCalleeInfo(val caller: IMethodInfo, val inc: IMethodInfo, fresh: mutable.Map[String, Int], inlinedMethodCount: collection.Map[Symbol, Int]) {
def isLargeSum = caller.length + inc.length - 1 > SMALL_METHOD_SIZE
+ private def freshName(s: String): TermName = {
+ fresh(s) += 1
+ newTermName(s + fresh(s))
+ }
+
/** Inline 'inc' into 'caller' at the given block and instruction.
* The instruction must be a CALL_METHOD.
*/
def doInline(block: BasicBlock, instr: Instruction) {
+
+ staleOut += block
+
val targetPos = instr.pos
log("Inlining " + inc.m + " in " + caller.m + " at pos: " + posToStr(targetPos))
def blockEmit(i: Instruction) = block.emit(i, targetPos)
def newLocal(baseName: String, kind: TypeKind) =
- new Local(caller.sym.newVariable(targetPos, freshName(baseName)), kind, false)
+ new Local(caller.sym.newVariable(freshName(baseName), targetPos), kind, false)
- val a = new analysis.MethodTFA(inc.m)
+ val (hasRETURN, a) = getRecentTFA(inc.m)
/* The exception handlers that are active at the current block. */
val activeHandlers = caller.handlers filter (_ covered block)
@@ -379,7 +426,7 @@ abstract class Inliners extends SubComponent {
case x => newLocal("$retVal", x)
}
- val inlinedLocals = perRunCaches.newMap[Local, Local]()
+ val inlinedLocals = mutable.HashMap.empty[Local, Local]
/** Add a new block in the current context. */
def newBlock() = {
@@ -400,7 +447,7 @@ abstract class Inliners extends SubComponent {
/** alfa-rename `l` in caller's context. */
def dupLocal(l: Local): Local = {
- val sym = caller.sym.newVariable(l.sym.pos, freshName(l.sym.name.toString))
+ val sym = caller.sym.newVariable(freshName(l.sym.name.toString), l.sym.pos)
// sym.setInfo(l.sym.tpe)
val dupped = new Local(sym, l.kind, false)
inlinedLocals(l) = dupped
@@ -461,9 +508,6 @@ abstract class Inliners extends SubComponent {
inlinedBlock(b).varsInScope ++= (b.varsInScope map inlinedLocals)
}
- // analyse callee
- a.run
-
// re-emit the instructions before the call
block.open
block.clear
@@ -478,8 +522,9 @@ abstract class Inliners extends SubComponent {
block.close
// duplicate the other blocks in the callee
- inc.m.linearizedBlocks() foreach { bb =>
- var info = a in bb
+ val calleeLin = inc.m.linearizedBlocks()
+ calleeLin foreach { bb =>
+ var info = if(hasRETURN) (a in bb) else null
def emitInlined(i: Instruction) = inlinedBlock(bb).emit(i, targetPos)
def emitDrops(toDrop: Int) = info.stack.types drop toDrop foreach (t => emitInlined(DROP(t)))
@@ -495,7 +540,7 @@ abstract class Inliners extends SubComponent {
case _ => ()
}
emitInlined(map(i))
- info = a.interpret(info, i)
+ info = if(hasRETURN) a.interpret(info, i) else null
}
inlinedBlock(bb).close
}
@@ -503,6 +548,9 @@ abstract class Inliners extends SubComponent {
afterBlock emit instrAfter
afterBlock.close
+ staleIn += afterBlock
+ splicedBlocks ++= (calleeLin map inlinedBlock)
+
// add exception handlers of the callee
caller addHandlers (inc.handlers map translateExh)
assert(pending.isEmpty, "Pending NEW elements: " + pending)
@@ -520,7 +568,7 @@ abstract class Inliners extends SubComponent {
| isSafeToInline: %s
| shouldInline: %s
""".stripMargin.format(
- inc.m, sameSymbols, inc.numInlined < 2,
+ inc.m, sameSymbols, inlinedMethodCount(inc.sym) < 2,
inc.m.hasCode, isSafeToInline(stack), shouldInline
)
)
@@ -617,28 +665,22 @@ abstract class Inliners extends SubComponent {
var score = 0
- // better not inline inside closures, but hope that the closure itself
- // is repeatedly inlined
- if (caller.isInClosure) score -= 2
+ // better not inline inside closures, but hope that the closure itself is repeatedly inlined
+ if (caller.isInClosure) score -= 2
else if (caller.inlinedCalls < 1) score -= 1 // only monadic methods can trigger the first inline
- if (inc.isSmall)
- score += 1
+ if (inc.isSmall) score += 1;
+ if (inc.isLarge) score -= 1;
if (caller.isSmall && isLargeSum) {
score -= 1
debuglog("shouldInline: score decreased to " + score + " because small " + caller + " would become large")
}
- if (inc.isLarge)
- score -= 1
- if (inc.isMonadic)
- score += 3
- else if (inc.isHigherOrder)
- score += 1
- if (inc.isInClosure)
- score += 2
- if (inc.numInlined > 2)
- score -= 2
+ if (inc.isMonadic) score += 3
+ else if (inc.isHigherOrder) score += 1
+
+ if (inc.isInClosure) score += 2;
+ if (inlinedMethodCount(inc.sym) > 2) score -= 2;
log("shouldInline(" + inc.m + ") score: " + score)
diff --git a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
index 14cbdf2f3b..f251fd83fb 100644
--- a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
@@ -166,10 +166,8 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana
changesOf(oldSym) = (changes ++ changesErasure).distinct
case _ =>
// a new top level definition
- changesOf(sym) =
- sym.info.parents.filter(_.typeSymbol.isSealed).map(
- p => changeChangeSet(p.typeSymbol,
- sym+" extends a sealed "+p.typeSymbol))
+ changesOf(sym) = sym.parentSymbols filter (_.isSealed) map (p =>
+ changeChangeSet(p, sym+" extends a sealed "+p))
}
}
// Create a change for the top level classes that were removed
@@ -242,7 +240,7 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana
for ((oldSym, changes) <- changesOf; change <- changes) {
def checkParents(cls: Symbol, file: AbstractFile) {
- val parentChange = cls.info.parents.exists(_.typeSymbol.fullName == oldSym.fullName)
+ val parentChange = cls.parentSymbols exists (_.fullName == oldSym.fullName)
// if (settings.buildmanagerdebug.value)
// compiler.inform("checkParents " + cls + " oldSym: " + oldSym + " parentChange: " + parentChange + " " + cls.info.parents)
change match {
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 0dc51d5eb0..7c71438b98 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -110,7 +110,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
class ILoopInterpreter extends IMain(settings, out) {
outer =>
- private class ThreadStoppingLineManager extends Line.Manager(parentClassLoader) {
+ private class ThreadStoppingLineManager(classLoader: ClassLoader) extends Line.Manager(classLoader) {
override def onRunaway(line: Line[_]): Unit = {
val template = """
|// She's gone rogue, captain! Have to take her out!
@@ -126,8 +126,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
override lazy val formatting = new Formatting {
def prompt = ILoop.this.prompt
}
- override protected def createLineManager(): Line.Manager =
- new ThreadStoppingLineManager
+ override protected def createLineManager(classLoader: ClassLoader): Line.Manager =
+ new ThreadStoppingLineManager(classLoader)
override protected def parentClassLoader =
settings.explicitParentLoader.getOrElse( classOf[ILoop].getClassLoader )
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 0f0ab69e6d..8cdd2334ab 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -269,7 +269,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
/** Create a line manager. Overridable. */
protected def noLineManager = ReplPropsKludge.noThreadCreation(settings)
- protected def createLineManager(): Line.Manager = new Line.Manager(_classLoader)
+ protected def createLineManager(classLoader: ClassLoader): Line.Manager = new Line.Manager(classLoader)
/** Instantiate a compiler. Overridable. */
protected def newCompiler(settings: Settings, reporter: Reporter) = {
@@ -304,7 +304,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
final def ensureClassLoader() {
if (_classLoader == null) {
_classLoader = makeClassLoader()
- _lineManager = if (noLineManager) null else createLineManager()
+ _lineManager = if (noLineManager) null else createLineManager(_classLoader)
}
}
def classLoader: AbstractFileClassLoader = {
diff --git a/src/compiler/scala/tools/nsc/io/MsilFile.scala b/src/compiler/scala/tools/nsc/io/MsilFile.scala
index 69db23923d..d970d0e9c9 100644
--- a/src/compiler/scala/tools/nsc/io/MsilFile.scala
+++ b/src/compiler/scala/tools/nsc/io/MsilFile.scala
@@ -13,4 +13,6 @@ import ch.epfl.lamp.compiler.msil.{ Type => MsilType, _ }
* uniformly, as AbstractFiles.
*/
class MsilFile(val msilType: MsilType) extends VirtualFile(msilType.FullName, msilType.Namespace) {
-} \ No newline at end of file
+}
+
+object NoMsilFile extends MsilFile(null) { }
diff --git a/src/compiler/scala/tools/nsc/io/NoAbstractFile.scala b/src/compiler/scala/tools/nsc/io/NoAbstractFile.scala
new file mode 100644
index 0000000000..36cf42d7ec
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/io/NoAbstractFile.scala
@@ -0,0 +1,30 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package io
+
+import java.io.InputStream
+
+/** A distinguished object so you can avoid both null
+ * and Option.
+ */
+object NoAbstractFile extends AbstractFile {
+ def absolute: AbstractFile = this
+ def container: AbstractFile = this
+ def create(): Unit = ???
+ def delete(): Unit = ???
+ def file: JFile = null
+ def input: InputStream = null
+ def isDirectory: Boolean = false
+ def iterator: Iterator[AbstractFile] = Iterator.empty
+ def lastModified: Long = 0L
+ def lookupName(name: String, directory: Boolean): AbstractFile = null
+ def lookupNameUnchecked(name: String, directory: Boolean): AbstractFile = null
+ def name: String = ""
+ def output: java.io.OutputStream = null
+ def path: String = ""
+ override def toByteArray = Array[Byte]()
+}
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 0d7afdc4ec..0c94e40d68 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -126,11 +126,15 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
if (treeInfo.firstConstructor(stats) == EmptyTree) makeConstructor(List()) :: stats
else stats)
- def makeParam(name: String, tpt: Tree) =
- ValDef(Modifiers(Flags.JAVA | Flags.PARAM), newTermName(name), tpt, EmptyTree)
+ def makeSyntheticParam(count: Int, tpt: Tree): ValDef =
+ makeParam(nme.syntheticParamName(count), tpt)
+ def makeParam(name: String, tpt: Tree): ValDef =
+ makeParam(newTypeName(name), tpt)
+ def makeParam(name: TermName, tpt: Tree): ValDef =
+ ValDef(Modifiers(Flags.JAVA | Flags.PARAM), name, tpt, EmptyTree)
def makeConstructor(formals: List[Tree]) = {
- val vparams = formals.zipWithIndex map { case (p, i) => makeParam("x$" + (i + 1), p) }
+ val vparams = mapWithIndex(formals)((p, i) => makeSyntheticParam(i + 1, p))
DefDef(Modifiers(Flags.JAVA), nme.CONSTRUCTOR, List(), List(vparams), TypeTree(), blankExpr)
}
diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala
index 61864f0c8a..d81f05cd51 100644
--- a/src/compiler/scala/tools/nsc/matching/Matrix.scala
+++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala
@@ -252,7 +252,8 @@ trait Matrix extends MatrixAdditions {
{
val n = if (name == null) cunit.freshTermName("temp") else name
// careful: pos has special meaning
- recordSyntheticSym(owner.newVariable(pos, n) setInfo tpe setFlag (SYNTHETIC.toLong /: flags)(_|_))
+ val flagsLong = (SYNTHETIC.toLong /: flags)(_|_)
+ recordSyntheticSym(owner.newVariable(n, pos, flagsLong) setInfo tpe)
}
}
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 11d829eadb..9d4c9b4411 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -54,7 +54,7 @@ trait ParallelMatching extends ast.TreeDSL
}
def createLabelDef(namePrefix: String, body: Tree, params: List[Symbol] = Nil, restpe: Type = matchResultType) = {
val labelName = cunit.freshTermName(namePrefix)
- val labelSym = owner.newLabel(owner.pos, labelName)
+ val labelSym = owner.newLabel(labelName, owner.pos)
val labelInfo = MethodType(params, restpe)
LabelDef(labelSym setInfo labelInfo, params, body setType restpe)
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index 967b582f11..c76a04c6ba 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -47,20 +47,7 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
/** Prints the message with the given position indication. */
def printMessage(posIn: Position, msg: String) {
- val pos = if (posIn eq null) NoPosition
- else if (posIn.isDefined) posIn.inUltimateSource(posIn.source)
- else posIn
- pos match {
- case FakePos(fmsg) =>
- printMessage(fmsg+" "+msg)
- case NoPosition =>
- printMessage(msg)
- case _ =>
- val buf = new StringBuilder(msg)
- val file = pos.source.file
- printMessage((if (shortname) file.name else file.path)+":"+pos.line+": "+msg)
- printSourceLine(pos)
- }
+ printMessage(Position.formatMessage(posIn, msg, shortname))
}
def print(pos: Position, msg: String, severity: Severity) {
printMessage(pos, clabel(severity) + msg)
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index efd5323ce2..6806ca03ba 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -96,6 +96,7 @@ trait ScalaSettings extends AbsScalaSettings
val Xexperimental = BooleanSetting ("-Xexperimental", "Enable experimental extensions.") .
withPostSetHook(set => List(YmethodInfer, overrideObjects) foreach (_.value = set.value))
// YdepMethTpes, YvirtClasses,
+ val Xmacros = BooleanSetting ("-Xmacros", "Enable macros.")
/** Compatibility stubs for options whose value name did
* not previously match the option name.
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 340e1d1d08..4205c2ff36 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -39,7 +39,7 @@ abstract class SymbolLoaders {
*/
def enterClass(root: Symbol, name: String, completer: SymbolLoader): Symbol = {
val owner = realOwner(root)
- val clazz = owner.newClass(NoPosition, newTypeName(name))
+ val clazz = owner.newClass(newTypeName(name))
clazz setInfo completer
enterIfNew(owner, clazz, completer)
}
@@ -49,7 +49,7 @@ abstract class SymbolLoaders {
*/
def enterModule(root: Symbol, name: String, completer: SymbolLoader): Symbol = {
val owner = realOwner(root)
- val module = owner.newModule(NoPosition, newTermName(name))
+ val module = owner.newModule(newTermName(name))
module setInfo completer
module.moduleClass setInfo moduleClassLoader
enterIfNew(owner, module, completer)
@@ -199,7 +199,7 @@ abstract class SymbolLoaders {
return
}
}
- val pkg = root.newPackage(NoPosition, newTermName(name))
+ val pkg = root.newPackage(newTermName(name))
pkg.moduleClass.setInfo(completer)
pkg.setInfo(pkg.moduleClass.tpe)
root.info.decls.enter(pkg)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index a158012f9f..b818927ceb 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -255,8 +255,11 @@ abstract class ClassfileParser {
f = ownerTpe.findMember(origName, 0, 0, false).suchThat(_.tpe =:= tpe)
} else {
log("Couldn't find " + name + ": " + tpe + " inside: \n" + ownerTpe)
- f = if (tpe.isInstanceOf[MethodType]) owner.newMethod(owner.pos, name).setInfo(tpe)
- else owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE)
+ f = tpe match {
+ case MethodType(_, _) => owner.newMethod(name, owner.pos)
+ case _ => owner.newVariable(name, owner.pos)
+ }
+ f setInfo tpe
log("created fake member " + f.fullName)
}
// println("\townerTpe.decls: " + ownerTpe.decls)
@@ -283,7 +286,7 @@ abstract class ClassfileParser {
if (in.buf(start).toInt != CONSTANT_NAMEANDTYPE) errorBadTag(start)
val name = getName(in.getChar(start + 1).toInt)
// create a dummy symbol for method types
- val dummySym = ownerTpe.typeSymbol.newMethod(ownerTpe.typeSymbol.pos, name)
+ val dummySym = ownerTpe.typeSymbol.newMethod(name, ownerTpe.typeSymbol.pos)
var tpe = getType(dummySym, in.getChar(start + 3).toInt)
// fix the return type, which is blindly set to the class currently parsed
@@ -455,7 +458,7 @@ abstract class ClassfileParser {
ss = name.subName(start, end)
sym = owner.info.decls lookup ss
if (sym == NoSymbol) {
- sym = owner.newPackage(NoPosition, ss) setInfo completer
+ sym = owner.newPackage(ss) setInfo completer
sym.moduleClass setInfo completer
owner.info.decls enter sym
}
@@ -465,11 +468,9 @@ abstract class ClassfileParser {
}
ss = name.subName(0, start)
owner.info.decls lookup ss orElse {
- sym = owner.newClass(NoPosition, ss.toTypeName) setInfo completer
- if (opt.verboseDebug)
- println("loaded "+sym+" from file "+file)
-
- owner.info.decls enter sym
+ sym = owner.newClass(ss.toTypeName) setInfoAndEnter completer
+ debuglog("loaded "+sym+" from file "+file)
+ sym
}
}
@@ -499,7 +500,7 @@ abstract class ClassfileParser {
def parseClass() {
val jflags = in.nextChar
val isAnnotation = hasAnnotation(jflags)
- var sflags = toScalaFlags(jflags, isClass = true)
+ var sflags = toScalaClassFlags(jflags)
var nameIdx = in.nextChar
externalName = pool.getClassName(nameIdx)
val c = if (externalName.toString.indexOf('$') < 0) pool.getClassSymbol(nameIdx) else clazz
@@ -604,13 +605,13 @@ abstract class ClassfileParser {
def parseField() {
val jflags = in.nextChar
- var sflags = toScalaFlags(jflags, isField = true)
- if ((sflags & PRIVATE) != 0L && !global.settings.XO.value) {
+ var sflags = toScalaFieldFlags(jflags)
+ if ((sflags & PRIVATE) != 0L && !global.settings.optimise.value) {
in.skip(4); skipAttributes()
} else {
val name = pool.getName(in.nextChar)
val info = pool.getType(in.nextChar)
- val sym = getOwner(jflags).newValue(NoPosition, name).setFlag(sflags)
+ val sym = getOwner(jflags).newValue(name, NoPosition, sflags)
val isEnum = (jflags & JAVA_ACC_ENUM) != 0
sym setInfo {
@@ -635,8 +636,8 @@ abstract class ClassfileParser {
def parseMethod() {
val jflags = in.nextChar.toInt
- var sflags = toScalaFlags(jflags)
- if (isPrivate(jflags) && !global.settings.XO.value) {
+ var sflags = toScalaMethodFlags(jflags)
+ if (isPrivate(jflags) && !global.settings.optimise.value) {
val name = pool.getName(in.nextChar)
if (name == nme.CONSTRUCTOR)
sawPrivateConstructor = true
@@ -644,11 +645,11 @@ abstract class ClassfileParser {
} else {
if ((jflags & JAVA_ACC_BRIDGE) != 0)
sflags |= BRIDGE
- if ((sflags & PRIVATE) != 0L && global.settings.XO.value) {
+ if ((sflags & PRIVATE) != 0L && global.settings.optimise.value) {
in.skip(4); skipAttributes()
} else {
val name = pool.getName(in.nextChar)
- val sym = getOwner(jflags).newMethod(NoPosition, name).setFlag(sflags)
+ val sym = getOwner(jflags).newMethod(name, NoPosition, sflags)
var info = pool.getType(sym, (in.nextChar))
if (name == nme.CONSTRUCTOR)
info match {
@@ -726,7 +727,7 @@ abstract class ClassfileParser {
else TypeBounds.lower(tp)
case '*' => TypeBounds.empty
}
- val newtparam = sym.newExistential(sym.pos, newTypeName("?"+i)) setInfo bounds
+ val newtparam = sym.newExistential(newTypeName("?"+i), sym.pos) setInfo bounds
existentials += newtparam
xs += newtparam.tpe //@M should probably be .tpeHK
i += 1
@@ -813,7 +814,7 @@ abstract class ClassfileParser {
val start = index
while (sig(index) != '>') {
val tpname = subName(':'.==).toTypeName
- val s = sym.newTypeParameter(NoPosition, tpname)
+ val s = sym.newTypeParameter(tpname)
tparams = tparams + (tpname -> s)
sig2typeBounds(tparams, true)
newTParams += s
@@ -1074,10 +1075,10 @@ abstract class ClassfileParser {
def enterClassAndModule(entry: InnerClassEntry, completer: global.loaders.SymbolLoader, jflags: Int) {
val name = entry.originalName
- var sflags = toScalaFlags(jflags, isClass = true)
+ var sflags = toScalaClassFlags(jflags)
- val innerClass = getOwner(jflags).newClass(NoPosition, name.toTypeName).setInfo(completer).setFlag(sflags)
- val innerModule = getOwner(jflags).newModule(NoPosition, name.toTermName).setInfo(completer).setFlag(sflags)
+ val innerClass = getOwner(jflags).newClass(name.toTypeName).setInfo(completer).setFlag(sflags)
+ val innerModule = getOwner(jflags).newModule(name.toTermName).setInfo(completer).setFlag(sflags)
innerModule.moduleClass setInfo global.loaders.moduleClassLoader
getScope(jflags) enter innerClass
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 0b64a49a2c..3c97122c9c 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -60,8 +60,7 @@ abstract class ICodeReader extends ClassfileParser {
this.staticCode = new IClass(staticModule)
val jflags = in.nextChar
val isAttribute = (jflags & JAVA_ACC_ANNOTATION) != 0
- var sflags = toScalaFlags(jflags, true)
- if ((sflags & DEFERRED) != 0L) sflags = sflags & ~DEFERRED | ABSTRACT
+ val sflags = toScalaClassFlags(jflags) // what, this is never used??
val c = pool getClassSymbol in.nextChar
parseInnerClasses()
@@ -86,29 +85,24 @@ abstract class ICodeReader extends ClassfileParser {
val jflags = in.nextChar
val name = pool getName in.nextChar
val owner = getOwner(jflags)
- val dummySym = owner.newMethod(owner.pos, name) setFlag javaToScalaFlags(jflags)
+ val dummySym = owner.newMethod(name, owner.pos, toScalaMethodFlags(jflags))
try {
- val ch = in.nextChar
- var tpe = pool.getType(dummySym, ch)
+ val ch = in.nextChar
+ val tpe = pool.getType(dummySym, ch)
if ("<clinit>" == name.toString)
(jflags, NoSymbol)
else {
val owner = getOwner(jflags)
- var sym = owner.info.findMember(name, 0, 0, false).suchThat(old => sameType(old.tpe, tpe));
+ var sym = owner.info.findMember(name, 0, 0, false).suchThat(old => sameType(old.tpe, tpe))
if (sym == NoSymbol)
- sym = owner.info.findMember(newTermName(name + nme.LOCAL_SUFFIX_STRING), 0, 0, false).suchThat(old => old.tpe =:= tpe);
+ sym = owner.info.findMember(newTermName(name + nme.LOCAL_SUFFIX_STRING), 0, 0, false).suchThat(_.tpe =:= tpe)
if (sym == NoSymbol) {
log("Could not find symbol for " + name + ": " + tpe)
log(owner.info.member(name).tpe + " : " + tpe)
- if (name.toString == "toMap")
- tpe = pool.getType(dummySym, ch)
- if (field)
- sym = owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE | javaToScalaFlags(jflags))
- else
- sym = dummySym.setInfo(tpe)
- owner.info.decls.enter(sym)
+ sym = if (field) owner.newValue(name, owner.pos, toScalaFieldFlags(jflags)) else dummySym
+ sym setInfoAndEnter tpe
log("added " + sym + ": " + sym.tpe)
}
(jflags, sym)
@@ -119,19 +113,6 @@ abstract class ICodeReader extends ClassfileParser {
}
}
- private def javaToScalaFlags(flags: Int): Long = {
- import ch.epfl.lamp.fjbg.JAccessFlags._
-
- var res = 0L
- if ((flags & ACC_PRIVATE) != 0) res |= Flags.PRIVATE
- if ((flags & ACC_PROTECTED) != 0) res |= Flags.PROTECTED
- if ((flags & ACC_FINAL) != 0) res |= Flags.FINAL
- if ((flags & ACC_ABSTRACT) != 0) res |= Flags.DEFERRED
- if ((flags & ACC_SYNTHETIC) != 0) res |= Flags.SYNTHETIC
-
- res
- }
-
/** Checks if `tp1` is the same type as `tp2`, modulo implicit methods.
* We don't care about the distinction between implicit and explicit
* methods as this point, and we can't get back the information from
@@ -988,7 +969,7 @@ abstract class ICodeReader extends ClassfileParser {
/** Return a fresh Local variable for the given index.
*/
private def freshLocal(idx: Int, kind: TypeKind, isArg: Boolean) = {
- val sym = method.symbol.newVariable(NoPosition, newTermName("loc" + idx)).setInfo(kind.toType);
+ val sym = method.symbol.newVariable(newTermName("loc" + idx)).setInfo(kind.toType);
val l = new Local(sym, kind, isArg)
method.addLocal(l)
l
@@ -1005,7 +986,7 @@ abstract class ICodeReader extends ClassfileParser {
/** add a method param with the given index. */
def enterParam(idx: Int, kind: TypeKind) = {
- val sym = method.symbol.newVariable(NoPosition, newTermName("par" + idx)).setInfo(kind.toType)
+ val sym = method.symbol.newVariable(newTermName("par" + idx)).setInfo(kind.toType)
val l = new Local(sym, kind, true)
assert(!locals.isDefinedAt(idx))
locals += (idx -> List((l, kind)))
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
index 676c8f09da..ead431c8d7 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
@@ -68,7 +68,7 @@ abstract class MetaParser{
else if (token == "-") { nextToken(); Flags.CONTRAVARIANT }
else 0;
assert(token startsWith "?", token)
- val sym = owner.newTypeParameter(NoPosition, newTypeName(token)).setFlag(vflag)
+ val sym = owner.newTypeParameter(newTypeName(token)).setFlag(vflag)
nextToken()
val lo =
if (token == ">") { nextToken(); parseType() }
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index e7d08ef849..2eddd36db0 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -145,11 +145,8 @@ abstract class Pickler extends SubComponent {
val (locals, globals) = sym.children partition (_.isLocalClass)
val children =
if (locals.isEmpty) globals
- else {
- val localChildDummy = sym.newClass(sym.pos, tpnme.LOCAL_CHILD)
- localChildDummy.setInfo(ClassInfoType(List(sym.tpe), EmptyScope, localChildDummy))
- globals + localChildDummy
- }
+ else globals + sym.newClassWithInfo(tpnme.LOCAL_CHILD, List(sym.tpe), EmptyScope, pos = sym.pos)
+
putChildren(sym, children.toList sortBy (_.sealedSortName))
}
for (annot <- sym.annotations filter (ann => ann.isStatic && !ann.isErroneous) reverse)
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index e0cb0848be..6c238f52cc 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -175,7 +175,7 @@ abstract class TypeParser {
// first pass
for (tvarCILDef <- typ.getSortedTVars() ) {
val tpname = newTypeName(tvarCILDef.Name.replaceAll("!", "")) // TODO are really all type-params named in all assemblies out there? (NO)
- val tpsym = clazz.newTypeParameter(NoPosition, tpname)
+ val tpsym = clazz.newTypeParameter(tpname)
classTParams.put(tvarCILDef.Number, tpsym)
newTParams += tpsym
// TODO wouldn't the following also be needed later, i.e. during getCLRType
@@ -259,8 +259,8 @@ abstract class TypeParser {
|| ntype.IsInterface /* TODO why shouldn't nested ifaces be type-parsed too? */ )
{
val loader = new loaders.MsilFileLoader(new MsilFile(ntype))
- val nclazz = statics.newClass(NoPosition, ntype.Name.toTypeName)
- val nmodule = statics.newModule(NoPosition, ntype.Name)
+ val nclazz = statics.newClass(ntype.Name.toTypeName)
+ val nmodule = statics.newModule(ntype.Name)
nclazz.setInfo(loader)
nmodule.setInfo(loader)
staticDefs.enter(nclazz)
@@ -449,7 +449,7 @@ abstract class TypeParser {
// first pass
for (mvarCILDef <- method.getSortedMVars() ) {
val mtpname = newTypeName(mvarCILDef.Name.replaceAll("!", "")) // TODO are really all method-level-type-params named in all assemblies out there? (NO)
- val mtpsym = methodSym.newTypeParameter(NoPosition, mtpname)
+ val mtpsym = methodSym.newTypeParameter(mtpname)
methodTParams.put(mvarCILDef.Number, mtpsym)
newMethodTParams += mtpsym
// TODO wouldn't the following also be needed later, i.e. during getCLRType
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index c59a819b02..17d63ea439 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -77,31 +77,51 @@ abstract class AddInterfaces extends InfoTransform {
def implClassPhase = currentRun.erasurePhase.next
/** Return the implementation class of a trait; create a new one of one does not yet exist */
- def implClass(iface: Symbol): Symbol = implClassMap.getOrElse(iface, {
- atPhase(implClassPhase) {
- val implName = nme.implClassName(iface.name)
- var impl = if (iface.owner.isClass) iface.owner.info.decl(implName) else NoSymbol
- if (impl != NoSymbol && settings.XO.value) {
- log("unlinking impl class " + impl)
- iface.owner.info.decls.unlink(impl)
- impl = NoSymbol
- }
- if (impl == NoSymbol) {
- impl = iface.cloneSymbolImpl(iface.owner)
- impl.name = implName
- impl.sourceFile = iface.sourceFile
- if (iface.owner.isClass)
- iface.owner.info.decls enter impl
+ def implClass(iface: Symbol): Symbol = {
+ iface.info
+
+ implClassMap.getOrElse(iface, {
+ atPhase(implClassPhase) {
+ log("%s.implClass == %s".format(iface, iface.implClass))
+ val implName = nme.implClassName(iface.name)
+ var impl = if (iface.owner.isClass) iface.owner.info.decl(implName) else NoSymbol
+ impl.info
+
+ val originalImpl = impl
+ val originalImplString = originalImpl.hasFlagsToString(-1L)
+ if (impl != NoSymbol) {
+ // Unlink a pre-existing symbol only if the implementation class is
+ // visible on the compilation classpath. In general this is true under
+ // -optimise and not otherwise, but the classpath can use arbitrary
+ // logic so the classpath must be queried.
+ if (classPath.context.isValidName(implName + ".class")) {
+ log("unlinking impl class " + impl)
+ iface.owner.info.decls.unlink(impl)
+ impl = NoSymbol
+ }
+ else log("not unlinking existing " + impl + " as the impl class is not visible on the classpath.")
+ }
+ if (impl == NoSymbol) {
+ impl = iface.cloneSymbolImpl(iface.owner)
+ impl.name = implName
+ impl.sourceFile = iface.sourceFile
+ if (iface.owner.isClass)
+ iface.owner.info.decls enter impl
+ }
+ if (currentRun.compiles(iface)) currentRun.symSource(impl) = iface.sourceFile
+ impl setPos iface.pos
+ impl.flags = iface.flags & ~(INTERFACE | lateINTERFACE) | IMPLCLASS
+ impl setInfo new LazyImplClassType(iface)
+ implClassMap(iface) = impl
+ debuglog(
+ "generating impl class " + impl + " " + impl.hasFlagsToString(-1L) + " in " + iface.owner + (
+ if (originalImpl == NoSymbol) "" else " (cloned from " + originalImpl.fullLocationString + " " + originalImplString + ")"
+ )
+ )
+ impl
}
- if (currentRun.compiles(iface)) currentRun.symSource(impl) = iface.sourceFile
- impl setPos iface.pos
- impl.flags = iface.flags & ~(INTERFACE | lateINTERFACE) | IMPLCLASS
- impl setInfo new LazyImplClassType(iface)
- implClassMap(iface) = impl
- debuglog("generating impl class " + impl + " in " + iface.owner)//debug
- impl
- }
- })
+ })
+ }
/** A lazy type to set the info of an implementation class
* The parents of an implementation class for trait iface are:
@@ -121,8 +141,11 @@ abstract class AddInterfaces extends InfoTransform {
private def implDecls(implClass: Symbol, ifaceDecls: Scope): Scope = {
val decls = new Scope
if ((ifaceDecls lookup nme.MIXIN_CONSTRUCTOR) == NoSymbol)
- decls enter (implClass.newMethod(implClass.pos, nme.MIXIN_CONSTRUCTOR)
- setInfo MethodType(List(), UnitClass.tpe))
+ decls enter (
+ implClass.newMethod(nme.MIXIN_CONSTRUCTOR, implClass.pos)
+ setInfo MethodType(Nil, UnitClass.tpe)
+ )
+
for (sym <- ifaceDecls.iterator) {
if (isInterfaceMember(sym)) {
if (needsImplMethod(sym)) {
@@ -247,8 +270,8 @@ abstract class AddInterfaces extends InfoTransform {
addMixinConstructorDef(clazz, templ.body map implMemberDef))
.setSymbol(clazz.newLocalDummy(templ.pos))
}
- new ChangeOwnerTraverser(templ.symbol.owner, clazz)(
- new ChangeOwnerTraverser(templ.symbol, templ1.symbol)(templ1))
+ templ1.changeOwner(templ.symbol.owner -> clazz, templ.symbol -> templ1.symbol)
+ templ1
}
def implClassDefs(trees: List[Tree]): List[Tree] = {
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 034628e95f..50e6139e65 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -143,15 +143,14 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* ### CREATING THE METHOD CACHE ### */
def addStaticVariableToClass(forName: TermName, forType: Type, forInit: Tree, isFinal: Boolean): Symbol = {
- val varSym = (
- currentClass.newVariable(ad.pos, mkTerm("" + forName))
- setFlag PRIVATE | STATIC | SYNTHETIC
- setInfo forType
+ val flags = PRIVATE | STATIC | SYNTHETIC | (
+ if (isFinal) FINAL else 0
)
- if (isFinal) varSym setFlag FINAL
- else varSym.addAnnotation(VolatileAttr)
+
+ val varSym = currentClass.newVariable(mkTerm("" + forName), ad.pos, flags) setInfoAndEnter forType
+ if (!isFinal)
+ varSym.addAnnotation(VolatileAttr)
- currentClass.info.decls enter varSym
val varDef = typedPos( VAL(varSym) === forInit )
newStaticMembers append transform(varDef)
@@ -163,13 +162,12 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def addStaticMethodToClass(forName: String, forArgsTypes: List[Type], forResultType: Type)
(forBody: Pair[Symbol, List[Symbol]] => Tree): Symbol = {
- val methSym = currentClass.newMethod(ad.pos, mkTerm(forName))
- .setFlag(STATIC | SYNTHETIC)
- methSym.setInfo(MethodType(methSym.newSyntheticValueParams(forArgsTypes), forResultType))
- currentClass.info.decls enter methSym
+ val methSym = currentClass.newMethod(mkTerm(forName), ad.pos, STATIC | SYNTHETIC)
+ val params = methSym.newSyntheticValueParams(forArgsTypes)
+ methSym setInfoAndEnter MethodType(params, forResultType)
- val methDef = typedPos( DefDef(methSym, { forBody(Pair(methSym, methSym.paramss(0))) }) )
+ val methDef = typedPos( DefDef(methSym, forBody(methSym -> params)) )
newStaticMembers append transform(methDef)
methSym
@@ -280,7 +278,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe)
{ case Pair(reflMethodSym, List(forReceiverSym)) =>
- val methodSym = reflMethodSym.newVariable(ad.pos, mkTerm("method")) setInfo MethodClass.tpe
+ val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe
BLOCK(
IF (getPolyCache OBJ_EQ NULL) THEN (safeREF(reflPolyCacheSym) === mkNewPolyCache) ENDIF,
@@ -404,7 +402,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def invocation = (lookup DOT invokeName)(qual1(), invokeArgs) // .invoke(qual1, ...)
// exception catching machinery
- val invokeExc = currentOwner.newValue(ad.pos, mkTerm("")) setInfo InvocationTargetExceptionClass.tpe
+ val invokeExc = currentOwner.newValue(mkTerm(""), ad.pos) setInfo InvocationTargetExceptionClass.tpe
def catchVar = Bind(invokeExc, Typed(Ident(nme.WILDCARD), TypeTree(InvocationTargetExceptionClass.tpe)))
def catchBody = Throw(Apply(Select(Ident(invokeExc), nme.getCause), Nil))
@@ -492,7 +490,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
assert(params.length == mparams.length, mparams)
typedPos {
- val sym = currentOwner.newValue(ad.pos, mkTerm("qual")) setInfo qual0.tpe
+ val sym = currentOwner.newValue(mkTerm("qual"), ad.pos) setInfo qual0.tpe
qual = safeREF(sym)
BLOCK(
@@ -565,7 +563,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
case theTry @ Try(block, catches, finalizer)
if theTry.tpe.typeSymbol != definitions.UnitClass && theTry.tpe.typeSymbol != definitions.NothingClass =>
val tpe = theTry.tpe.widen
- val tempVar = currentOwner.newVariable(theTry.pos, mkTerm(nme.EXCEPTION_RESULT_PREFIX)).setInfo(tpe)
+ val tempVar = currentOwner.newVariable(mkTerm(nme.EXCEPTION_RESULT_PREFIX), theTry.pos).setInfo(tpe)
def assignBlock(rhs: Tree) = super.transform(BLOCK(Ident(tempVar) === transform(rhs)))
val newBlock = assignBlock(block)
@@ -637,8 +635,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
// create a symbol for the static field
val stfieldSym = (
- currentClass.newVariable(pos, mkTerm("symbol$"))
- setFlag PRIVATE | STATIC | SYNTHETIC | FINAL
+ currentClass.newVariable(mkTerm("symbol$"), pos, PRIVATE | STATIC | SYNTHETIC | FINAL)
setInfo SymbolClass.tpe
)
currentClass.info.decls enter stfieldSym
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 4d4f4f4c27..23817545e2 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -105,8 +105,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
// Move tree into constructor, take care of changing owner from `oldowner` to constructor symbol
def intoConstructor(oldowner: Symbol, tree: Tree) =
- intoConstructorTransformer.transform(
- new ChangeOwnerTraverser(oldowner, constr.symbol)(tree))
+ intoConstructorTransformer transform tree.changeOwner(oldowner -> constr.symbol)
// Should tree be moved in front of super constructor call?
def canBeMoved(tree: Tree) = tree match {
@@ -393,11 +392,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
/** Create a getter or a setter and enter into `clazz` scope
*/
def addAccessor(sym: Symbol, name: TermName, flags: Long) = {
- val m = (
- clazz.newMethod(sym.pos, name)
- setFlag (flags & ~LOCAL & ~PRIVATE)
- setPrivateWithin clazz
- )
+ val m = clazz.newMethod(name, sym.pos, flags & ~(LOCAL | PRIVATE)) setPrivateWithin clazz
clazz.info.decls enter m
}
@@ -405,12 +400,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
val getr = addAccessor(
sym, nme.getterName(sym.name), getterFlags(sym.flags))
getr setInfo MethodType(List(), sym.tpe)
- defBuf += localTyper.typed {
- //util.trace("adding getter def for "+getr) {
- atPos(sym.pos) {
- DefDef(getr, Select(This(clazz), sym))
- }//}
- }
+ defBuf += localTyper.typedPos(sym.pos)(DefDef(getr, Select(This(clazz), sym)))
getr
}
@@ -454,28 +444,24 @@ abstract class Constructors extends Transform with ast.TreeDSL {
def delayedInitClosure(stats: List[Tree]) =
localTyper.typed {
atPos(impl.pos) {
- val closureClass = clazz.newClass(impl.pos, nme.delayedInitArg.toTypeName)
- .setFlag(SYNTHETIC | FINAL)
+ val closureClass = clazz.newClass(nme.delayedInitArg.toTypeName, impl.pos, SYNTHETIC | FINAL)
val closureParents = List(AbstractFunctionClass(0).tpe, ScalaObjectClass.tpe)
- closureClass.setInfo(new ClassInfoType(closureParents, new Scope, closureClass))
-
- val outerField = closureClass.newValue(impl.pos, nme.OUTER)
- .setFlag(PrivateLocal | PARAMACCESSOR)
- .setInfo(clazz.tpe)
-
- val applyMethod = closureClass.newMethod(impl.pos, nme.apply)
- .setFlag(FINAL)
- .setInfo(MethodType(List(), ObjectClass.tpe))
-
- closureClass.info.decls enter outerField
- closureClass.info.decls enter applyMethod
-
- val outerFieldDef = ValDef(outerField)
-
- val changeOwner = new ChangeOwnerTraverser(impl.symbol, applyMethod)
+ closureClass setInfoAndEnter new ClassInfoType(closureParents, new Scope, closureClass)
+
+ val outerField = (
+ closureClass
+ newValue(nme.OUTER, impl.pos, PrivateLocal | PARAMACCESSOR)
+ setInfoAndEnter clazz.tpe
+ )
+ val applyMethod = (
+ closureClass
+ newMethod(nme.apply, impl.pos, FINAL)
+ setInfoAndEnter MethodType(Nil, ObjectClass.tpe)
+ )
+ val outerFieldDef = ValDef(outerField)
val closureClassTyper = localTyper.atOwner(closureClass)
- val applyMethodTyper = closureClassTyper.atOwner(applyMethod)
+ val applyMethodTyper = closureClassTyper.atOwner(applyMethod)
val constrStatTransformer = new Transformer {
override def transform(tree: Tree): Tree = tree match {
@@ -507,8 +493,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
}
else tree
case _ =>
- changeOwner.changeOwner(tree)
- tree
+ tree.changeOwner(impl.symbol -> applyMethod)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index f3b1e77c8d..71696c24e6 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -768,10 +768,8 @@ abstract class Erasure extends AddInterfaces
}
);
if (bridgeNeeded) {
- val bridge = other.cloneSymbolImpl(owner)
- .setPos(owner.pos)
- .setFlag(member.flags | BRIDGE)
- .resetFlag(ACCESSOR | DEFERRED | LAZY | lateDEFERRED)
+ val newFlags = (member.flags | BRIDGE) & ~(ACCESSOR | DEFERRED | LAZY | lateDEFERRED)
+ val bridge = other.cloneSymbolImpl(owner, newFlags) setPos owner.pos
// the parameter symbols need to have the new owner
bridge.setInfo(otpe.cloneInfo(bridge))
bridgeTarget(bridge) = member
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index cf7d6c94fe..14f3dc16fa 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -91,6 +91,21 @@ abstract class ExplicitOuter extends InfoTransform
if (firstTry != NoSymbol && firstTry.outerSource == clazz) firstTry
else clazz.info.decls find (_.outerSource == clazz) getOrElse NoSymbol
}
+ def newOuterAccessor(clazz: Symbol) = {
+ val accFlags = SYNTHETIC | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 )
+ val sym = clazz.newMethodSymbol(nme.OUTER, clazz.pos, accFlags)
+ val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType
+
+ sym expandName clazz
+ sym.referenced = clazz
+ sym setInfo MethodType(Nil, restpe)
+ }
+ def newOuterField(clazz: Symbol) = {
+ val accFlags = SYNTHETIC | PARAMACCESSOR | ( if (clazz.isEffectivelyFinal) PrivateLocal else PROTECTED )
+ val sym = clazz.newValue(nme.OUTER_LOCAL, clazz.pos, accFlags)
+
+ sym setInfo clazz.outerClass.thisType
+ }
/** <p>
* The type transformation method:
@@ -136,7 +151,7 @@ abstract class ExplicitOuter extends InfoTransform
}
if (sym.owner.isTrait) sym setNotFlag PROTECTED // 6
if (sym.isClassConstructor && isInner(sym.owner)) { // 1
- val p = sym.newValueParameter(sym.pos, innerClassConstructorParamName)
+ val p = sym.newValueParameter(innerClassConstructorParamName, sym.pos)
.setInfo(sym.owner.outerClass.thisType)
MethodType(p :: params, restpe)
} else if (restpe ne restpe1)
@@ -146,27 +161,20 @@ abstract class ExplicitOuter extends InfoTransform
var decls1 = decls
if (isInner(clazz) && !clazz.isInterface) {
decls1 = decls.cloneScope
- val outerAcc = clazz.newMethod(clazz.pos, nme.OUTER) // 3
+ val outerAcc = clazz.newMethod(nme.OUTER, clazz.pos) // 3
outerAcc expandName clazz
-
- val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType
- decls1 enter (clazz.newOuterAccessor(clazz.pos) setInfo MethodType(Nil, restpe))
- if (hasOuterField(clazz)) { //2
- val access = if (clazz.isEffectivelyFinal) PrivateLocal else PROTECTED
- decls1 enter (
- clazz.newValue(clazz.pos, nme.OUTER_LOCAL)
- setFlag (SYNTHETIC | PARAMACCESSOR | access)
- setInfo clazz.outerClass.thisType
- )
- }
+
+ decls1 enter newOuterAccessor(clazz)
+ if (hasOuterField(clazz)) //2
+ decls1 enter newOuterField(clazz)
}
if (!clazz.isTrait && !parents.isEmpty) {
for (mc <- clazz.mixinClasses) {
val mixinOuterAcc: Symbol = atPhase(phase.next)(outerAccessor(mc))
if (mixinOuterAcc != NoSymbol) {
if (decls1 eq decls) decls1 = decls.cloneScope
- val newAcc = mixinOuterAcc.cloneSymbol(clazz)
- newAcc resetFlag DEFERRED setInfo (clazz.thisType memberType mixinOuterAcc)
+ val newAcc = mixinOuterAcc.cloneSymbol(clazz, mixinOuterAcc.flags & ~DEFERRED)
+ newAcc setInfo (clazz.thisType memberType mixinOuterAcc)
decls1 enter newAcc
}
}
@@ -372,15 +380,13 @@ abstract class ExplicitOuter extends InfoTransform
def makeGuardDef(vs: List[Symbol], guard: Tree) = {
val gdname = unit.freshTermName("gd")
- val method = currentOwner.newMethod(tree.pos, gdname) setFlag SYNTHETIC
- val fmls = vs map (_.tpe)
- val tpe = new MethodType(method newSyntheticValueParams fmls, BooleanClass.tpe)
- method setInfo tpe
-
- localTyper typed (DEF(method) === {
- new ChangeOwnerTraverser(currentOwner, method) traverse guard
- new TreeSymSubstituter(vs, method.paramss.head) transform (guard)
- })
+ val method = currentOwner.newMethod(gdname, tree.pos, SYNTHETIC)
+ val params = method newSyntheticValueParams vs.map(_.tpe)
+ method setInfo new MethodType(params, BooleanClass.tpe)
+
+ localTyper typed {
+ DEF(method) === guard.changeOwner(currentOwner -> method).substTreeSyms(vs zip params: _*)
+ }
}
val nguard = new ListBuffer[Tree]
@@ -475,7 +481,7 @@ abstract class ExplicitOuter extends InfoTransform
val vparamss1 =
if (isInner(clazz)) { // (4)
val outerParam =
- sym.newValueParameter(sym.pos, nme.OUTER) setInfo outerField(clazz).info
+ sym.newValueParameter(nme.OUTER, sym.pos) setInfo outerField(clazz).info
((ValDef(outerParam) setType NoType) :: vparamss.head) :: vparamss.tail
} else vparamss
super.transform(treeCopy.DefDef(tree, mods, name, tparams, vparamss1, tpt, rhs))
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 2180fd4f3a..712298bd89 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -9,7 +9,8 @@ package transform
import symtab._
import Flags._
import util.TreeSet
-import scala.collection.mutable.{ LinkedHashMap, ListBuffer }
+import scala.collection.{ mutable, immutable }
+import scala.collection.mutable.LinkedHashMap
abstract class LambdaLift extends InfoTransform {
import global._
@@ -64,6 +65,8 @@ abstract class LambdaLift extends InfoTransform {
/** The set of symbols that need to be renamed. */
private val renamable = newSymSet
+ private val renamableImplClasses = mutable.HashMap[Name, Symbol]() withDefaultValue NoSymbol
+
/** A flag to indicate whether new free variables have been found */
private var changedFreeVars: Boolean = _
@@ -152,7 +155,21 @@ abstract class LambdaLift extends InfoTransform {
tree match {
case ClassDef(_, _, _, _) =>
liftedDefs(tree.symbol) = Nil
- if (sym.isLocal) renamable addEntry sym
+ if (sym.isLocal) {
+ // Don't rename implementation classes independently of their interfaces. If
+ // the interface is to be renamed, then we will rename the implementation
+ // class at that time. You'd think we could call ".implClass" on the trait
+ // rather than collecting them in another map, but that seems to fail for
+ // exactly the traits being renamed here (i.e. defined in methods.)
+ //
+ // !!! - it makes no sense to have methods like "implClass" and
+ // "companionClass" which fail for an arbitrary subset of nesting
+ // arrangements, and then have separate methods which attempt to compensate
+ // for that failure. There should be exactly one method for any given
+ // entity which always gives the right answer.
+ if (sym.isImplClass) renamableImplClasses(nme.interfaceName(sym.name)) = sym
+ else renamable addEntry sym
+ }
case DefDef(_, _, _, _, _, _) =>
if (sym.isLocal) {
renamable addEntry sym
@@ -196,8 +213,8 @@ abstract class LambdaLift extends InfoTransform {
for (caller <- called.keys ; callee <- called(caller) ; fvs <- free get callee ; fv <- fvs)
markFree(fv, caller)
} while (changedFreeVars)
-
- for (sym <- renamable) {
+
+ def renameSym(sym: Symbol) {
val originalName = sym.name
val base = sym.name + nme.NAME_JOIN_STRING + (
if (sym.isAnonymousFunction && sym.owner.isMethod)
@@ -211,19 +228,35 @@ abstract class LambdaLift extends InfoTransform {
debuglog("renaming in %s: %s => %s".format(sym.owner.fullLocationString, originalName, sym.name))
}
+ /** Rename a trait's interface and implementation class in coordinated fashion.
+ */
+ def renameTrait(traitSym: Symbol, implSym: Symbol) {
+ val originalImplName = implSym.name
+ renameSym(traitSym)
+ implSym.name = nme.implClassName(traitSym.name)
+
+ debuglog("renaming impl class in step with %s: %s => %s".format(traitSym, originalImplName, implSym.name))
+ }
+
+ for (sym <- renamable) {
+ // If we renamed a trait from Foo to Foo$1, we must rename the implementation
+ // class from Foo$class to Foo$1$class. (Without special consideration it would
+ // become Foo$class$1 instead.)
+ val implClass = if (sym.isTrait) renamableImplClasses(sym.name) else NoSymbol
+ if ((implClass ne NoSymbol) && (sym.owner == implClass.owner)) renameTrait(sym, implClass)
+ else renameSym(sym)
+ }
+
atPhase(phase.next) {
for ((owner, freeValues) <- free.toList) {
+ val newFlags = SYNTHETIC | ( if (owner.isClass) PARAMACCESSOR | PrivateLocal else PARAM )
debuglog("free var proxy: %s, %s".format(owner.fullLocationString, freeValues.toList.mkString(", ")))
-
- proxies(owner) =
- for (fv <- freeValues.toList) yield {
- val proxy = owner.newValue(owner.pos, fv.name)
- .setFlag(if (owner.isClass) PARAMACCESSOR | PrivateLocal else PARAM)
- .setFlag(SYNTHETIC)
- .setInfo(fv.info);
- if (owner.isClass) owner.info.decls enter proxy;
- proxy
- }
+ proxies(owner) =
+ for (fv <- freeValues.toList) yield {
+ val proxy = owner.newValue(fv.name, owner.pos, newFlags) setInfo fv.info
+ if (owner.isClass) owner.info.decls enter proxy
+ proxy
+ }
}
}
}
@@ -409,12 +442,12 @@ abstract class LambdaLift extends InfoTransform {
}
else tree1
case Block(stats, expr0) =>
- val (lzyVals, rest) = stats.partition {
- case stat@ValDef(_, _, _, _) if stat.symbol.isLazy => true
- case stat@ValDef(_, _, _, _) if stat.symbol.hasFlag(MODULEVAR) => true
- case _ => false
- }
- treeCopy.Block(tree, lzyVals:::rest, expr0)
+ val (lzyVals, rest) = stats partition {
+ case stat: ValDef => stat.symbol.isLazy || stat.symbol.isModuleVar
+ case _ => false
+ }
+ if (lzyVals.isEmpty) tree
+ else treeCopy.Block(tree, lzyVals ::: rest, expr0)
case _ =>
tree
}
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index 5452087aa3..f8c5f5bfc6 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -246,7 +246,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
if (bmps.length > n)
bmps(n)
else {
- val sym = meth.newVariable(meth.pos, nme.newBitmapName(nme.BITMAP_NORMAL, n)).setInfo(IntClass.tpe)
+ val sym = meth.newVariable(nme.newBitmapName(nme.BITMAP_NORMAL, n), meth.pos).setInfo(IntClass.tpe)
atPhase(currentRun.typerPhase) {
sym addAnnotation VolatileAttr
}
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index bc7d1754d4..c5475fa0f2 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -71,6 +71,8 @@ abstract class LiftCode extends Transform with TypingTransformers {
case mod => mod.toString
}
+ // I fervently hope this is a test case or something, not anything being
+ // depended upon. Of more fragile code I cannot conceive.
for (line <- (tree.toString.split(Properties.lineSeparator) drop 2 dropRight 1)) {
var s = line.trim
s = s.replace("$mr.", "")
@@ -81,24 +83,23 @@ abstract class LiftCode extends Transform with TypingTransformers {
s = s.replace("immutable.this.Nil", "List()")
s = s.replace("modifiersFromInternalFlags", "Modifiers")
s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()")
- s = """Modifiers\((\d+)L, newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => {
- val buf = new StringBuffer()
+ s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => {
+ val buf = new StringBuilder
val flags = m.group(1).toLong
- var s_flags = Flags.modifiersOfFlags(flags) map copypasteModifier
- buf.append("Set(" + s_flags.mkString(", ") + ")")
+ val s_flags = Flags.modifiersOfFlags(flags) map copypasteModifier mkString ", "
+ if (s_flags != "")
+ buf.append("Set(" + s_flags + ")")
- var privateWithin = m.group(2)
- buf.append(", " + "newTypeName(\"" + privateWithin + "\")")
+ val privateWithin = "" + m.group(2)
+ if (privateWithin != "")
+ buf.append(", newTypeName(\"" + privateWithin + "\")")
- var annotations = m.group(3)
- buf.append(", " + "List(" + annotations + ")")
+ val annotations = m.group(3)
+ if (annotations.nonEmpty)
+ buf.append(", List(" + annotations + ")")
- var s = buf.toString
- if (s.endsWith(", List()")) s = s.substring(0, s.length - ", List()".length)
- if (s.endsWith(", newTypeName(\"\")")) s = s.substring(0, s.length - ", newTypeName(\"\")".length)
- if (s.endsWith("Set()")) s = s.substring(0, s.length - "Set()".length)
- "Modifiers(" + s + ")"
+ "Modifiers(" + buf.toString + ")"
})
s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => {
val flags = m.group(1).toLong
@@ -310,13 +311,13 @@ abstract class LiftCode extends Transform with TypingTransformers {
*/
private def reifySymbolDef(sym: Symbol): Tree = {
if (reifyDebug) println("reify sym def " + sym)
- var rsym: Tree =
+
+ ValDef(NoMods, localName(sym), TypeTree(),
Apply(
Select(reify(sym.owner), "newNestedSymbol"),
- List(reify(sym.pos), reify(sym.name)))
- if (sym.flags != 0L)
- rsym = Apply(Select(rsym, "setInternalFlags"), List(Literal(Constant(sym.flags))))
- ValDef(NoMods, localName(sym), TypeTree(), rsym)
+ List(reify(sym.name), reify(sym.pos), Literal(Constant(sym.flags)))
+ )
+ )
}
/**
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index c7d3b331a6..bf19cf10e9 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -186,13 +186,9 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
* always accessors and deferred. */
def newGetter(field: Symbol): Symbol = {
// println("creating new getter for "+ field +" : "+ field.info +" at "+ field.locationString+(field hasFlag MUTABLE))
- // atPhase(currentRun.erasurePhase){
- // println("before erasure: "+ (field.info))
- // }
- clazz.newMethod(field.pos, nme.getterName(field.name))
- .setFlag(field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED |
- (if (field.isMutable) 0 else STABLE))
- .setInfo(MethodType(List(), field.info)) // TODO preserve pre-erasure info?
+ val newFlags = field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED | ( if (field.isMutable) 0 else STABLE )
+ // TODO preserve pre-erasure info?
+ clazz.newMethod(nme.getterName(field.name), field.pos, newFlags) setInfo MethodType(Nil, field.info)
}
/** Create a new setter. Setters are never private or local. They are
@@ -200,13 +196,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def newSetter(field: Symbol): Symbol = {
//println("creating new setter for "+field+field.locationString+(field hasFlag MUTABLE))
val setterName = nme.getterToSetter(nme.getterName(field.name))
- val setter = clazz.newMethod(field.pos, setterName)
- .setFlag(field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED)
- setter.setInfo(MethodType(setter.newSyntheticValueParams(List(field.info)), UnitClass.tpe)) // TODO preserve pre-erasure info?
- if (needsExpandedSetterName(field)) {
- //println("creating expanded setter from "+field)
+ val newFlags = field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED
+ val setter = clazz.newMethod(setterName, field.pos, newFlags)
+ // TODO preserve pre-erasure info?
+ setter setInfo MethodType(setter.newSyntheticValueParams(List(field.info)), UnitClass.tpe)
+ if (needsExpandedSetterName(field))
setter.name = nme.expandedSetterName(setter.name, clazz)
- }
+
setter
}
@@ -343,7 +339,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// so it can no longer be found in the member's owner (the trait)
val accessed = atPhase(currentRun.picklerPhase)(member.accessed)
val sym = atPhase(currentRun.erasurePhase){ // #3857, need to retain info before erasure when cloning (since cloning only carries over the current entry in the type history)
- clazz.newValue(member.pos, nme.getterToLocal(member.name)).setInfo(member.tpe.resultType) // so we have a type history entry before erasure
+ clazz.newValue(nme.getterToLocal(member.name), member.pos).setInfo(member.tpe.resultType) // so we have a type history entry before erasure
}
sym.updateInfo(member.tpe.resultType) // info at current phase
addMember(clazz,
@@ -361,9 +357,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
} else if (member.isMethod && member.isModule && member.hasNoFlags(LIFTED | BRIDGE)) {
// mixin objects: todo what happens with abstract objects?
- addMember(clazz, member.cloneSymbol(clazz))
- .setPos(clazz.pos)
- .resetFlag(DEFERRED | lateDEFERRED)
+ addMember(clazz, member.cloneSymbol(clazz, member.flags & ~(DEFERRED | lateDEFERRED)) setPos clazz.pos)
}
}
}
@@ -396,9 +390,12 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
if (sourceModule != NoSymbol) {
sourceModule setPos sym.pos
sourceModule.flags = MODULE | FINAL
- } else {
- sourceModule = clazz.owner.newModule(
- sym.pos, sym.name.toTermName, sym.asInstanceOf[ClassSymbol])
+ }
+ else {
+ sourceModule = (
+ clazz.owner.newModuleSymbol(sym.name.toTermName, sym.pos, MODULE | FINAL)
+ setModuleClass sym.asInstanceOf[ClassSymbol]
+ )
clazz.owner.info.decls enter sourceModule
}
sourceModule setInfo sym.tpe
@@ -530,9 +527,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
if (currentOwner.isImplClass) {
if (isImplementedStatically(sym)) {
sym setFlag notOVERRIDE
- self = sym.newValue(sym.pos, nme.SELF)
- .setFlag(PARAM)
- .setInfo(toInterface(currentOwner.typeOfThis));
+ self = sym.newValueParameter(nme.SELF, sym.pos) setInfo toInterface(currentOwner.typeOfThis)
val selfdef = ValDef(self) setType NoType
treeCopy.DefDef(tree, mods, name, tparams, List(selfdef :: vparams), tpt, rhs)
} else {
@@ -742,7 +737,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
assert(!sym.isOverloaded, sym)
def createBitmap: Symbol = {
- val sym = clazz0.newVariable(clazz0.pos, bitmapName) setInfo IntClass.tpe
+ val sym = clazz0.newVariable(bitmapName, clazz0.pos) setInfo IntClass.tpe
atPhase(currentRun.typerPhase)(sym addAnnotation VolatileAttr)
category match {
diff --git a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
index 73d17458bf..f7d2c9de28 100644
--- a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
+++ b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
@@ -37,8 +37,8 @@ abstract class SampleTransform extends Transform {
Select( // The `Select` factory method is defined in class `Trees`
sup,
currentOwner.newValue( // creates a new term symbol owned by `currentowner`
- tree1.pos,
- newTermName("sample")))))) // The standard term name creator
+ newTermName("sample"), // The standard term name creator
+ tree1.pos)))))
case _ =>
tree1
}
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 99b0a82690..fd826fb6d8 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -64,6 +64,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
type TypeEnv = immutable.Map[Symbol, Type]
def emptyEnv: TypeEnv = Map[Symbol, Type]()
+
private implicit val typeOrdering: Ordering[Type] = Ordering[String] on ("" + _.typeSymbol.name)
import definitions.{
@@ -73,6 +74,34 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
AnyRefClass, ObjectClass, Predef_AnyRef,
uncheckedVarianceClass
}
+
+ /** TODO - this is a lot of maps.
+ */
+
+ /** For a given class and concrete type arguments, give its specialized class */
+ val specializedClass: mutable.Map[(Symbol, TypeEnv), Symbol] = new mutable.LinkedHashMap
+
+ /** Map a method symbol to a list of its specialized overloads in the same class. */
+ private val overloads: mutable.Map[Symbol, List[Overload]] = mutable.HashMap[Symbol, List[Overload]]() withDefaultValue Nil
+
+ /** Map a symbol to additional information on specialization. */
+ private val info: mutable.Map[Symbol, SpecializedInfo] = perRunCaches.newMap[Symbol, SpecializedInfo]()
+
+ /** Map class symbols to the type environments where they were created. */
+ private val typeEnv = mutable.HashMap[Symbol, TypeEnv]() withDefaultValue emptyEnv
+
+ // holds mappings from regular type parameter symbols to symbols of
+ // specialized type parameters which are subtypes of AnyRef
+ private val anyrefSpecCache = perRunCaches.newMap[Symbol, Symbol]()
+
+ // holds mappings from members to the type variables in the class
+ // that they were already specialized for, so that they don't get
+ // specialized twice (this is for AnyRef specializations)
+ private val wasSpecializedForTypeVars = perRunCaches.newMap[Symbol, Set[Symbol]]() withDefaultValue Set()
+
+ /** Concrete methods that use a specialized type, or override such methods. */
+ private val concreteSpecMethods = new mutable.HashSet[Symbol]()
+
private def isSpecialized(sym: Symbol) = sym hasAnnotation SpecializedClass
private def hasSpecializedFlag(sym: Symbol) = sym hasFlag SPECIALIZED
private def specializedTypes(tps: List[Symbol]) = tps filter isSpecialized
@@ -135,21 +164,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
}
- /** For a given class and concrete type arguments, give its specialized class */
- val specializedClass: mutable.Map[(Symbol, TypeEnv), Symbol] = new mutable.LinkedHashMap
-
- /** Returns the generic class that was specialized to 'cls', or
- * 'cls' itself if cls is not a specialized subclass.
+ /** Returns the generic class that was specialized to 'sClass', or
+ * 'sClass' itself if sClass is not a specialized subclass.
*/
- def genericClass(cls: Symbol): Symbol =
- if (hasSpecializedFlag(cls)) cls.info.parents.head.typeSymbol
- else cls
-
- /** Map a method symbol to a list of its specialized overloads in the same class. */
- private val overloads: mutable.Map[Symbol, List[Overload]] =
- new mutable.HashMap[Symbol, List[Overload]] {
- override def default(key: Symbol): List[Overload] = Nil
- }
+ def genericClass(sClass: Symbol): Symbol =
+ if (hasSpecializedFlag(sClass)) sClass.superClass
+ else sClass
case class Overload(sym: Symbol, env: TypeEnv) {
override def toString = "specialized overload " + sym + " in " + env
@@ -227,9 +247,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
}
- /** Map a symbol to additional information on specialization. */
- private val info: mutable.Map[Symbol, SpecializedInfo] = perRunCaches.newMap[Symbol, SpecializedInfo]()
-
/** Has `clazz` any type parameters that need be specialized? */
def hasSpecializedParams(clazz: Symbol) =
clazz.info.typeParams exists isSpecialized
@@ -398,25 +415,21 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case _ => Set()
}
- // holds mappings from regular type parameter symbols to symbols of
- // specialized type parameters which are subtypes of AnyRef
- private val anyrefSpecCache = perRunCaches.newMap[Symbol, Symbol]()
-
- /** Returns the type parameter in the specialized class `cls` that corresponds to type parameter
+ /** Returns the type parameter in the specialized class `clazz` that corresponds to type parameter
* `sym` in the original class. It will create it if needed or use the one from the cache.
*/
- private def typeParamSubAnyRef(sym: Symbol, cls: Symbol) = (
+ private def typeParamSubAnyRef(sym: Symbol, clazz: Symbol) = (
anyrefSpecCache.getOrElseUpdate(sym,
- cls.newTypeParameter(sym.pos, sym.name append nme.SPECIALIZED_SUFFIX_NAME toTypeName)
+ clazz.newTypeParameter(sym.name append nme.SPECIALIZED_SUFFIX_NAME toTypeName, sym.pos)
setInfo TypeBounds(sym.info.bounds.lo, AnyRefClass.tpe)
).tpe
)
/** Cleans the anyrefSpecCache of all type parameter symbols of a class.
*/
- private def cleanAnyRefSpecCache(cls: Symbol, decls: List[Symbol]) = (
+ private def cleanAnyRefSpecCache(clazz: Symbol, decls: List[Symbol]) = (
// remove class type parameters and those of normalized members.
- cls :: decls foreach {
+ clazz :: decls foreach {
_.tpe match {
case PolyType(tparams, _) => anyrefSpecCache --= tparams
case _ => ()
@@ -424,12 +437,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
)
- // holds mappings from members to the type variables in the class
- // that they were already specialized for, so that they don't get
- // specialized twice (this is for AnyRef specializations)
- private val wasSpecializedForTypeVars =
- perRunCaches.newMap[Symbol, immutable.Set[Symbol]]() withDefaultValue immutable.Set[Symbol]()
-
/** Type parameters that survive when specializing in the specified environment. */
def survivingParams(params: List[Symbol], env: TypeEnv) =
params.filter(p => !isSpecialized(p) || !isScalaValueType(env(p)))
@@ -479,38 +486,35 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
def specializeClass(clazz: Symbol, outerEnv: TypeEnv): List[Symbol] = {
def specializedClass(env0: TypeEnv, normMembers: List[Symbol]): Symbol = {
- val cls = clazz.owner.newClass(clazz.pos, specializedName(clazz, env0).toTypeName)
- .setFlag(SPECIALIZED | clazz.flags)
- .resetFlag(CASE)
- cls.sourceFile = clazz.sourceFile
- currentRun.symSource(cls) = clazz.sourceFile // needed later on by mixin
-
- val env = mapAnyRefsInSpecSym(env0, clazz, cls)
-
- typeEnv(cls) = env
- this.specializedClass((clazz, env0)) = cls
+ /** It gets hard to follow all the clazz and cls, and specializedClass
+ * was both already used for a map and mucho long. So "sClass" is the
+ * specialized subclass of "clazz" throughout this file.
+ */
+ val sClass = clazz.owner.newClass(specializedName(clazz, env0).toTypeName, clazz.pos, (clazz.flags | SPECIALIZED) & ~CASE)
- // declarations of the newly specialized class 'cls'
- val decls1 = new Scope
+ def cloneInSpecializedClass(member: Symbol, flagFn: Long => Long) =
+ member.cloneSymbol(sClass, flagFn(member.flags | SPECIALIZED))
+
+ sClass.sourceFile = clazz.sourceFile
+ currentRun.symSource(sClass) = clazz.sourceFile // needed later on by mixin
- // original unspecialized type parameters
- var oldClassTParams: List[Symbol] = Nil
+ val env = mapAnyRefsInSpecSym(env0, clazz, sClass)
+ typeEnv(sClass) = env
+ this.specializedClass((clazz, env0)) = sClass
- // unspecialized type parameters of 'cls' (cloned)
- var newClassTParams: List[Symbol] = Nil
+ val decls1 = new Scope // declarations of the newly specialized class 'sClass'
+ var oldClassTParams: List[Symbol] = Nil // original unspecialized type parameters
+ var newClassTParams: List[Symbol] = Nil // unspecialized type parameters of 'specializedClass' (cloned)
// has to be a val in order to be computed early. It is later called
// within 'atPhase(next)', which would lead to an infinite cycle otherwise
val specializedInfoType: Type = {
- // val (_, unspecParams) = splitParams(clazz.info.typeParams)
- // oldClassTParams = unspecParams
- val survivedParams = survivingParams(clazz.info.typeParams, env)
- oldClassTParams = survivedParams
- newClassTParams = produceTypeParameters(survivedParams, cls, env) map subst(env)
+ oldClassTParams = survivingParams(clazz.info.typeParams, env)
+ newClassTParams = produceTypeParameters(oldClassTParams, sClass, env) map subst(env)
// log("new tparams " + newClassTParams.zip(newClassTParams map {s => (s.tpe, s.tpe.bounds.hi)}) + ", in env: " + env)
def applyContext(tpe: Type) =
- subst(env, tpe).instantiateTypeParams(survivedParams, newClassTParams map (_.tpe))
+ subst(env, tpe).instantiateTypeParams(oldClassTParams, newClassTParams map (_.tpe))
/** Return a list of specialized parents to be re-mixed in a specialized subclass.
* Assuming env = [T -> Int] and
@@ -520,25 +524,24 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* so that class Integral$mci extends Integral[Int] with Numeric$mcI.
*/
def specializedParents(parents: List[Type]): List[Type] = {
- val res = new mutable.ListBuffer[Type]
- // log(cls + ": seeking specialized parents of class with parents: " + parents.map(_.typeSymbol))
+ var res: List[Type] = Nil
+ // log(specializedClass + ": seeking specialized parents of class with parents: " + parents.map(_.typeSymbol))
for (p <- parents) {
- // log(p.typeSymbol)
val stp = atPhase(phase.next)(specializedType(p))
if (stp != p)
- if (p.typeSymbol.isTrait) res += stp
+ if (p.typeSymbol.isTrait) res ::= stp
else if (currentRun.compiles(clazz))
reporter.warning(clazz.pos, p.typeSymbol + " must be a trait. Specialized version of "
+ clazz + " will inherit generic " + p) // TODO change to error
}
- res.reverse.toList
+ res
}
var parents = List(applyContext(atPhase(currentRun.typerPhase)(clazz.tpe)))
// log("!!! Parents: " + parents + ", sym: " + parents.map(_.typeSymbol))
if (parents.head.typeSymbol.isTrait)
parents = parents.head.parents.head :: parents
- val extraSpecializedMixins = specializedParents(clazz.info.parents.map(applyContext))
+ val extraSpecializedMixins = specializedParents(clazz.info.parents map applyContext)
if (extraSpecializedMixins.nonEmpty)
debuglog("specializeClass on " + clazz + " founds extra specialized mixins: " + extraSpecializedMixins.mkString(", "))
// If the class being specialized has a self-type, the self type may
@@ -547,17 +550,16 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// already be covered. Then apply the current context to the self-type
// as with the parents and assign it to typeOfThis.
if (clazz.typeOfThis.typeConstructor ne clazz.typeConstructor) {
- cls.typeOfThis = applyContext(clazz.typeOfThis)
+ sClass.typeOfThis = applyContext(clazz.typeOfThis)
log("Rewriting self-type for specialized class:\n" +
- " " + clazz.defStringSeenAs(clazz.typeOfThis) + "\n" +
- " => " + cls.defStringSeenAs(cls.typeOfThis)
+ " " + clazz.defStringSeenAs(clazz.typeOfThis) + "\n" +
+ " => " + sClass.defStringSeenAs(sClass.typeOfThis)
)
}
- val infoType = ClassInfoType(parents ::: extraSpecializedMixins, decls1, cls)
- if (newClassTParams.isEmpty) infoType else PolyType(newClassTParams, infoType)
+ polyType(newClassTParams, ClassInfoType(parents ::: extraSpecializedMixins, decls1, sClass))
}
- atPhase(phase.next)(cls.setInfo(specializedInfoType))
+ atPhase(phase.next)(sClass setInfo specializedInfoType)
val fullEnv = outerEnv ++ env
/** Enter 'sym' in the scope of the current specialized class. It's type is
@@ -567,13 +569,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
def enterMember(sym: Symbol): Symbol = {
typeEnv(sym) = fullEnv ++ typeEnv(sym) // append the full environment
- sym modifyInfo (_.substThis(clazz, cls).instantiateTypeParams(oldClassTParams, newClassTParams map (_.tpe)))
+ sym modifyInfo (_.substThis(clazz, sClass).instantiateTypeParams(oldClassTParams, newClassTParams map (_.tpe)))
// we remove any default parameters. At this point, they have been all
// resolved by the type checker. Later on, erasure re-typechecks everything and
// chokes if it finds default parameters for specialized members, even though
// they are never needed.
mapParamss(sym)(_ resetFlag DEFAULTPARAM)
- decls1.enter(subst(fullEnv)(sym))
+ decls1 enter subst(fullEnv)(sym)
}
/** Create and enter in scope an overridden symbol m1 for `m` that forwards
@@ -590,13 +592,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* def m$I(x: Int) = <body>/adapted to env {A -> Int} // om
*/
def forwardToOverload(m: Symbol): Symbol = {
- val specMember = (
- enterMember(m cloneSymbol cls)
- setFlag (OVERRIDE | SPECIALIZED)
- resetFlag (DEFERRED | CASEACCESSOR)
- ) // m1
-
- val om = specializedOverload(cls, m, env).setFlag(OVERRIDE)
+ val specMember = enterMember(cloneInSpecializedClass(m, f => (f | OVERRIDE) & ~(DEFERRED | CASEACCESSOR)))
+ val om = specializedOverload(sClass, m, env).setFlag(OVERRIDE)
val original = info.get(m) match {
case Some(NormalizedMember(tg)) => tg
case _ => m
@@ -617,7 +614,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
m.resetFlag(PRIVATE).setFlag(PROTECTED)
if (m.isConstructor) {
- val specCtor = enterMember(m.cloneSymbol(cls) setFlag SPECIALIZED)
+ val specCtor = enterMember(cloneInSpecializedClass(m, x => x))
info(specCtor) = Forward(m)
}
else if (isNormalizedMember(m)) { // methods added by normalization
@@ -625,7 +622,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
if (nonConflicting(env ++ typeEnv(m))) {
if (info(m).degenerate) {
debuglog("degenerate normalized member " + m + " info(m): " + info(m))
- val specMember = enterMember(m.cloneSymbol(cls)).setFlag(SPECIALIZED).resetFlag(DEFERRED)
+ val specMember = enterMember(cloneInSpecializedClass(m, _ & ~DEFERRED))
info(specMember) = Implementation(original)
typeEnv(specMember) = env ++ typeEnv(m)
@@ -639,7 +636,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
log("conflicting env for " + m + " env: " + env)
}
else if (m.isDeferred) { // abstract methods
- val specMember = enterMember(m.cloneSymbol(cls)).setFlag(SPECIALIZED).setFlag(DEFERRED)
+ val specMember = enterMember(cloneInSpecializedClass(m, _ | DEFERRED))
debuglog("deferred " + specMember.fullName + " remains abstract")
info(specMember) = new Abstract(specMember)
@@ -652,24 +649,18 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
} else if (m.isValue && !m.isMethod) { // concrete value definition
def mkAccessor(field: Symbol, name: Name) = {
- val sym = (
- cls.newMethod(field.pos, name)
- setFlag (SPECIALIZED | m.getter(clazz).flags)
- resetFlag (LOCAL | PARAMACCESSOR | CASEACCESSOR | LAZY)
- // we rely on the super class to initialize param accessors
- )
+ val newFlags = (SPECIALIZED | m.getter(clazz).flags) & ~(LOCAL | CASEACCESSOR | PARAMACCESSOR | LAZY)
+ // we rely on the super class to initialize param accessors
+ val sym = sClass.newMethod(name, field.pos, newFlags)
info(sym) = SpecializedAccessor(field)
sym
}
def overrideIn(clazz: Symbol, sym: Symbol) = {
- val sym1 = (
- sym cloneSymbol clazz
- setFlag (OVERRIDE | SPECIALIZED)
- resetFlag (DEFERRED | CASEACCESSOR | PARAMACCESSOR | LAZY)
- )
+ val newFlags = (sym.flags | OVERRIDE | SPECIALIZED) & ~(DEFERRED | CASEACCESSOR | PARAMACCESSOR | LAZY)
+ val sym1 = sym.cloneSymbol(clazz, newFlags)
sym1 modifyInfo (_ asSeenFrom (clazz.tpe, sym1.owner))
}
- val specVal = specializedOverload(cls, m, env)
+ val specVal = specializedOverload(sClass, m, env)
addConcreteSpecMethod(m)
specVal.asInstanceOf[TermSymbol].setAlias(m)
@@ -678,15 +669,15 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// create accessors
debuglog("m: " + m + " isLocal: " + nme.isLocalName(m.name) + " specVal: " + specVal.name + " isLocal: " + nme.isLocalName(specVal.name))
if (nme.isLocalName(m.name)) {
- val specGetter = mkAccessor(specVal, nme.localToGetter(specVal.name)).setInfo(MethodType(List(), specVal.info))
- val origGetter = overrideIn(cls, m.getter(clazz))
+ val specGetter = mkAccessor(specVal, nme.localToGetter(specVal.name)) setInfo MethodType(Nil, specVal.info)
+ val origGetter = overrideIn(sClass, m.getter(clazz))
info(origGetter) = Forward(specGetter)
enterMember(specGetter)
enterMember(origGetter)
debuglog("created accessors: " + specGetter + " orig: " + origGetter)
clazz.caseFieldAccessors.find(_.name.startsWith(m.name)) foreach { cfa =>
- val cfaGetter = overrideIn(cls, cfa)
+ val cfaGetter = overrideIn(sClass, cfa)
info(cfaGetter) = SpecializedAccessor(specVal)
enterMember(cfaGetter)
debuglog("found case field accessor for " + m + " added override " + cfaGetter);
@@ -697,7 +688,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
.resetFlag(STABLE)
specSetter.setInfo(MethodType(specSetter.newSyntheticValueParams(List(specVal.info)),
UnitClass.tpe))
- val origSetter = overrideIn(cls, m.setter(clazz))
+ val origSetter = overrideIn(sClass, m.setter(clazz))
info(origSetter) = Forward(specSetter)
enterMember(specSetter)
enterMember(origSetter)
@@ -707,7 +698,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
specVal.resetFlag(PRIVATE)
}
} else if (m.isClass) {
- val specClass: Symbol = m.cloneSymbol(cls).setFlag(SPECIALIZED)
+ val specClass: Symbol = cloneInSpecializedClass(m, x => x)
typeEnv(specClass) = fullEnv
specClass.name = specializedName(specClass, fullEnv).toTypeName
enterMember(specClass)
@@ -715,7 +706,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
info(specClass) = SpecializedInnerClass(m, fullEnv)
}
}
- cls
+ sClass
}
val decls1 = clazz.info.decls.toList flatMap { m: Symbol =>
@@ -783,7 +774,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
for (env0 <- specializations(specializingOn) if needsSpecialization(env0, sym)) yield {
val tps = survivingParams(sym.info.typeParams, env0)
- val specMember = sym.cloneSymbol(owner).setFlag(SPECIALIZED).resetFlag(DEFERRED)
+ val specMember = sym.cloneSymbol(owner, (sym.flags | SPECIALIZED) & ~DEFERRED)
val env = mapAnyRefsInSpecSym(env0, sym, specMember)
val (keys, vals) = env.toList.unzip
@@ -857,14 +848,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Return the specialized overload of `m`, in the given environment. */
private def specializedOverload(owner: Symbol, sym: Symbol, env: TypeEnv): Symbol = {
- val specMember = sym.cloneSymbol(owner) // this method properly duplicates the symbol's info
+ // this method properly duplicates the symbol's info
+ val specMember = sym.cloneSymbol(owner, (sym.flags | SPECIALIZED) & ~(DEFERRED | CASEACCESSOR | ACCESSOR | LAZY))
specMember.name = specializedName(sym, env)
-
- (specMember
- modifyInfo (info => subst(env, info.asSeenFrom(owner.thisType, sym.owner)))
- setFlag (SPECIALIZED)
- resetFlag (DEFERRED | CASEACCESSOR | ACCESSOR | LAZY)
- )
+ specMember modifyInfo (info => subst(env, info.asSeenFrom(owner.thisType, sym.owner)))
}
/** For each method m that overrides an inherited method m', add a special
@@ -1023,9 +1010,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
}
- /** Map class symbols to the type environments where they were created. */
- private val typeEnv = mutable.HashMap[Symbol, TypeEnv]() withDefaultValue emptyEnv
-
/** Apply type bindings in the given environment `env` to all declarations. */
private def subst(env: TypeEnv, decls: List[Symbol]): List[Symbol] =
decls map subst(env)
@@ -1212,11 +1196,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
clazz.owner.info.decl(originalName).suchThat(_.isClass)
} else NoSymbol
- def illegalSpecializedInheritance(clazz: Symbol): Boolean = {
- hasSpecializedFlag(clazz) && originalClass(clazz).info.parents.exists { p =>
- hasSpecializedParams(p.typeSymbol) && !p.typeSymbol.isTrait
- }
- }
+ def illegalSpecializedInheritance(clazz: Symbol): Boolean = (
+ hasSpecializedFlag(clazz)
+ && originalClass(clazz).parentSymbols.exists(p => hasSpecializedParams(p) && !p.isTrait)
+ )
def specializeCalls(unit: CompilationUnit) = new TypingTransformer(unit) {
/** Map a specializable method to it's rhs, when not deferred. */
@@ -1275,7 +1258,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
.format(tree, symbol.tpe, tree.tpe, env, specializedName(symbol, env)))
if (!env.isEmpty) { // a method?
val specCandidates = qual.tpe.member(specializedName(symbol, env))
- val specMember = specCandidates suchThat (s => doesConform(symbol, tree.tpe, s.tpe, env))
+ val specMember = specCandidates suchThat { s =>
+ doesConform(symbol, tree.tpe, qual.tpe.memberType(s), env)
+ }
+
log("[specSym] found: " + specCandidates.tpe + ", instantiated as: " + tree.tpe)
log("[specSym] found specMember: " + specMember)
if (specMember ne NoSymbol)
@@ -1588,20 +1574,20 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
treeCopy.DefDef(tree, mods, name, tparams, vparamss1, tpt, tmp)
}
- /** Create trees for specialized members of 'cls', based on the
+ /** Create trees for specialized members of 'sClass', based on the
* symbols that are already there.
*/
- private def makeSpecializedMembers(cls: Symbol): List[Tree] = {
+ private def makeSpecializedMembers(sClass: Symbol): List[Tree] = {
// add special overrides first
-// if (!cls.hasFlag(SPECIALIZED))
-// for (m <- specialOverrides(cls)) cls.info.decls.enter(m)
+// if (!specializedClass.hasFlag(SPECIALIZED))
+// for (m <- specialOverrides(specializedClass)) specializedClass.info.decls.enter(m)
val mbrs = new mutable.ListBuffer[Tree]
var hasSpecializedFields = false
- for (m <- cls.info.decls
+ for (m <- sClass.info.decls
if m.hasFlag(SPECIALIZED)
&& (m.sourceFile ne null)
- && satisfiable(typeEnv(m), !cls.hasFlag(SPECIALIZED))) {
+ && satisfiable(typeEnv(m), !sClass.hasFlag(SPECIALIZED))) {
log("creating tree for " + m.fullName)
if (m.isMethod) {
if (info(m).target.hasAccessorFlag) hasSpecializedFields = true
@@ -1609,16 +1595,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val origParamss = parameters(info(m).target)
val vparams = (
map2(m.info.paramTypes, origParamss(0))((tp, sym) =>
- m.newValue(sym.pos, specializedName(sym, typeEnv(cls)))
- .setInfo(tp)
- .setFlag(sym.flags)
+ m.newValue(specializedName(sym, typeEnv(sClass)), sym.pos, sym.flags) setInfo tp
)
)
// param accessors for private members (the others are inherited from the generic class)
if (m.isPrimaryConstructor) {
- for (param <- vparams ; if cls.info.nonPrivateMember(param.name) == NoSymbol) {
- val acc = param.cloneSymbol(cls).setFlag(PARAMACCESSOR | PRIVATE)
- cls.info.decls.enter(acc)
+ for (param <- vparams ; if sClass.info.nonPrivateMember(param.name) == NoSymbol) {
+ val acc = param.cloneSymbol(sClass, param.flags | PARAMACCESSOR | PRIVATE)
+ sClass.info.decls.enter(acc)
mbrs += ValDef(acc, EmptyTree).setType(NoType).setPos(m.pos)
}
}
@@ -1638,10 +1622,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
}
if (hasSpecializedFields) {
- val isSpecializedInstance = cls.hasFlag(SPECIALIZED) || cls.info.parents.exists(_.typeSymbol.hasFlag(SPECIALIZED))
- val sym = cls.newMethod(nme.SPECIALIZED_INSTANCE, cls.pos)
- .setInfo(MethodType(Nil, BooleanClass.tpe))
- cls.info.decls.enter(sym)
+ val isSpecializedInstance = sClass :: sClass.parentSymbols exists (_ hasFlag SPECIALIZED)
+ val sym = sClass.newMethod(nme.SPECIALIZED_INSTANCE, sClass.pos) setInfoAndEnter MethodType(Nil, BooleanClass.tpe)
+
mbrs += atPos(sym.pos) {
DefDef(sym, Literal(Constant(isSpecializedInstance)).setType(BooleanClass.tpe)).setType(NoType)
}
@@ -1716,9 +1699,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
atPos(pos) { (receiver /: argss) (Apply) }
}
- /** Concrete methods that use a specialized type, or override such methods. */
- private val concreteSpecMethods = new mutable.HashSet[Symbol]()
-
/** Add method m to the set of symbols for which we need an implementation tree
* in the tree transformer.
*
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index e2cd0a8402..1655ad09c4 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -128,7 +128,7 @@ abstract class TailCalls extends Transform {
* the label field.
*/
this.label = {
- val label = method.newLabel(method.pos, newTermName("_" + method.name))
+ val label = method.newLabel(newTermName("_" + method.name), method.pos)
val thisParam = method.newSyntheticValueParam(currentClass.typeOfThis)
label setInfo MethodType(thisParam :: method.tpe.params, method.tpe.finalResultType)
}
@@ -144,7 +144,7 @@ abstract class TailCalls extends Transform {
def isTransformed = isEligible && accessed
def tailrecFailure() = unit.error(failPos, "could not optimize @tailrec annotated " + method + ": " + failReason)
- def newThis(pos: Position) = method.newValue(pos, nme.THIS) setInfo currentClass.typeOfThis setFlag SYNTHETIC
+ def newThis(pos: Position) = method.newValue(nme.THIS, pos, SYNTHETIC) setInfo currentClass.typeOfThis
override def toString(): String = (
"" + method.name + " tparams: " + tparams + " tailPos: " + tailPos +
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index adb408f7e4..56d9658377 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -133,11 +133,9 @@ abstract class UnCurry extends InfoTransform
/** Return non-local return key for given method */
private def nonLocalReturnKey(meth: Symbol) =
- nonLocalReturnKeys.getOrElseUpdate(meth, {
- meth.newValue(meth.pos, unit.freshTermName("nonLocalReturnKey"))
- .setFlag (SYNTHETIC)
- .setInfo (ObjectClass.tpe)
- })
+ nonLocalReturnKeys.getOrElseUpdate(meth,
+ meth.newValue(unit.freshTermName("nonLocalReturnKey"), meth.pos, SYNTHETIC) setInfo ObjectClass.tpe
+ )
/** Generate a non-local return throw with given return expression from given method.
* I.e. for the method's non-local return key, generate:
@@ -170,7 +168,7 @@ abstract class UnCurry extends InfoTransform
private def nonLocalReturnTry(body: Tree, key: Symbol, meth: Symbol) = {
localTyper.typed {
val extpe = nonLocalReturnExceptionType(meth.tpe.finalResultType)
- val ex = meth.newValue(body.pos, nme.ex) setInfo extpe
+ val ex = meth.newValue(nme.ex, body.pos) setInfo extpe
val pat = Bind(ex,
Typed(Ident(nme.WILDCARD),
AppliedTypeTree(Ident(NonLocalReturnControlClass),
@@ -255,40 +253,42 @@ abstract class UnCurry extends InfoTransform
if (fun1 ne fun) fun1
else {
val (formals, restpe) = (targs.init, targs.last)
- val anonClass = owner newAnonymousFunctionClass fun.pos setFlag (FINAL | SYNTHETIC | inConstructorFlag)
+ val anonClass = owner.newAnonymousFunctionClass(fun.pos, inConstructorFlag)
def parents =
if (isFunctionType(fun.tpe)) List(abstractFunctionForFunctionType(fun.tpe), SerializableClass.tpe)
else if (isPartial) List(appliedType(AbstractPartialFunctionClass.typeConstructor, targs), SerializableClass.tpe)
else List(ObjectClass.tpe, fun.tpe, SerializableClass.tpe)
anonClass setInfo ClassInfoType(parents, new Scope, anonClass)
- val applyMethod = anonClass.newMethod(fun.pos, nme.apply) setFlag FINAL
- applyMethod setInfo MethodType(applyMethod newSyntheticValueParams formals, restpe)
- anonClass.info.decls enter applyMethod
- anonClass.addAnnotation(serialVersionUIDAnnotation)
+ val applyMethod = anonClass.newMethod(nme.apply, fun.pos, FINAL)
+ applyMethod setInfoAndEnter MethodType(applyMethod newSyntheticValueParams formals, restpe)
+ anonClass addAnnotation serialVersionUIDAnnotation
fun.vparams foreach (_.symbol.owner = applyMethod)
- new ChangeOwnerTraverser(fun.symbol, applyMethod) traverse fun.body
+ fun.body.changeOwner(fun.symbol -> applyMethod)
def missingCaseCall(scrutinee: Tree): Tree = Apply(Select(This(anonClass), nme.missingCase), List(scrutinee))
def applyMethodDef() = {
- val body =
+ val body = localTyper.typedPos(fun.pos) {
if (isPartial) gen.mkUncheckedMatch(gen.withDefaultCase(fun.body, missingCaseCall))
else fun.body
- DefDef(Modifiers(FINAL), nme.apply, Nil, List(fun.vparams), TypeTree(restpe), body) setSymbol applyMethod
+ }
+ // Have to repack the type to avoid mismatches when existentials
+ // appear in the result - see SI-4869.
+ val applyResultType = localTyper.packedType(body, applyMethod)
+ DefDef(Modifiers(FINAL), nme.apply, Nil, List(fun.vparams), TypeTree(applyResultType), body) setSymbol applyMethod
}
def isDefinedAtMethodDef() = {
val isDefinedAtName = {
if (anonClass.info.member(nme._isDefinedAt) != NoSymbol) nme._isDefinedAt
else nme.isDefinedAt
}
- val m = anonClass.newMethod(fun.pos, isDefinedAtName) setFlag FINAL
- m setInfo MethodType(m newSyntheticValueParams formals, BooleanClass.tpe)
- anonClass.info.decls enter m
- val vparam = fun.vparams.head.symbol
- val idparam = m.paramss.head.head
- val substParam = new TreeSymSubstituter(List(vparam), List(idparam))
+ val m = anonClass.newMethod(isDefinedAtName, fun.pos, FINAL)
+ val params = m newSyntheticValueParams formals
+ m setInfoAndEnter MethodType(params, BooleanClass.tpe)
+
+ val substParam = new TreeSymSubstituter(fun.vparams map (_.symbol), params)
def substTree[T <: Tree](t: T): T = substParam(resetLocalAttrs(t))
// waiting here until we can mix case classes and extractors reliably (i.e., when virtpatmat becomes the default)
@@ -516,9 +516,9 @@ abstract class UnCurry extends InfoTransform
*/
def liftTree(tree: Tree) = {
debuglog("lifting tree at: " + (tree.pos))
- val sym = currentOwner.newMethod(tree.pos, unit.freshTermName("liftedTree"))
+ val sym = currentOwner.newMethod(unit.freshTermName("liftedTree"), tree.pos)
sym.setInfo(MethodType(List(), tree.tpe))
- new ChangeOwnerTraverser(currentOwner, sym).traverse(tree)
+ tree.changeOwner(currentOwner -> sym)
localTyper.typedPos(tree.pos)(Block(
List(DefDef(sym, List(Nil), tree)),
Apply(Ident(sym), Nil)
@@ -772,7 +772,7 @@ abstract class UnCurry extends InfoTransform
}
val forwresult = dd.symbol.tpe.finalResultType
val forwformsyms = map2(forwformals, flatparams)((tp, oldparam) =>
- currentClass.newValueParameter(oldparam.symbol.pos, oldparam.name).setInfo(tp)
+ currentClass.newValueParameter(oldparam.name, oldparam.symbol.pos).setInfo(tp)
)
def mono = MethodType(forwformsyms, forwresult)
val forwtype = dd.symbol.tpe match {
@@ -781,11 +781,7 @@ abstract class UnCurry extends InfoTransform
}
// create the symbol
- val forwsym = (
- currentClass.newMethod(dd.pos, dd.name)
- . setFlag (VARARGS | SYNTHETIC | flatdd.symbol.flags)
- . setInfo (forwtype)
- )
+ val forwsym = currentClass.newMethod(dd.name, dd.pos, VARARGS | SYNTHETIC | flatdd.symbol.flags) setInfo forwtype
// create the tree
val forwtree = theTyper.typedPos(dd.pos) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 1d9eb9c292..faff4ccab2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -42,11 +42,11 @@ trait Contexts { self: Analyzer =>
*
* - if option `-Yno-imports` is given, nothing is imported
* - if the unit is java defined, only `java.lang` is imported
- * - if option `-Yno-predef` is given, if the unit has an import of Predef
- * among its leading imports, or if the unit is [[scala.ScalaObject]]
+ * - if option `-Yno-predef` is given, if the unit body has an import of Predef
+ * among its leading imports, or if the tree is [[scala.ScalaObject]]
* or [[scala.Predef]], `Predef` is not imported.
*/
- protected def rootImports(unit: CompilationUnit, tree: Tree): List[Symbol] = {
+ protected def rootImports(unit: CompilationUnit): List[Symbol] = {
import definitions._
assert(isDefinitionsInitialized, "definitions uninitialized")
@@ -56,23 +56,15 @@ trait Contexts { self: Analyzer =>
else List(JavaLangPackage, ScalaPackage, PredefModule)
}
- def rootContext(unit: CompilationUnit): Context =
- rootContext(unit, EmptyTree, false)
-
+ def rootContext(unit: CompilationUnit): Context = rootContext(unit, EmptyTree, false)
+ def rootContext(unit: CompilationUnit, tree: Tree): Context = rootContext(unit, tree, false)
def rootContext(unit: CompilationUnit, tree: Tree, erasedTypes: Boolean): Context = {
import definitions._
var sc = startContext
- def addImport(pkg: Symbol) {
- assert(pkg ne null)
- val qual = gen.mkAttributedStableRef(pkg)
- sc = sc.makeNewImport(
- Import(qual, List(ImportSelector(nme.WILDCARD, -1, null, -1)))
- .setSymbol(NoSymbol.newImport(NoPosition).setFlag(SYNTHETIC).setInfo(ImportType(qual)))
- .setType(NoType))
+ for (sym <- rootImports(unit)) {
+ sc = sc.makeNewImport(sym)
sc.depth += 1
}
- for (imp <- rootImports(unit, tree))
- addImport(imp)
val c = sc.make(unit, tree, sc.owner, sc.scope, sc.imports)
c.reportAmbiguousErrors = !erasedTypes
c.reportGeneralErrors = !erasedTypes
@@ -130,6 +122,10 @@ trait Contexts { self: Analyzer =>
var typingIndentLevel: Int = 0
def typingIndent = " " * typingIndentLevel
+ def enclClassOrMethod: Context =
+ if ((owner eq NoSymbol) || (owner.isClass) || (owner.isMethod)) this
+ else outer.enclClassOrMethod
+
def undetparamsString =
if (undetparams.isEmpty) ""
else undetparams.mkString("undetparams=", ", ", "")
@@ -207,6 +203,9 @@ trait Contexts { self: Analyzer =>
c.implicitsEnabled = true
c
}
+
+ def makeNewImport(sym: Symbol): Context =
+ makeNewImport(gen.mkWildcardImport(sym))
def makeNewImport(imp: Import): Context =
make(unit, imp, owner, scope, new ImportInfo(imp, depth) :: imports)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 3b90eaeed7..e14f0bcd87 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -45,8 +45,9 @@ trait Implicits {
* @return A search result
*/
def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context): SearchResult = {
- printInference("[inferImplicit%s] pt = %s".format(
- if (isView) " view" else "", pt)
+ printInference("[infer %s] %s with pt=%s in %s".format(
+ if (isView) "view" else "implicit",
+ tree, pt, context.owner.enclClass)
)
printTyping(
ptBlock("infer implicit" + (if (isView) " view" else ""),
@@ -65,7 +66,7 @@ trait Implicits {
printTyping("typing implicit: %s %s".format(tree, context.undetparamsString))
val result = new ImplicitSearch(tree, pt, isView, context.makeImplicit(reportAmbiguous)).bestImplicit
- printInference("[inferImplicit] result: " + result)
+ printInference("[infer implicit] inferred " + result)
context.undetparams = context.undetparams filterNot result.subst.from.contains
stopTimer(implicitNanos, start)
@@ -93,21 +94,13 @@ trait Implicits {
private val ManifestSymbols = Set(PartialManifestClass, FullManifestClass, OptManifestClass)
- /** Map all type params in given list to WildcardType
- * @param tparams The list of type parameters to map
- * @param tp The type in which to do the mapping
- */
- private def tparamsToWildcards(tparams: List[Symbol], tp: Type) =
- if (tparams.isEmpty) tp
- else tp.instantiateTypeParams(tparams, tparams map (_ => WildcardType))
-
/* Map a polytype to one in which all type parameters and argument-dependent types are replaced by wildcards.
* Consider `implicit def b(implicit x: A): x.T = error("")`. We need to approximate DebruijnIndex types
* when checking whether `b` is a valid implicit, as we haven't even searched a value for the implicit arg `x`,
* so we have to approximate (otherwise it is excluded a priori).
*/
private def depoly(tp: Type): Type = tp match {
- case PolyType(tparams, restpe) => tparamsToWildcards(tparams, ApproximateDependentMap(restpe))
+ case PolyType(tparams, restpe) => deriveTypeWithWildcards(tparams)(ApproximateDependentMap(restpe))
case _ => ApproximateDependentMap(tp)
}
@@ -191,12 +184,10 @@ trait Implicits {
*/
def memberWildcardType(name: Name, tp: Type) = {
val result = refinedType(List(WildcardType), NoSymbol)
- var psym = name match {
- case x: TypeName => result.typeSymbol.newAbstractType(NoPosition, x)
- case x: TermName => result.typeSymbol.newValue(NoPosition, x)
+ name match {
+ case x: TermName => result.typeSymbol.newValue(x) setInfoAndEnter tp
+ case x: TypeName => result.typeSymbol.newAbstractType(x) setInfoAndEnter tp
}
- psym setInfo tp
- result.decls enter psym
result
}
@@ -395,7 +386,6 @@ trait Implicits {
* @pre `info.tpe` does not contain an error
*/
private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean): SearchResult = {
- printInference("[typedImplicit] " + info)
(context.openImplicits find { case (tp, sym) => sym == tree.symbol && dominates(pt, tp)}) match {
case Some(pending) =>
// println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG
@@ -614,16 +604,15 @@ trait Implicits {
info.sym.fullLocationString, itree1.symbol.fullLocationString))
else {
val tvars = undetParams map freshVar
-
- if (matchesPt(itree2.tpe, pt.instantiateTypeParams(undetParams, tvars), undetParams)) {
- printInference(
- ptBlock("matchesPt",
- "itree1" -> itree1,
- "tvars" -> tvars,
- "undetParams" -> undetParams
- )
- )
-
+ def ptInstantiated = pt.instantiateTypeParams(undetParams, tvars)
+
+ printInference("[search] considering %s (pt contains %s) trying %s against pt=%s".format(
+ if (undetParams.isEmpty) "no tparams" else undetParams.map(_.name).mkString(", "),
+ typeVarsInType(ptInstantiated) filterNot (_.isGround) match { case Nil => "no tvars" ; case tvs => tvs.mkString(", ") },
+ itree2.tpe, pt
+ ))
+
+ if (matchesPt(itree2.tpe, ptInstantiated, undetParams)) {
if (tvars.nonEmpty)
printTyping(ptLine("" + info.sym, "tvars" -> tvars, "tvars.constr" -> tvars.map(_.constr)))
@@ -637,6 +626,7 @@ trait Implicits {
// we must be conservative in leaving type params in undetparams
// prototype == WildcardType: want to remove all inferred Nothings
val AdjustedTypeArgs(okParams, okArgs) = adjustTypeArgs(undetParams, tvars, targs)
+
val subst: TreeTypeSubstituter =
if (okParams.isEmpty) EmptyTreeTypeSubstituter
else {
@@ -663,11 +653,10 @@ trait Implicits {
}
val result = new SearchResult(itree2, subst)
incCounter(foundImplicits)
- printInference("[typedImplicit1] SearchResult: " + result)
+ printInference("[success] found %s for pt %s".format(result, ptInstantiated))
result
}
- else fail("incompatible: %s does not match expected type %s".format(
- itree2.tpe, pt.instantiateTypeParams(undetParams, tvars)))
+ else fail("incompatible: %s does not match expected type %s".format(itree2.tpe, ptInstantiated))
}
}
catch {
@@ -786,16 +775,11 @@ trait Implicits {
// most frequent one first
matches sortBy (x => if (isView) -x.useCountView else -x.useCountArg)
}
- def eligibleString = {
- val args = List(
- "search" -> pt,
- "target" -> tree,
- "isView" -> isView
- ) ++ eligible.map("eligible" -> _)
-
- ptBlock("Implicit search in " + context, args: _*)
- }
- printInference(eligibleString)
+ if (eligible.nonEmpty)
+ printInference("[search%s] %s with pt=%s in %s, eligible:\n %s".format(
+ if (isView) " view" else "",
+ tree, pt, context.owner.enclClass, eligible.mkString("\n "))
+ )
/** Faster implicit search. Overall idea:
* - prune aggressively
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 295b66b17f..9db291a306 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -138,6 +138,9 @@ trait Infer {
def solvedTypes(tvars: List[TypeVar], tparams: List[Symbol],
variances: List[Int], upper: Boolean, depth: Int): List[Type] = {
+ if (tvars.nonEmpty)
+ printInference("[solve types] solving for " + tparams.map(_.name).mkString(", ") + " in " + tvars.mkString(", "))
+
if (!solve(tvars, tparams, variances, upper, depth)) {
// no panic, it's good enough to just guess a solution, we'll find out
// later whether it works. *ZAP* @M danger, Will Robinson! this means
@@ -363,10 +366,7 @@ trait Infer {
def makeFullyDefined(tp: Type): Type = {
val tparams = new ListBuffer[Symbol]
def addTypeParam(bounds: TypeBounds): Type = {
- val tparam =
- context.owner.newAbstractType(context.tree.pos.focus, newTypeName("_"+tparams.size))
- .setFlag(EXISTENTIAL)
- .setInfo(bounds)
+ val tparam = context.owner.newExistential(newTypeName("_"+tparams.size), context.tree.pos.focus) setInfo bounds
tparams += tparam
tparam.tpe
}
@@ -553,18 +553,6 @@ trait Infer {
throw new NoInstance("parameter lists differ in length")
val restpeInst = restpe.instantiateTypeParams(tparams, tvars)
- printInference(
- ptBlock("methTypeArgs",
- "tparams" -> tparams,
- "formals" -> formals,
- "restpe" -> restpe,
- "restpeInst" -> restpeInst,
- "argtpes" -> argtpes,
- "pt" -> pt,
- "tvars" -> tvars,
- "constraints" -> tvars.map(_.constr)
- )
- )
// first check if typevars can be fully defined from the expected type.
// The return value isn't used so I'm making it obvious that this side
@@ -602,17 +590,7 @@ trait Infer {
tvars, tparams, tparams map varianceInTypes(formals),
false, lubDepth(formals) max lubDepth(argtpes)
)
- val result = adjustTypeArgs(tparams, tvars, targs, restpe)
-
- printInference(
- ptBlock("methTypeArgs result",
- "tvars" -> tvars,
- "constraints" -> tvars.map(_.constr),
- "targs" -> targs,
- "adjusted type args" -> result
- )
- )
- result
+ adjustTypeArgs(tparams, tvars, targs, restpe)
}
private[typechecker] def followApply(tp: Type): Type = tp match {
@@ -1097,15 +1075,6 @@ trait Infer {
def inferMethodInstance(fn: Tree, undetparams: List[Symbol],
args: List[Tree], pt0: Type): List[Symbol] = fn.tpe match {
case MethodType(params0, _) =>
- printInference(
- ptBlock("inferMethodInstance",
- "fn" -> fn,
- "undetparams" -> undetparams,
- "args" -> args,
- "pt0" -> pt0
- )
- )
-
try {
val pt = if (pt0.typeSymbol == UnitClass) WildcardType else pt0
val formals = formalTypes(params0 map (_.tpe), args.length)
@@ -1115,11 +1084,19 @@ trait Infer {
val AdjustedTypeArgs.AllArgsAndUndets(okparams, okargs, allargs, leftUndet) =
methTypeArgs(undetparams, formals, restpe, argtpes, pt)
+ printInference("[infer method] solving for %s in %s based on (%s)%s (%s)".format(
+ undetparams.map(_.name).mkString(", "),
+ fn.tpe,
+ argtpes.mkString(", "),
+ restpe,
+ (okparams map (_.name), okargs).zipped.map(_ + "=" + _).mkString("solved: ", ", ", "")
+ ))
+
checkBounds(fn.pos, NoPrefix, NoSymbol, undetparams, allargs, "inferred ")
val treeSubst = new TreeTypeSubstituter(okparams, okargs)
treeSubst traverseTrees fn :: args
- val result = leftUndet match {
+ leftUndet match {
case Nil => Nil
case xs =>
// #3890
@@ -1129,10 +1106,6 @@ trait Infer {
xs1
}
- if (result.nonEmpty)
- printInference("inferMethodInstance, still undetermined: " + result)
-
- result
}
catch ifNoInstance { msg =>
errorTree(fn, "no type parameters for " +
@@ -1143,19 +1116,7 @@ trait Infer {
}
}
- /** Type with all top-level occurrences of abstract types replaced by their bounds */
- def widen(tp: Type): Type = tp match { // @M don't normalize here (compiler loops on pos/bug1090.scala )
- case TypeRef(_, sym, _) if sym.isAbstractType =>
- widen(tp.bounds.hi)
- case TypeRef(_, sym, _) if sym.isAliasType =>
- widen(tp.normalize)
- case rtp @ RefinedType(parents, decls) =>
- copyRefinedType(rtp, parents mapConserve widen, decls)
- case AnnotatedType(_, underlying, _) =>
- widen(underlying)
- case _ =>
- tp
- }
+ def widen(tp: Type): Type = abstractTypesToBounds(tp)
/** Substitute free type variables <code>undetparams</code> of type constructor
* <code>tree</code> in pattern, given prototype <code>pt</code>.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index b9264aae55..7f9e56a926 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -2,6 +2,8 @@ package scala.tools.nsc
package typechecker
import symtab.Flags._
+import scala.tools.nsc.util._
+import scala.reflect.ReflectionUtils
trait Macros { self: Analyzer =>
import global._
@@ -13,6 +15,20 @@ trait Macros { self: Analyzer =>
owner.info.decl(nme.macroMethodName(mac.name))
}
+ def macroArgs(tree: Tree): (List[List[Tree]]) = tree match {
+ case Apply(fn, args) =>
+ macroArgs(fn) :+ args
+ case TypeApply(fn, args) =>
+ macroArgs(fn) :+ args
+ case Select(qual, name) if !isStaticMacro(tree.symbol) =>
+ List(List(qual))
+ case _ =>
+ List(List())
+ }
+
+ private def isStaticMacro(mac: Symbol): Boolean =
+ mac.owner.isModuleClass
+
/**
* The definition of the method implementing a macro. Example:
* Say we have in a class C
@@ -33,25 +49,32 @@ trait Macros { self: Analyzer =>
*/
def macroMethDef(mdef: DefDef): Tree = {
def paramDef(name: Name, tpt: Tree) = ValDef(Modifiers(PARAM), name, tpt, EmptyTree)
- val universeType = TypeTree(ReflectApiUniverse.tpe)
- val globParamSec = List(paramDef(nme.glob, universeType))
- def globSelect(name: Name) = Select(Ident(nme.glob), name)
+ val contextType = TypeTree(ReflectMacroContext.tpe)
+ val globParamSec = List(paramDef(nme.context, contextType))
+ def globSelect(name: Name) = Select(Ident(nme.context), name)
def globTree = globSelect(newTypeName("Tree"))
def globType = globSelect(newTypeName("Type"))
- val thisParamSec = if (mdef.symbol.owner.isModuleClass) List() else List(paramDef(newTermName("_this"), globTree))
+ val thisParamSec = if (isStaticMacro(mdef.symbol)) List() else List(paramDef(newTermName("_this"), globTree))
def tparamInMacro(tdef: TypeDef) = paramDef(tdef.name.toTermName, globType)
- def vparamInMacro(vdef: ValDef): ValDef = paramDef(vdef.name, globTree)
+ def vparamInMacro(vdef: ValDef): ValDef = paramDef(vdef.name, vdef.tpt match {
+ case tpt @ AppliedTypeTree(hk, _) if treeInfo.isRepeatedParamType(tpt) => AppliedTypeTree(hk, List(globTree))
+ case _ => globTree
+ })
def wrapImplicit(tree: Tree) = atPos(tree.pos) {
- Block(List(ValDef(Modifiers(IMPLICIT), newTermName("$" + nme.glob), universeType, Ident(nme.glob))), tree)
+ // implicit hasn't proven useful so far, so I'm disabling it
+ //val implicitDecl = ValDef(Modifiers(IMPLICIT), nme.contextImplicit, SingletonTypeTree(Ident(nme.context)), Ident(nme.context))
+ val importGlob = Import(Ident(nme.context), List(ImportSelector(nme.WILDCARD, -1, null, -1)))
+ Block(List(importGlob), tree)
}
+ var formals = (mdef.vparamss map (_ map vparamInMacro))
+ if (mdef.tparams.nonEmpty) formals = (mdef.tparams map tparamInMacro) :: formals
atPos(mdef.pos) {
new DefDef( // can't call DefDef here; need to find out why
- mods = mdef.mods &~ MACRO,
+ mods = mdef.mods &~ MACRO &~ OVERRIDE,
name = nme.macroMethodName(mdef.name),
tparams = List(),
- vparamss = globParamSec :: thisParamSec :: (mdef.tparams map tparamInMacro) ::
- (mdef.vparamss map (_ map vparamInMacro)),
+ vparamss = globParamSec :: thisParamSec :: formals,
tpt = globTree,
wrapImplicit(mdef.rhs))
}
@@ -59,11 +82,98 @@ trait Macros { self: Analyzer =>
def addMacroMethods(templ: Template, namer: Namer): Unit = {
for (ddef @ DefDef(mods, _, _, _, _, _) <- templ.body if mods hasFlag MACRO) {
- val sym = namer.enterSyntheticSym(util.trace("macro def: ")(macroMethDef(ddef)))
- println("added to "+namer.context.owner.enclClass+": "+sym)
+ val trace = scala.tools.nsc.util.trace when settings.debug.value
+ val sym = namer.enterSyntheticSym(trace("macro def: ")(macroMethDef(ddef)))
+ trace("added to "+namer.context.owner.enclClass+": ")(sym)
}
}
- def macroExpand(tree: Tree): Tree = ???
+ lazy val mirror = new scala.reflect.runtime.Mirror {
+ lazy val libraryClassLoader = {
+ val classpath = global.classPath.asURLs
+ ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
+ }
+
+ override def defaultReflectiveClassLoader() = libraryClassLoader
+ }
+
+ class MacroExpandError(val msg: String) extends Exception(msg)
-} \ No newline at end of file
+ /** Return optionally address of companion object and implementation method symbol
+ * of given macro; or None if implementation classfile cannot be loaded or does
+ * not contain the macro implementation.
+ */
+ def macroImpl(mac: Symbol): Option[(AnyRef, mirror.Symbol)] = {
+ try {
+ val mmeth = macroMeth(mac)
+ if (mmeth == NoSymbol) None
+ else {
+ val receiverClass: mirror.Symbol = mirror.classWithName(mmeth.owner.fullName)
+ val receiverObj = receiverClass.companionModule
+ if (receiverObj == NoSymbol) None
+ else {
+ val receiver = mirror.getCompanionObject(receiverClass)
+ val rmeth = receiverObj.info.member(mirror.newTermName(mmeth.name.toString))
+ Some((receiver, rmeth))
+ }
+ }
+ } catch {
+ case ex: ClassNotFoundException =>
+ None
+ }
+ }
+
+ /** Return result of macro expansion.
+ * Or, if that fails, and the macro overrides a method return
+ * tree that calls this method instead of the macro.
+ */
+ def macroExpand(tree: Tree): Any = {
+ val macroDef = tree.symbol
+ macroImpl(macroDef) match {
+ case Some((receiver, rmeth)) =>
+ val argss = List(global) :: macroArgs(tree)
+ val paramss = macroMeth(macroDef).paramss
+ val rawArgss = for ((as, ps) <- argss zip paramss) yield {
+ if (isVarArgsList(ps)) as.take(ps.length - 1) :+ as.drop(ps.length - 1)
+ else as
+ }
+ val rawArgs: Seq[Any] = rawArgss.flatten
+ try {
+ mirror.invoke(receiver, rmeth, rawArgs: _*)
+ } catch {
+ case ex =>
+ val realex = ReflectionUtils.unwrapThrowable(ex)
+ val stacktrace = new java.io.StringWriter()
+ realex.printStackTrace(new java.io.PrintWriter(stacktrace))
+ val msg = System.getProperty("line.separator") + stacktrace
+ throw new MacroExpandError("exception during macro expansion: " + msg)
+ }
+ case None =>
+ val trace = scala.tools.nsc.util.trace when settings.debug.value
+ def notFound() = throw new MacroExpandError("macro implementation not found: " + macroDef.name)
+ def fallBackToOverridden(tree: Tree): Tree = {
+ tree match {
+ case Select(qual, name) if (macroDef.isMacro) =>
+ macroDef.allOverriddenSymbols match {
+ case first :: others =>
+ return Select(qual, name) setPos tree.pos setSymbol first
+ case _ =>
+ trace("macro is not overridden: ")(tree)
+ notFound()
+ }
+ case Apply(fn, args) =>
+ Apply(fallBackToOverridden(fn), args) setPos tree.pos
+ case TypeApply(fn, args) =>
+ TypeApply(fallBackToOverridden(fn), args) setPos tree.pos
+ case _ =>
+ trace("unexpected tree in fallback: ")(tree)
+ notFound()
+ }
+ }
+ val tree1 = fallBackToOverridden(tree)
+ trace("falling back to ")(tree1)
+ currentRun.macroExpansionFailed = true
+ tree1
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 62393befd2..29dffd99d6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -125,11 +125,7 @@ trait MethodSynthesis {
def keepClean = false // whether annotations whose definitions are not meta-annotated should be kept.
def validate() { }
def createAndEnterSymbol(): Symbol = {
- val sym = (
- owner.newMethod(tree.pos.focus, name)
- setFlag tree.mods.flags & flagsMask
- setFlag flagsExtra
- )
+ val sym = owner.newMethod(name, tree.pos.focus, (tree.mods.flags & flagsMask) | flagsExtra)
setPrivateWithin(tree, sym)
enterInScope(sym)
sym setInfo completer(sym)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 200191fa13..e04d89047b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -293,23 +293,22 @@ trait Namers extends MethodSynthesis {
private def createMemberSymbol(tree: MemberDef, name: Name, mask: Long): Symbol = {
val pos = tree.pos
val isParameter = tree.mods.isParameter
- val sym = tree match {
- case TypeDef(_, _, _, _) if isParameter => owner.newTypeParameter(pos, name.toTypeName)
- case TypeDef(_, _, _, _) => owner.newAliasType(pos, name.toTypeName)
- case DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => owner.newConstructor(pos)
- case DefDef(_, _, _, _, _, _) => owner.newMethod(pos, name.toTermName)
- case ClassDef(_, _, _, _) => owner.newClass(pos, name.toTypeName)
- case ModuleDef(_, _, _) => owner.newModule(pos, name)
- case ValDef(_, _, _, _) if isParameter => owner.newValueParameter(pos, name)
+ val flags = tree.mods.flags & mask
+
+ tree match {
+ case TypeDef(_, _, _, _) if isParameter => owner.newTypeParameter(name.toTypeName, pos, flags)
+ case TypeDef(_, _, _, _) => owner.newTypeSymbol(name.toTypeName, pos, flags)
+ case DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => owner.newConstructor(pos, flags)
+ case DefDef(_, _, _, _, _, _) => owner.newMethod(name.toTermName, pos, flags)
+ case ClassDef(_, _, _, _) => owner.newClassSymbol(name.toTypeName, pos, flags)
+ case ModuleDef(_, _, _) => owner.newModule(name, pos, flags)
+ case ValDef(_, _, _, _) if isParameter => owner.newValueParameter(name, pos, flags)
case PackageDef(pid, _) => createPackageSymbol(pos, pid)
- case ValDef(_, _, _, _) => owner.newValue(pos, name)
+ case ValDef(_, _, _, _) => owner.newValue(name, pos, flags)
}
- sym setFlag (tree.mods.flags & mask)
}
- private def createFieldSymbol(tree: ValDef): TermSymbol = (
- owner.newValue(tree.pos, nme.getterToLocal(tree.name))
- setFlag tree.mods.flags & FieldFlags | PrivateLocal
- )
+ private def createFieldSymbol(tree: ValDef): TermSymbol =
+ owner.newValue(nme.getterToLocal(tree.name), tree.pos, tree.mods.flags & FieldFlags | PrivateLocal)
private def createImportSymbol(tree: Tree) =
NoSymbol.newImport(tree.pos) setInfo completerOf(tree)
@@ -325,7 +324,7 @@ trait Namers extends MethodSynthesis {
if (existing.isPackage && pkgOwner == existing.owner)
existing
else {
- val pkg = pkgOwner.newPackage(pos, pid.name.toTermName)
+ val pkg = pkgOwner.newPackage(pid.name.toTermName, pos)
val pkgClass = pkg.moduleClass
val pkgClassInfo = new PackageClassInfoType(newPackageScope(pkgClass), pkgClass)
@@ -579,7 +578,7 @@ trait Namers extends MethodSynthesis {
// via "x$lzy" as can be seen in test #3927.
val sym = (
if (owner.isClass) createFieldSymbol(tree)
- else owner.newValue(tree.pos, tree.name append nme.LAZY_LOCAL) setFlag tree.mods.flags resetFlag IMPLICIT
+ else owner.newValue(tree.name append nme.LAZY_LOCAL, tree.pos, tree.mods.flags & ~IMPLICIT)
)
enterValSymbol(tree, sym setFlag MUTABLE setLazyAccessor lazyAccessor)
}
@@ -843,10 +842,10 @@ trait Namers extends MethodSynthesis {
Namers.this.classOfModuleClass get clazz foreach { cdefRef =>
val cdef = cdefRef()
if (cdef.mods.isCase) addApplyUnapply(cdef, templateNamer)
- addMacroMethods(cdef.impl, templateNamer)
+ if (settings.Xmacros.value) addMacroMethods(cdef.impl, templateNamer)
classOfModuleClass -= clazz
}
- addMacroMethods(templ, templateNamer)
+ if (settings.Xmacros.value) addMacroMethods(templ, templateNamer)
}
// add the copy method to case classes; this needs to be done here, not in SyntheticMethods, because
@@ -1391,10 +1390,9 @@ trait Namers extends MethodSynthesis {
)
if (sym hasAnnotation NativeAttr)
sym resetFlag DEFERRED
- else if (!symbolAllowsDeferred && ownerRequiresConcrete) {
+ else if (!symbolAllowsDeferred && ownerRequiresConcrete)
fail("only classes can have declared but undefined members" + abstractVarMessage(sym))
- sym resetFlag DEFERRED
- }
+
checkWithDeferred(PRIVATE)
checkWithDeferred(FINAL)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index a8dfea02ec..79cb211215 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -154,10 +154,9 @@ trait NamesDefaults { self: Analyzer =>
// never used for constructor calls, they always have a stable qualifier
def blockWithQualifier(qual: Tree, selected: Name) = {
- val sym = blockTyper.context.owner.newValue(qual.pos, unit.freshTermName("qual$"))
- .setInfo(qual.tpe)
- blockTyper.context.scope.enter(sym)
- val vd = atPos(sym.pos)(ValDef(sym, qual).setType(NoType))
+ val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos) setInfo qual.tpe
+ blockTyper.context.scope enter sym
+ val vd = atPos(sym.pos)(ValDef(sym, qual) setType NoType)
var baseFunTransformed = atPos(baseFun.pos.makeTransparent) {
// don't use treeCopy: it would assign opaque position.
@@ -269,7 +268,7 @@ trait NamesDefaults { self: Analyzer =>
case _ =>
(seqType(arg.tpe), true)
} else (arg.tpe, false)
- val s = context.owner.newValue(arg.pos, unit.freshTermName("x$"))
+ val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos)
val valType = if (byName) functionType(List(), argTpe)
else if (repeated) argTpe
else argTpe
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index 440db4300c..ed185c27d6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -53,7 +53,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
import typeDebug.{ ptTree, ptBlock, ptLine }
def solveContextBound(contextBoundTp: Type): (Tree, Type) = {
- val solSym = NoSymbol.newTypeParameter(NoPosition, newTypeName("SolveImplicit$"))
+ val solSym = NoSymbol.newTypeParameter(newTypeName("SolveImplicit$"))
val param = solSym.setInfo(contextBoundTp.typeSymbol.typeParams(0).info.cloneInfo(solSym)) // TypeBounds(NothingClass.typeConstructor, baseTp)
val pt = appliedType(contextBoundTp, List(param.tpeHK))
val savedUndets = context.undetparams
@@ -1128,62 +1128,48 @@ defined class Foo */
// }
// }
- def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type): Option[Tree] = if (optimizingCodeGen) {
- def unfold(tms: List[TreeMaker], currLabel: Option[Symbol] = None, nextLabel: Option[Symbol] = None): List[CaseDef] = tms match {
- // constant
- case (EqualityTestTreeMaker(_, const@SwitchablePattern(), _)) :: (btm@BodyTreeMaker(body, _)) :: Nil => import CODE._
- @inline
- def substedBody = btm.substitution(body)
- val labelledBody = currLabel match {
- case None => substedBody // currLabel.isEmpty implies nextLabel.isEmpty
- case Some(myLabel) =>
- LabelDef(myLabel, Nil,
- nextLabel match {
- case None => substedBody
- case Some(next) => ID(next) APPLY ()
- }
- )
- }
- List(CaseDef(const, EmptyTree, labelledBody))
-
- // alternatives
- case AlternativesTreeMaker(_, altss, _) :: bodyTm :: Nil => // assert(currLabel.isEmpty && nextLabel.isEmpty)
- val labels = altss map { alts =>
- Some(freshSym(NoPosition, MethodType(Nil, pt), "$alt$") setFlag (METHOD | LABEL))
- }
-
- val caseDefs = (altss, labels, labels.tail :+ None).zipped.map { case (alts, currLabel, nextLabel) =>
- unfold(alts :+ bodyTm, currLabel, nextLabel)
- }
-
- if (caseDefs exists (_.isEmpty)) Nil
- else caseDefs.flatten
-
- case _ => Nil // failure
- }
+ def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type): Option[Tree] = if (!optimizingCodeGen) None else {
+ def sequence[T](xs: List[Option[T]]): Option[List[T]] =
+ if (xs exists (_.isEmpty)) None else Some(xs.flatten)
val caseDefs = cases map { makers =>
removeSubstOnly(makers) match {
// default case (don't move this to unfold, as it may only occur on the top level, not as an alternative -- well, except in degenerate matches)
case (btm@BodyTreeMaker(body, _)) :: Nil =>
- List(CaseDef(Ident(nme.WILDCARD), EmptyTree, btm.substitution(body)))
- case nonTrivialMakers =>
- unfold(nonTrivialMakers)
+ Some(CaseDef(Ident(nme.WILDCARD), EmptyTree, btm.substitution(body)))
+ // constant
+ case (EqualityTestTreeMaker(_, const@SwitchablePattern(), _)) :: (btm@BodyTreeMaker(body, _)) :: Nil => import CODE._
+ Some(CaseDef(const, EmptyTree, btm.substitution(body)))
+ // alternatives
+ case AlternativesTreeMaker(_, altss, _) :: (btm@BodyTreeMaker(body, _)) :: Nil => // assert(currLabel.isEmpty && nextLabel.isEmpty)
+ val caseConstants = altss map {
+ case EqualityTestTreeMaker(_, const@SwitchablePattern(), _) :: Nil =>
+ Some(const)
+ case _ =>
+ None
+ }
+
+ sequence(caseConstants) map { contants =>
+ val substedBody = btm.substitution(body)
+ CaseDef(Alternative(contants), EmptyTree, substedBody)
+ }
+ case _ =>
+ None //failure (can't translate pattern to a switch)
}
}
- if (caseDefs exists (_.isEmpty)) None
- else { import CODE._
+ sequence(caseDefs) map { caseDefs =>
+ import CODE._
val matcher = BLOCK(
VAL(scrutSym) === scrut, // TODO: type test for switchable type if patterns allow switch but the scrutinee doesn't
- Match(REF(scrutSym), caseDefs.flatten) // match on scrutSym, not scrut to avoid duplicating scrut
+ Match(REF(scrutSym), caseDefs) // match on scrutSym, not scrut to avoid duplicating scrut
)
// matcher filter (tree => tree.tpe == null) foreach println
// treeBrowser browse matcher
- Some(matcher) // set type to avoid recursion in typedMatch
+ matcher // set type to avoid recursion in typedMatch
}
- } else None
+ }
def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): List[List[TreeMaker]] =
doCSE(prevBinder, doDCE(prevBinder, cases, pt), pt)
@@ -1245,7 +1231,7 @@ defined class Foo */
}
t match {
case Function(_, _) if t.symbol == NoSymbol =>
- t.symbol = currentOwner.newValue(t.pos, nme.ANON_FUN_NAME).setFlag(SYNTHETIC).setInfo(NoType)
+ t.symbol = currentOwner.newAnonymousFunctionValue(t.pos)
// println("new symbol for "+ (t, t.symbol.ownerChain))
case Function(_, _) if (t.symbol.owner == NoSymbol) || (t.symbol.owner == origOwner) =>
// println("fundef: "+ (t, t.symbol.ownerChain, currentOwner.ownerChain))
@@ -1377,19 +1363,19 @@ defined class Foo */
@inline private def dontStore(tp: Type) = (tp.typeSymbol eq UnitClass) || (tp.typeSymbol eq NothingClass)
lazy val keepGoing = freshSym(NoPosition, BooleanClass.tpe, "keepGoing") setFlag MUTABLE
lazy val matchRes = freshSym(NoPosition, AnyClass.tpe, "matchRes") setFlag MUTABLE
- override def runOrElse(scrut: Tree, matcher: Tree, scrutTp: Type, resTp: Type, hasDefault: Boolean) = matcher match {
- case Function(List(x: ValDef), body) =>
- matchRes.info = if (resTp ne NoType) resTp.widen else AnyClass.tpe // we don't always know resTp, and it might be AnyVal, in which case we can't assign NULL
- if (dontStore(resTp)) matchRes resetFlag MUTABLE // don't assign to Unit-typed var's, in fact, make it a val -- conveniently also works around SI-5245
- BLOCK(
- VAL(zeroSym) === REF(NoneModule), // TODO: can we just get rid of explicitly emitted zero? don't know how to do that as a local rewrite...
- VAL(x.symbol) === scrut, // reuse the symbol of the function's argument to avoid creating a fresh one and substituting it for x.symbol in body -- the owner structure is repaired by fixerUpper
- VAL(matchRes) === mkZero(matchRes.info), // must cast to deal with GADT typing, hence the private mkZero above
- VAL(keepGoing) === TRUE,
- body,
- if(hasDefault) REF(matchRes)
- else (IF (REF(keepGoing)) THEN MATCHERROR(REF(x.symbol)) ELSE REF(matchRes))
- )
+ override def runOrElse(scrut: Tree, matcher: Tree, scrutTp: Type, resTp: Type, hasDefault: Boolean) = {
+ val Function(List(x: ValDef), body) = matcher
+ matchRes.info = if (resTp ne NoType) resTp.widen else AnyClass.tpe // we don't always know resTp, and it might be AnyVal, in which case we can't assign NULL
+ if (dontStore(resTp)) matchRes resetFlag MUTABLE // don't assign to Unit-typed var's, in fact, make it a val -- conveniently also works around SI-5245
+ BLOCK(
+ VAL(zeroSym) === REF(NoneModule), // TODO: can we just get rid of explicitly emitted zero? don't know how to do that as a local rewrite...
+ VAL(x.symbol) === scrut, // reuse the symbol of the function's argument to avoid creating a fresh one and substituting it for x.symbol in body -- the owner structure is repaired by fixerUpper
+ VAL(matchRes) === mkZero(matchRes.info), // must cast to deal with GADT typing, hence the private mkZero above
+ VAL(keepGoing) === TRUE,
+ body,
+ if(hasDefault) REF(matchRes)
+ else (IF (REF(keepGoing)) THEN MATCHERROR(REF(x.symbol)) ELSE REF(matchRes))
+ )
}
// only used to wrap the RHS of a body
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 8f9cd46611..112aa47114 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -171,8 +171,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
def varargBridge(member: Symbol, bridgetpe: Type): Tree = {
log("Generating varargs bridge for " + member.fullLocationString + " of type " + bridgetpe)
- val bridge = member.cloneSymbolImpl(clazz)
- .setPos(clazz.pos).setFlag(member.flags | VBRIDGE)
+ val bridge = member.cloneSymbolImpl(clazz, member.flags | VBRIDGE) setPos clazz.pos
bridge.setInfo(bridgetpe.cloneInfo(bridge))
clazz.info.decls enter bridge
@@ -332,21 +331,22 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
// return if we already checked this combination elsewhere
if (member.owner != clazz) {
- if ((member.owner isSubClass other.owner) && (member.isDeferred || !other.isDeferred)) {
+ def deferredCheck = member.isDeferred || !other.isDeferred
+ def subOther(s: Symbol) = s isSubClass other.owner
+ def subMember(s: Symbol) = s isSubClass member.owner
+
+ if (subOther(member.owner) && deferredCheck) {
//Console.println(infoString(member) + " shadows1 " + infoString(other) " in " + clazz);//DEBUG
- return;
+ return
+ }
+ if (clazz.parentSymbols exists (p => subOther(p) && subMember(p) && deferredCheck)) {
+ //Console.println(infoString(member) + " shadows2 " + infoString(other) + " in " + clazz);//DEBUG
+ return
+ }
+ if (clazz.parentSymbols forall (p => subOther(p) == subMember(p))) {
+ //Console.println(infoString(member) + " shadows " + infoString(other) + " in " + clazz);//DEBUG
+ return
}
- if (clazz.info.parents exists (parent =>
- (parent.typeSymbol isSubClass other.owner) && (parent.typeSymbol isSubClass member.owner) &&
- (member.isDeferred || !other.isDeferred))) {
- //Console.println(infoString(member) + " shadows2 " + infoString(other) + " in " + clazz);//DEBUG
- return;
- }
- if (clazz.info.parents forall (parent =>
- (parent.typeSymbol isSubClass other.owner) == (parent.typeSymbol isSubClass member.owner))) {
- //Console.println(infoString(member) + " shadows " + infoString(other) + " in " + clazz);//DEBUG
- return;
- }
}
/** Is the intersection between given two lists of overridden symbols empty?
@@ -444,6 +444,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
// check a type alias's RHS corresponds to its declaration
// this overlaps somewhat with validateVariance
if(member.isAliasType) {
+ // println("checkKindBounds" + ((List(member), List(memberTp.normalize), self, member.owner)))
val kindErrors = typer.infer.checkKindBounds(List(member), List(memberTp.normalize), self, member.owner)
if(!kindErrors.isEmpty)
@@ -672,9 +673,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
}
}
}
- val parents = bc.info.parents
- if (!parents.isEmpty && parents.head.typeSymbol.hasFlag(ABSTRACT))
- checkNoAbstractDecls(parents.head.typeSymbol)
+ if (bc.superClass hasFlag ABSTRACT)
+ checkNoAbstractDecls(bc.superClass)
}
checkNoAbstractMembers()
@@ -1166,12 +1166,9 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
}
def createStaticModuleAccessor() = atPhase(phase.next) {
val method = (
- sym.owner.newMethod(sym.pos, sym.name.toTermName)
- setFlag (sym.flags | STABLE)
- resetFlag MODULE
- setInfo NullaryMethodType(sym.moduleClass.tpe)
+ sym.owner.newMethod(sym.name.toTermName, sym.pos, (sym.flags | STABLE) & ~MODULE)
+ setInfoAndEnter NullaryMethodType(sym.moduleClass.tpe)
)
- sym.owner.info.decls enter method
localTyper.typedPos(tree.pos)(gen.mkModuleAccessDef(method, sym))
}
def createInnerModuleAccessor(vdef: Tree) = List(
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index cde531adc1..4e4fbe35cb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -97,18 +97,13 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
var superAcc = clazz.info.decl(supername).suchThat(_.alias == sym)
if (superAcc == NoSymbol) {
debuglog("add super acc " + sym + sym.locationString + " to `" + clazz);//debug
- superAcc =
- clazz.newMethod(tree.pos, supername)
- .setFlag(SUPERACCESSOR | PRIVATE)
- .setAlias(sym)
+ superAcc = clazz.newMethod(supername, tree.pos, SUPERACCESSOR | PRIVATE) setAlias sym
var superAccTpe = clazz.thisType.memberType(sym)
if (sym.isModule && !sym.isMethod) {
// the super accessor always needs to be a method. See #231
superAccTpe = NullaryMethodType(superAccTpe)
}
- superAcc.setInfo(superAccTpe.cloneInfo(superAcc))
- //println("creating super acc "+superAcc+":"+superAcc.tpe)//DEBUG
- clazz.info.decls enter superAcc
+ superAcc setInfoAndEnter (superAccTpe cloneInfo superAcc)
storeAccessorDefinition(clazz, DefDef(superAcc, EmptyTree))
}
atPos(sup.pos) {
@@ -312,14 +307,12 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
memberType.cloneInfo(protAcc).asSeenFrom(qual.tpe, sym.owner))
}
- var protAcc = clazz.info.decl(accName).suchThat(s => s == NoSymbol || s.tpe =:= accType(s))
- if (protAcc == NoSymbol) {
- protAcc = clazz.newMethod(tree.pos, nme.protName(sym.originalName))
- protAcc.setInfo(accType(protAcc))
- clazz.info.decls.enter(protAcc);
+ val protAcc = clazz.info.decl(accName).suchThat(s => s == NoSymbol || s.tpe =:= accType(s)) orElse {
+ val newAcc = clazz.newMethod(nme.protName(sym.originalName), tree.pos)
+ newAcc setInfoAndEnter accType(newAcc)
- val code = DefDef(protAcc, {
- val (receiver :: _) :: tail = protAcc.paramss
+ val code = DefDef(newAcc, {
+ val (receiver :: _) :: tail = newAcc.paramss
val base: Tree = Select(Ident(receiver), sym)
val allParamTypes = mapParamss(sym)(_.tpe)
val args = map2(tail, allParamTypes)((params, tpes) => map2(params, tpes)(makeArg(_, receiver, _)))
@@ -328,12 +321,15 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
debuglog("" + code)
storeAccessorDefinition(clazz, code)
+ newAcc
}
- var res: Tree = atPos(tree.pos) {
- if (targs.head == EmptyTree)
- Apply(Select(This(clazz), protAcc), List(qual))
- else
- Apply(TypeApply(Select(This(clazz), protAcc), targs), List(qual))
+ val selection = Select(This(clazz), protAcc)
+ def mkApply(fn: Tree) = Apply(fn, qual :: Nil)
+ val res = atPos(tree.pos) {
+ targs.head match {
+ case EmptyTree => mkApply(selection)
+ case _ => mkApply(TypeApply(selection, targs))
+ }
}
debuglog("Replaced " + tree + " with " + res)
if (hasArgs) localTyper.typedOperator(res) else localTyper.typed(res)
@@ -371,25 +367,21 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
val clazz = hostForAccessorOf(field, currentOwner.enclClass)
assert(clazz != NoSymbol, field)
debuglog("Decided for host class: " + clazz)
+
val accName = nme.protSetterName(field.originalName)
- var protAcc = clazz.info.decl(accName)
- if (protAcc == NoSymbol) {
- protAcc = clazz.newMethod(field.pos, nme.protSetterName(field.originalName))
- protAcc.setInfo(MethodType(protAcc.newSyntheticValueParams(List(clazz.typeOfThis, field.tpe)),
- UnitClass.tpe))
- clazz.info.decls.enter(protAcc)
- val code = DefDef(protAcc, {
- val obj :: value :: Nil = protAcc.paramss.head
- atPos(tree.pos) {
- Assign(
- Select(Ident(obj), field.name),
- Ident(value))
- }
- })
- debuglog("" + code)
- storeAccessorDefinition(clazz, code)
+ val protectedAccessor = clazz.info decl accName orElse {
+ val protAcc = clazz.newMethod(accName, field.pos)
+ val paramTypes = List(clazz.typeOfThis, field.tpe)
+ val params = protAcc newSyntheticValueParams paramTypes
+ val accessorType = MethodType(params, UnitClass.tpe)
+
+ protAcc setInfoAndEnter accessorType
+ val obj :: value :: Nil = params
+ storeAccessorDefinition(clazz, DefDef(protAcc, Assign(Select(Ident(obj), field.name), Ident(value))))
+
+ protAcc
}
- atPos(tree.pos)(Select(This(clazz), protAcc))
+ atPos(tree.pos)(Select(This(clazz), protectedAccessor))
}
/** Does `sym` need an accessor when accessed from `currentOwner`?
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 92e4e257bf..4e986dc5aa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -110,12 +110,12 @@ trait SyntheticMethods extends ast.TreeDSL {
}
private def createInternal(name: Name, f: Symbol => Tree, info: Type): Tree = {
- val m = clazz.newMethod(clazz.pos.focus, name.toTermName)
+ val m = clazz.newMethod(name.toTermName, clazz.pos.focus)
m setInfo info
finishMethod(m, f)
}
private def createInternal(name: Name, f: Symbol => Tree, infoFn: Symbol => Type): Tree = {
- val m = clazz.newMethod(clazz.pos.focus, name.toTermName)
+ val m = clazz.newMethod(name.toTermName, clazz.pos.focus)
m setInfo infoFn(m)
finishMethod(m, f)
}
@@ -282,7 +282,7 @@ trait SyntheticMethods extends ast.TreeDSL {
def argsBody: Tree = {
val otherName = context.unit.freshTermName(clazz.name + "$")
- val otherSym = m.newValue(m.pos, otherName) setInfo clazz.tpe setFlag SYNTHETIC
+ val otherSym = m.newValue(otherName, m.pos, SYNTHETIC) setInfo clazz.tpe
val pairwise = accessors map (acc => fn(Select(This(clazz), acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc)))
val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(This(clazz)))
def block = Block(ValDef(otherSym, thatCast), AND(pairwise :+ canEq: _*))
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 080a802272..fe3ceafa2d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -181,10 +181,7 @@ trait TypeDiagnostics {
val getter = if (member.isSetter) member.getter(member.owner) else member
val flags = if (getter.setter(member.owner) != NoSymbol) DEFERRED | MUTABLE else DEFERRED
- ( getter.owner.newValue(getter.pos, getter.name.toTermName)
- setInfo getter.tpe.resultType
- setFlag flags
- )
+ getter.owner.newValue(getter.name.toTermName, getter.pos, flags) setInfo getter.tpe.resultType
}
def treeSymTypeMsg(tree: Tree): String = {
@@ -497,6 +494,11 @@ trait TypeDiagnostics {
def cyclicReferenceMessage(sym: Symbol, tree: Tree) = condOpt(tree) {
case ValDef(_, _, tpt, _) if tpt.tpe == null => "recursive "+sym+" needs type"
case DefDef(_, _, _, _, tpt, _) if tpt.tpe == null => List(cyclicAdjective(sym), sym, "needs result type") mkString " "
+ case Import(expr, selectors) =>
+ ( "encountered unrecoverable cycle resolving import." +
+ "\nNote: this is often due in part to a class depending on a definition nested within its companion." +
+ "\nIf applicable, you may wish to try moving some members into another object."
+ )
}
/** Report a type error.
@@ -511,7 +513,11 @@ trait TypeDiagnostics {
ex match {
case CyclicReference(sym, info: TypeCompleter) =>
- contextError(ex.pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
+ val pos = info.tree match {
+ case Import(expr, _) => expr.pos
+ case _ => ex.pos
+ }
+ contextError(pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
if (sym == ObjectClass)
throw new FatalError("cannot redefine root "+sym)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 5ccf27ded9..216ad6cd4c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -911,7 +911,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
if (tree.isType)
adaptType()
- else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode))
+ else if (inExprModeButNot(mode, FUNmode) && tree.symbol != null && tree.symbol.isMacro && !tree.isDef) {
+ val tree1 = expandMacro(tree)
+ if (tree1.isErroneous) tree1 else typed(tree1, mode, pt)
+ } else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode))
adaptConstrPattern()
else if (inAllModes(mode, EXPRmode | FUNmode) &&
!tree.tpe.isInstanceOf[MethodType] &&
@@ -1659,7 +1662,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case Some(repl) =>
silent(_.typedTypeConstructor(stringParser(repl).typ())) match {
case tpt: Tree =>
- val alias = enclClass.newAliasType(useCase.pos, name.toTypeName)
+ val alias = enclClass.newAliasType(name.toTypeName, useCase.pos)
val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias)
alias setInfo typeFun(tparams, appliedType(tpt.tpe, tparams map (_.tpe)))
context.scope.enter(alias)
@@ -1793,7 +1796,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case ldef @ LabelDef(_, _, _) =>
if (ldef.symbol == NoSymbol)
ldef.symbol = namer.enterInScope(
- context.owner.newLabel(ldef.pos, ldef.name) setInfo MethodType(List(), UnitClass.tpe))
+ context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), UnitClass.tpe))
case _ =>
}
}
@@ -1814,7 +1817,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
} else {
context.scope.unlink(ldef.symbol)
val sym2 = namer.enterInScope(
- context.owner.newLabel(ldef.pos, ldef.name) setInfo MethodType(List(), restpe))
+ context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), restpe))
val rhs2 = typed(resetAllAttrs(ldef.rhs), restpe)
ldef.params foreach (param => param.tpe = param.symbol.tpe)
treeCopy.LabelDef(ldef, ldef.name, ldef.params, rhs2) setSymbol sym2 setType restpe
@@ -2529,7 +2532,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val unapp = unapplyMember(otpe)
val unappType = otpe.memberType(unapp)
- val argDummy = context.owner.newValue(fun.pos, nme.SELECTOR_DUMMY) setFlag SYNTHETIC setInfo pt
+ val argDummy = context.owner.newValue(nme.SELECTOR_DUMMY, fun.pos, SYNTHETIC) setInfo pt
val arg = Ident(argDummy) setType pt
if (!isApplicableSafe(Nil, unappType, List(pt), WildcardType)) {
@@ -2542,7 +2545,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val pattp = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe)
// turn any unresolved type variables in freevars into existential skolems
- val skolems = freeVars map (fv => newExistentialSkolem(fv, unapplyContext.owner, fv))
+ val skolems = freeVars map (fv => unapplyContext.owner.newExistentialSkolem(fv, fv))
arg.tpe = pattp.substSym(freeVars, skolems)
argDummy setInfo arg.tpe
}
@@ -2817,7 +2820,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
val bound = sym.existentialBound
val sowner = if (isRawParameter(sym)) context.owner else sym.owner
- val quantified = sowner.newExistential(sym.pos, name)
+ val quantified = sowner.newExistential(name, sym.pos)
quantified setInfo bound.cloneInfo(quantified)
}
@@ -2835,9 +2838,22 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def packSymbols(hidden: List[Symbol], tp: Type): Type =
if (hidden.isEmpty) tp
else existentialTransform(hidden, tp)(existentialAbstraction)
+
+ def isReferencedFrom(ctx: Context, sym: Symbol): Boolean =
+ ctx.owner.isTerm &&
+ (ctx.scope.exists { dcl => dcl.isInitialized && (dcl.info contains sym) }) ||
+ {
+ var ctx1 = ctx.outer
+ while ((ctx1 != NoContext) && (ctx1.scope eq ctx.scope)) ctx1 = ctx1.outer
+ (ctx1 != NoContext) && isReferencedFrom(ctx1, sym)
+ }
def isCapturedExistential(sym: Symbol) =
- sym hasAllFlags (EXISTENTIAL | CAPTURED) // todo refine this
+ (sym hasAllFlags (EXISTENTIAL | CAPTURED)) && {
+ val start = startTimer(isReferencedNanos)
+ try !isReferencedFrom(context, sym)
+ finally stopTimer(isReferencedNanos, start)
+ }
def packCaptured(tpe: Type): Type = {
val captured = mutable.Set[Symbol]()
@@ -3079,7 +3095,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
* */
( context.owner
newLocalDummy (ann.pos)
- newValue (ann.pos, nme.self)
+ newValue (nme.self, ann.pos)
setInfo (arg1.tpe.withoutAnnotations)
)
}
@@ -3120,9 +3136,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (vble == NoSymbol)
vble =
if (isFullyDefined(pt))
- context.owner.newAliasType(tree.pos, name) setInfo pt
+ context.owner.newAliasType(name, tree.pos) setInfo pt
else
- context.owner.newAbstractType(tree.pos, name) setInfo TypeBounds.empty
+ context.owner.newAbstractType(name, tree.pos) setInfo TypeBounds.empty
val rawInfo = vble.rawInfo
vble = if (vble.name == tpnme.WILDCARD) context.scope.enter(vble)
else namer.enterInScope(vble)
@@ -3130,7 +3146,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def typedBindTerm(name: TermName) = {
if (vble == NoSymbol)
- vble = context.owner.newValue(tree.pos, name)
+ vble = context.owner.newValue(name, tree.pos)
if (vble.name.toTermName != nme.WILDCARD) {
if ((mode & ALTmode) != 0)
error(tree.pos, "illegal variable in pattern alternative")
@@ -3471,9 +3487,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// (calling typed1 more than once for the same tree)
if (checked ne res) typed { atPos(tree.pos)(checked) }
else res
- } else if ((mode & FUNmode) == 0 && fun2.hasSymbol && fun2.symbol.isMacro)
- typed1(macroExpand(res), mode, pt)
- else
+ } else
res
case ex: TypeError =>
fun match {
@@ -3483,7 +3497,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (treeInfo.isVariableOrGetter(qual1)) {
stopTimer(failedOpEqNanos, opeqStart)
convertToAssignment(fun, qual1, name, args, ex)
- }
+ }
else {
stopTimer(failedApplyNanos, appStart)
reportTypeError(fun.pos, ex)
@@ -3800,11 +3814,31 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
var cx = startingIdentContext
while (defSym == NoSymbol && cx != NoContext) {
+ // !!! Shouldn't the argument to compileSourceFor be cx, not context?
+ // I can't tell because those methods do nothing in the standard compiler,
+ // presumably they are overridden in the IDE.
currentRun.compileSourceFor(context.asInstanceOf[analyzer.Context], name)
pre = cx.enclClass.prefix
defEntry = cx.scope.lookupEntry(name)
if ((defEntry ne null) && qualifies(defEntry.sym)) {
- defSym = defEntry.sym
+ // Right here is where SI-1987, overloading in package objects, can be
+ // seen to go wrong. There is an overloaded symbol, but when referring
+ // to the unqualified identifier from elsewhere in the package, only
+ // the last definition is visible. So overloading mis-resolves and is
+ // definition-order dependent, bad things. See run/t1987.scala.
+ //
+ // I assume the actual problem involves how/where these symbols are entered
+ // into the scope. But since I didn't figure out how to fix it that way, I
+ // catch it here by looking up package-object-defined symbols in the prefix.
+ if (isInPackageObject(defEntry.sym, pre.typeSymbol)) {
+ defSym = pre.member(defEntry.sym.name)
+ if (defSym ne defEntry.sym) {
+ log("!!! Overloaded package object member resolved incorrectly.\n Discarded: " +
+ defEntry.sym.defString + "\n Using: " + defSym.defString)
+ }
+ }
+ else
+ defSym = defEntry.sym
}
else {
cx = cx.enclClass
@@ -3897,9 +3931,18 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// Avoiding some spurious error messages: see SI-2388.
if (reporter.hasErrors && (name startsWith tpnme.ANON_CLASS_NAME)) ()
else {
- val similar = (
- // name length check to limit unhelpful suggestions for e.g. "x" and "b1"
- if (name.length > 2) {
+ // This laborious determination arrived at to keep the tests working.
+ val calcSimilar = (
+ name.length > 2 && (
+ startingIdentContext.reportGeneralErrors
+ || startingIdentContext.enclClassOrMethod.reportGeneralErrors
+ )
+ )
+ // avoid calculating if we're in "silent" mode.
+ // name length check to limit unhelpful suggestions for e.g. "x" and "b1"
+ val similar = {
+ if (!calcSimilar) ""
+ else {
val allowed = (
startingIdentContext.enclosingContextChain
flatMap (ctx => ctx.scope.toList ++ ctx.imports.flatMap(_.allImportedSymbols))
@@ -3912,8 +3955,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
)
similarString("" + name, allowedStrings)
}
- else ""
- )
+ }
error(tree.pos, "not found: "+decodeWithKind(name, context.owner) + similar)
}
}
@@ -4098,8 +4140,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case tree @ Function(_, _) =>
if (tree.symbol == NoSymbol)
- tree.symbol = context.owner.newValue(tree.pos, nme.ANON_FUN_NAME)
- .setFlag(SYNTHETIC).setInfo(NoType)
+ tree.symbol = context.owner.newAnonymousFunctionValue(tree.pos)
+
newTyper(context.makeNewScope(tree, tree.symbol)).typedFunction(tree, mode, pt)
case Assign(lhs, rhs) =>
@@ -4413,6 +4455,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
+ def expandMacro(tree: Tree): Tree = try {
+ macroExpand(tree) match {
+ case t: Tree => t
+ case t => errorTree(tree, "macros must return a compiler-specific tree; returned class is: " + t.getClass)
+ }
+ } catch {
+ case ex: MacroExpandError => errorTree(tree, ex.msg)
+ }
+
def atOwner(owner: Symbol): Typer =
newTyper(context.make(context.tree, owner))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index fd6f972ffc..a7cd89621c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -21,7 +21,7 @@ trait Unapplies extends ast.TreeDSL
import CODE.{ CASE => _, _ }
import treeInfo.{ isRepeatedParamType, isByNameParamType }
- private val unapplyParamName = newTermName("x$0")
+ private val unapplyParamName = nme.x_0
/** returns type list for return type of the extraction */
def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index a1ec90ed3f..53c767be20 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -9,7 +9,30 @@ package util
object Position {
val tabInc = 8
+
+ /** Prints the message with the given position indication. */
+ def formatMessage(posIn: Position, msg: String, shortenFile: Boolean): String = {
+ val pos = (
+ if (posIn eq null) NoPosition
+ else if (posIn.isDefined) posIn.inUltimateSource(posIn.source)
+ else posIn
+ )
+ def file = pos.source.file
+ def prefix = if (shortenFile) file.name else file.path
+
+ pos match {
+ case FakePos(fmsg) => fmsg+" "+msg
+ case NoPosition => msg
+ case _ =>
+ List(
+ "%s:%s: %s".format(prefix, pos.line, msg),
+ pos.lineContent.stripLineEnd,
+ " " * (pos.column - 1) + "^"
+ ) mkString "\n"
+ }
+ }
}
+
/** The Position class and its subclasses represent positions of ASTs and symbols.
* Except for NoPosition and FakePos, every position refers to a SourceFile
* and to an offset in the sourcefile (its `point`). For batch compilation,
diff --git a/src/compiler/scala/tools/nsc/util/Statistics.scala b/src/compiler/scala/tools/nsc/util/Statistics.scala
index 27239b9b9f..f7c27dceb5 100644
--- a/src/compiler/scala/tools/nsc/util/Statistics.scala
+++ b/src/compiler/scala/tools/nsc/util/Statistics.scala
@@ -20,7 +20,7 @@ class Statistics extends scala.reflect.internal.util.Statistics {
val typedSelectCount = new Counter
val typerNanos = new Timer
val classReadNanos = new Timer
-
+
val failedApplyNanos = new Timer
val failedOpEqNanos = new Timer
val failedSilentNanos = new Timer
@@ -48,6 +48,7 @@ class Statistics extends scala.reflect.internal.util.Statistics {
val subtypeImprovCount = new SubCounter(subtypeCount)
val subtypeETNanos = new Timer
val matchesPtNanos = new Timer
+ val isReferencedNanos = new Timer
val ctr1 = new Counter
val ctr2 = new Counter
val ctr3 = new Counter
@@ -137,6 +138,7 @@ abstract class StatisticsInfo {
inform("time spent in failed : "+showRelTyper(failedSilentNanos))
inform(" failed apply : "+showRelTyper(failedApplyNanos))
inform(" failed op= : "+showRelTyper(failedOpEqNanos))
+ inform("time spent ref scanning : "+showRelTyper(isReferencedNanos))
inform("micros by tree node : "+showCounts(microsByType))
inform("#visits by tree node : "+showCounts(visitsByType))
val average = new ClassCounts
diff --git a/src/compiler/scala/tools/util/EditDistance.scala b/src/compiler/scala/tools/util/EditDistance.scala
index 5067dce384..5f152ecabb 100644
--- a/src/compiler/scala/tools/util/EditDistance.scala
+++ b/src/compiler/scala/tools/util/EditDistance.scala
@@ -7,6 +7,8 @@ package scala.tools
package util
object EditDistance {
+ import java.lang.Character.{ toLowerCase => lower }
+
def similarString(name: String, allowed: TraversableOnce[String]): String = {
val suggested = suggestions(name, allowed.toSeq, maxDistance = 1, maxSuggestions = 2)
if (suggested.isEmpty) ""
@@ -46,7 +48,7 @@ object EditDistance {
var j = 1
while (j <= m) {
val t_j = t(j - 1)
- val cost = if (s_i == t_j) 0 else 1
+ val cost = if (lower(s_i) == lower(t_j)) 0 else 1
val c1 = d(i - 1)(j) + 1
val c2 = d(i)(j - 1) + 1
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index 585dc3fbe8..cea558d2d3 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -215,13 +215,9 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
case ldef @ LabelDef(name, params, rhs) =>
if (hasAnswerTypeAnn(tree.tpe)) {
- val sym = currentOwner.newMethod(tree.pos, name)
- .setInfo(ldef.symbol.info)
- .setFlag(Flags.SYNTHETIC)
-
- val rhs1 = new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs)
- val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe))
- new ChangeOwnerTraverser(currentOwner, sym) traverse rhsVal
+ val sym = currentOwner.newMethod(name, tree.pos, Flags.SYNTHETIC) setInfo ldef.symbol.info
+ val rhs1 = new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs)
+ val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe)) changeOwner (currentOwner -> sym)
val stm1 = localTyper.typed(DefDef(sym, rhsVal))
val expr = localTyper.typed(Apply(Ident(sym), List()))
@@ -355,12 +351,12 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val valueTpe = removeAllCPSAnnotations(expr.tpe)
- val sym = currentOwner.newValue(tree.pos, newTermName(unit.fresh.newName("tmp")))
- .setInfo(valueTpe)
- .setFlag(Flags.SYNTHETIC)
- .setAnnotations(List(AnnotationInfo(MarkerCPSSym.tpe, Nil, Nil)))
-
- new ChangeOwnerTraverser(currentOwner, sym) traverse expr
+ val sym: Symbol = (
+ currentOwner.newValue(newTermName(unit.fresh.newName("tmp")), tree.pos, Flags.SYNTHETIC)
+ setInfo valueTpe
+ setAnnotations List(AnnotationInfo(MarkerCPSSym.tpe, Nil, Nil))
+ )
+ expr.changeOwner(currentOwner -> sym)
(stms ::: List(ValDef(sym, expr) setType(NoType)),
Ident(sym) setType(valueTpe) setPos(tree.pos), linearize(spc, spcVal)(unit, tree.pos))
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
index 960b27c52f..b2a1546b4e 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
@@ -192,18 +192,17 @@ abstract class SelectiveCPSTransform extends PluginComponent with
// val expr2 = if (catches.nonEmpty) {
val pos = catches.head.pos
- val argSym = currentOwner.newValueParameter(pos, cpsNames.ex).setInfo(ThrowableClass.tpe)
+ val argSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe)
val rhs = Match(Ident(argSym), catches1)
val fun = Function(List(ValDef(argSym)), rhs)
- val funSym = currentOwner.newValueParameter(pos, cpsNames.catches).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp)))
+ val funSym = currentOwner.newValueParameter(cpsNames.catches, pos).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp)))
val funDef = localTyper.typed(atPos(pos) { ValDef(funSym, fun) })
val expr2 = localTyper.typed(atPos(pos) { Apply(Select(expr1, expr1.tpe.member(cpsNames.flatMapCatch)), List(Ident(funSym))) })
argSym.owner = fun.symbol
- val chown = new ChangeOwnerTraverser(currentOwner, fun.symbol)
- chown.traverse(rhs)
+ rhs.changeOwner(currentOwner -> fun.symbol)
- val exSym = currentOwner.newValueParameter(pos, cpsNames.ex).setInfo(ThrowableClass.tpe)
+ val exSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe)
val catch2 = { localTyper.typedCases(tree, List(
CaseDef(Bind(exSym, Typed(Ident("_"), TypeTree(ThrowableClass.tpe))),
Apply(Select(Ident(funSym), nme.isDefinedAt), List(Ident(exSym))),
@@ -263,8 +262,7 @@ abstract class SelectiveCPSTransform extends PluginComponent with
val tpe = vd.symbol.tpe
val rhs1 = atOwner(vd.symbol) { transform(rhs) }
-
- new ChangeOwnerTraverser(vd.symbol, currentOwner).traverse(rhs1) // TODO: don't traverse twice
+ rhs1.changeOwner(vd.symbol -> currentOwner) // TODO: don't traverse twice
log("valdef symbol " + vd.symbol + " has type " + tpe)
log("right hand side " + rhs1 + " has type " + rhs1.tpe)
@@ -302,11 +300,11 @@ abstract class SelectiveCPSTransform extends PluginComponent with
}
def applyCombinatorFun(ctxR: Tree, body: Tree) = {
- val arg = currentOwner.newValueParameter(ctxR.pos, name).setInfo(tpe)
+ val arg = currentOwner.newValueParameter(name, ctxR.pos).setInfo(tpe)
val body1 = (new TreeSymSubstituter(List(vd.symbol), List(arg)))(body)
val fun = localTyper.typed(atPos(vd.symbol.pos) { Function(List(ValDef(arg)), body1) }) // types body as well
arg.owner = fun.symbol
- new ChangeOwnerTraverser(currentOwner, fun.symbol).traverse(body1)
+ body1.changeOwner(currentOwner -> fun.symbol)
// see note about multiple traversals above
diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala
index dc8e67bbb0..7517e6604b 100644
--- a/src/library/scala/Function1.scala
+++ b/src/library/scala/Function1.scala
@@ -24,10 +24,18 @@ package scala
* assert(succ(0) == anonfun1(0))
* }
* }}}
+ *
+ * Note that `Function1` does not define a total function, as might
+ * be suggested by the existence of [[scala.PartialFunction]]. The only
+ * distinction between `Function1` and `PartialFunction` is that the
+ * latter can specify inputs which it will not handle.
+ *
*/
@annotation.implicitNotFound(msg = "No implicit view available from ${T1} => ${R}.")
trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double) +R] extends AnyRef { self =>
- /** Apply the body of this function to the argument.
+ /** Apply the body of this function to the argument. It may throw an
+ * exception.
+ *
* @return the result of function application.
*/
def apply(v1: T1): R
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index b2910c2278..70caff0221 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -13,6 +13,36 @@ package scala
* The function `isDefinedAt` allows to test dynamically if a value is in
* the domain of the function.
*
+ * Even if `isDefinedAt` returns true for an `a: A`, calling `apply(a)` may
+ * still throw an exception, so the following code is legal:
+ *
+ * {{{
+ * val f: PartialFunction[Int, Any] = { case _ => 1/0 }
+ * }}}
+ *
+ * The main distinction between `PartialFunction` and [[scala.Function1]] is
+ * that the user of a `PartialFunction` may choose to do something different
+ * with input that is declared to be outside its domain. For example:
+ *
+ * {{{
+ * val sample = 1 to 10
+ * val isEven: PartialFunction[Int, String] = {
+ * case x if x % 2 == 0 => x+" is even"
+ * }
+ *
+ * // the method collect can use isDefinedAt to select which members to collect
+ * val evenNumbers = sample collect isEven
+ *
+ * val isOdd: PartialFunction[Int, String] = {
+ * case x if x % 2 == 1 => x+" is odd"
+ * }
+ *
+ * // the method orElse allows chaining another partial function to handle
+ * // input outside the declared domain
+ * val numbers = sample map (isEven orElse isOdd)
+ * }}}
+ *
+ *
* @author Martin Odersky
* @version 1.0, 16/07/2003
*/
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index b175fb9e1d..824e048e73 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -269,7 +269,7 @@ object Predef extends LowPriorityImplicits {
def printf(text: String, xs: Any*) = Console.print(text.format(xs: _*))
def readLine(): String = Console.readLine()
- def readLine(text: String, args: Any*) = Console.readLine(text, args)
+ def readLine(text: String, args: Any*) = Console.readLine(text, args: _*)
def readBoolean() = Console.readBoolean()
def readByte() = Console.readByte()
def readShort() = Console.readShort()
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
new file mode 100644
index 0000000000..6116547aa2
--- /dev/null
+++ b/src/library/scala/StringContext.scala
@@ -0,0 +1,191 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2012, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+
+import collection.mutable.ArrayBuffer
+
+/** A class to support string interpolation.
+ * This class supports string interpolation as outlined in Scala SIP-11.
+ * It needs to be fully documented once the SIP is accepted.
+ *
+ * @param parts The parts that make up the interpolated string,
+ * without the expressions that get inserted by interpolation.
+ */
+case class StringContext(parts: String*) {
+
+ import StringContext._
+
+ /** Checks that the given arguments `args` number one less than the number
+ * of `parts` supplied to the enclosing `StringContext`.
+ * @param `args` The arguments to be checked.
+ * @throws An `IllegalArgumentException` if this is not the case.
+ */
+ def checkLengths(args: Any*): Unit =
+ if (parts.length != args.length + 1)
+ throw new IllegalArgumentException("wrong number of arguments for interpolated string")
+
+
+ /** The simple string interpolator.
+ *
+ * It inserts its arguments between corresponding parts of the string context.
+ * It also treats standard escape sequences as defined in the Scala specification.
+ * @param `args` The arguments to be inserted into the resulting string.
+ * @throws An `IllegalArgumentException`
+ * if the number of `parts` in the enclosing `StringContext` does not exceed
+ * the number of arguments `arg` by exactly 1.
+ * @throws A `StringContext.InvalidEscapeException` if if a `parts` string contains a backslash (`\`) character
+ * that does not start a valid escape sequence.
+ */
+ def s(args: Any*) = {
+ checkLengths(args: _*)
+ val pi = parts.iterator
+ val ai = args.iterator
+ val bldr = new java.lang.StringBuilder(treatEscapes(pi.next))
+ while (ai.hasNext) {
+ bldr append ai.next
+ bldr append treatEscapes(pi.next)
+ }
+ bldr.toString
+ }
+
+ /** The formatted string interpolator.
+ *
+ * It inserts its arguments between corresponding parts of the string context.
+ * It also treats standard escape sequences as defined in the Scala specification.
+ * Finally, if an interpolated expression is followed by a `parts` string
+ * that starts with a formatting specifier, the expression is formatted according to that
+ * specifier. All specifiers allowed in Java format strings are handled, and in the same
+ * way they are treated in Java.
+ *
+ * @param `args` The arguments to be inserted into the resulting string.
+ * @throws An `IllegalArgumentException`
+ * if the number of `parts` in the enclosing `StringContext` does not exceed
+ * the number of arguments `arg` by exactly 1.
+ * @throws A `StringContext.InvalidEscapeException` if a `parts` string contains a backslash (`\`) character
+ * that does not start a valid escape sequence.
+ *
+ * Note: The `f` method works by assembling a format string from all the `parts` strings and using
+ * `java.lang.String.format` to format all arguments with that format string. The format string is
+ * obtained by concatenating all `parts` strings, and performing two transformations:
+ *
+ * 1. Let a _formatting position_ be a start of any `parts` string except the first one.
+ * If a formatting position does not refer to a `%` character (which is assumed to
+ * start a format specifier), then the string format specifier `%s` is inserted.
+ *
+ * 2. Any `%` characters not in formatting positions are left in the resulting
+ * string literally. This is achieved by replacing each such occurrence by a string
+ * format specifier `%s` and adding a corresponding argument string `"%"`.
+ */
+ def f(args: Any*) = {
+ checkLengths(args: _*)
+ val pi = parts.iterator
+ val ai = args.iterator
+ val bldr = new java.lang.StringBuilder
+ val args1 = new ArrayBuffer[Any]
+ def copyString(first: Boolean): Unit = {
+ val str = treatEscapes(pi.next)
+ var start = 0
+ var idx = 0
+ if (!first) {
+ if ((str charAt 0) != '%')
+ bldr append "%s"
+ idx = 1
+ }
+ val len = str.length
+ while (idx < len) {
+ if (str(idx) == '%') {
+ bldr append (str substring (start, idx)) append "%s"
+ args1 += "%"
+ start = idx + 1
+ }
+ idx += 1
+ }
+ bldr append (str substring (start, idx))
+ }
+ copyString(first = true)
+ while (pi.hasNext) {
+ args1 += ai.next
+ copyString(first = false)
+ }
+ bldr.toString format (args1: _*)
+ }
+}
+
+object StringContext {
+
+ /** An exception that is thrown if a string contains a backslash (`\`) character that
+ * that does not start a valid escape sequence.
+ * @param str The offending string
+ * @param idx The index of the offending backslash character in `str`.
+ */
+ class InvalidEscapeException(str: String, idx: Int)
+ extends IllegalArgumentException("invalid escape character at index "+idx+" in \""+str+"\"")
+
+ /** Expands standard Scala escape sequences in a string.
+ * Escape sequences are:
+ * control: `\b`, `\t`, `\n`, `\f`, `\r`
+ * escape: `\\`, `\"`, `\'`
+ * octal: `\d` `\dd` `\ddd` where `d` is an octal digit between `0` and `7`.
+ *
+ * @param A string that may contain escape sequences
+ * @return The string with all escape sequences expanded.
+ */
+ def treatEscapes(str: String): String = {
+ lazy val bldr = new java.lang.StringBuilder
+ val len = str.length
+ var start = 0
+ var cur = 0
+ var idx = 0
+ def output(ch: Char) = {
+ bldr append str substring (start, cur)
+ bldr append ch
+ start = idx
+ }
+ while (idx < len) {
+ cur = idx
+ if (str(idx) == '\\') {
+ idx += 1
+ if ('0' <= str(idx) && str(idx) <= '7') {
+ val leadch = str(idx)
+ var oct = leadch - '0'
+ idx += 1
+ if ('0' <= str(idx) && str(idx) <= '7') {
+ oct = oct * 8 + str(idx) - '0'
+ idx += 1
+ if (leadch <= '3' && '0' <= str(idx) && str(idx) <= '7') {
+ oct = oct * 8 + str(idx) - '0'
+ idx += 1
+ }
+ }
+ output(oct.toChar)
+ } else {
+ val ch = str(idx)
+ idx += 1
+ output {
+ ch match {
+ case 'b' => '\b'
+ case 't' => '\t'
+ case 'n' => '\n'
+ case 'f' => '\f'
+ case 'r' => '\r'
+ case '\"' => '\"'
+ case '\'' => '\''
+ case '\\' => '\\'
+ case _ => throw new InvalidEscapeException(str, cur)
+ }
+ }
+ }
+ } else {
+ idx += 1
+ }
+ }
+ if (start == 0) str
+ else (bldr append str.substring(start, idx)).toString
+ }
+}
diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala
index 122eec2d90..c837775cf9 100644
--- a/src/library/scala/collection/GenTraversableLike.scala
+++ b/src/library/scala/collection/GenTraversableLike.scala
@@ -177,7 +177,28 @@ trait GenTraversableLike[+A, +Repr] extends GenTraversableOnce[A] with Paralleli
def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That
/** Builds a new collection by applying a function to all elements of this $coll
- * and concatenating the results.
+ * and using the elements of the resulting collections. For example:
+ *
+ * {{{
+ * def getWords(lines: Seq[String]): Seq[String] = lines flatMap (line => line split "\\W+")
+ * }}}
+ *
+ * The type of the resulting collection is guided by the static type of $coll. This might
+ * cause unexpected results sometimes. For example:
+ *
+ * {{{
+ * // lettersOf will return a Seq[Char] of likely repeated letters, instead of a Set
+ * def lettersOf(words: Seq[String]) = words flatMap (word => word.toSet)
+ *
+ * // lettersOf will return a Set[Char], not a Seq
+ * def lettersOf(words: Seq[String]) = words.toSet flatMap (word => word.toSeq)
+ *
+ * // xs will be a an Iterable[Int]
+ * val xs = Map("a" -> List(11,111), "b" -> List(22,222)).flatMap(_._2)
+ *
+ * // ys will be a Map[Int, Int]
+ * val ys = Map("a" -> List(1 -> 11,1 -> 111), "b" -> List(2 -> 22,2 -> 222)).flatMap(_._2)
+ * }}}
*
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index 3e42e7812b..305f8d768d 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -471,7 +471,7 @@ trait GenTraversableOnce[+A] {
* $willNotTerminateInf
* @return an indexed sequence containing all elements of this $coll.
*/
- def toIndexedSeq[A1 >: A]: immutable.IndexedSeq[A1]
+ def toIndexedSeq: immutable.IndexedSeq[A]
/** Converts this $coll to a stream.
* $willNotTerminateInf
diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala
index 94f7e9701b..d213e60112 100755
--- a/src/library/scala/collection/JavaConverters.scala
+++ b/src/library/scala/collection/JavaConverters.scala
@@ -48,7 +48,8 @@ package scala.collection
* @author Martin Odersky
* @since 2.8.1
*/
-object JavaConverters {
+
+trait JavaConverters {
import java.{ lang => jl, util => ju }
import java.util.{ concurrent => juc }
import JavaConversions._
@@ -536,3 +537,5 @@ object JavaConverters {
propertiesAsScalaMapConverter(p)
}
+
+object JavaConverters extends JavaConverters \ No newline at end of file
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index b6b4bfb96d..6d84b4276b 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -152,7 +152,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] with GenSeqLike[A, Repr]
if (!hasNext)
Iterator.empty.next
- val result = (self.newBuilder ++= elms).result
+ val result = (self.newBuilder ++= elms.toList).result
var i = idxs.length - 2
while(i >= 0 && idxs(i) >= idxs(i+1))
i -= 1
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index e2acc0b3e0..36d45c0c8a 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -535,7 +535,7 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
val b = newBuilder
var go = false
for (x <- this) {
- if (!p(x)) go = true
+ if (!go && !p(x)) go = true
if (go) b += x
}
b.result
@@ -709,6 +709,9 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
* outer $coll containing this `WithFilter` instance that satisfy
* predicate `p` and concatenating the results.
*
+ * The type of the resulting collection will be guided by the static type
+ * of the outer $coll.
+ *
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala
index 908c4c808d..5bb2e563f6 100644
--- a/src/library/scala/collection/TraversableOnce.scala
+++ b/src/library/scala/collection/TraversableOnce.scala
@@ -245,7 +245,7 @@ trait TraversableOnce[+A] extends GenTraversableOnce[A] {
def toSeq: Seq[A] = toStream
- def toIndexedSeq[B >: A]: immutable.IndexedSeq[B] = immutable.IndexedSeq() ++ seq
+ def toIndexedSeq: immutable.IndexedSeq[A] = immutable.IndexedSeq() ++ seq
def toBuffer[B >: A]: mutable.Buffer[B] = new ArrayBuffer[B] ++= seq
diff --git a/src/library/scala/collection/TraversableProxyLike.scala b/src/library/scala/collection/TraversableProxyLike.scala
index 15565e57c6..e7e797391e 100644
--- a/src/library/scala/collection/TraversableProxyLike.scala
+++ b/src/library/scala/collection/TraversableProxyLike.scala
@@ -77,7 +77,7 @@ trait TraversableProxyLike[+A, +Repr <: TraversableLike[A, Repr] with Traversabl
override def toList: List[A] = self.toList
override def toIterable: Iterable[A] = self.toIterable
override def toSeq: Seq[A] = self.toSeq
- override def toIndexedSeq[B >: A] = self.toIndexedSeq
+ override def toIndexedSeq: immutable.IndexedSeq[A] = self.toIndexedSeq
override def toBuffer[B >: A] = self.toBuffer
override def toStream: Stream[A] = self.toStream
override def toSet[B >: A]: immutable.Set[B] = self.toSet
diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
index 12c1a75c7a..7333074778 100644
--- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala
+++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
@@ -116,7 +116,19 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew
}
/** Converts this $coll of traversable collections into
- * a $coll in which all element collections are concatenated.
+ * a $coll formed by the elements of these traversable
+ * collections.
+ *
+ * The resulting collection's type will be guided by the
+ * static type of $coll. For example:
+ *
+ * {{{
+ * val xs = List(Set(1, 2, 3), Set(1, 2, 3))
+ * // xs == List(1, 2, 3, 1, 2, 3)
+ *
+ * val ys = Set(List(1, 2, 3), List(3, 2, 1))
+ * // ys == Set(1, 2, 3)
+ * }}}
*
* @tparam B the type of the elements of each traversable collection.
* @param asTraversable an implicit conversion which asserts that the element
diff --git a/src/library/scala/collection/generic/MutableSortedSetFactory.scala b/src/library/scala/collection/generic/MutableSortedSetFactory.scala
new file mode 100644
index 0000000000..b235379575
--- /dev/null
+++ b/src/library/scala/collection/generic/MutableSortedSetFactory.scala
@@ -0,0 +1,33 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package generic
+
+import scala.collection.mutable.{ Builder, GrowingBuilder }
+
+/**
+ * @define Coll mutable.SortedSet
+ * @define coll mutable sorted
+ *
+ * @author Lucien Pereira
+ *
+ */
+abstract class MutableSortedSetFactory[CC[A] <: mutable.SortedSet[A] with SortedSetLike[A, CC[A]] with mutable.Set[A] with mutable.SetLike[A, CC[A]]] extends SortedSetFactory[CC] {
+
+ /**
+ * mutable.SetBuilder uses '+' which is not a primitive for anything extending mutable.SetLike,
+ * this causes serious perfomances issues since each time 'elems = elems + x'
+ * is evaluated elems is cloned (which is O(n)).
+ *
+ * Fortunately GrowingBuilder comes to rescue.
+ *
+ */
+ override def newBuilder[A](implicit ord: Ordering[A]): Builder[A, CC[A]] = new GrowingBuilder[A, CC[A]](empty)
+
+}
diff --git a/src/library/scala/collection/generic/TraversableForwarder.scala b/src/library/scala/collection/generic/TraversableForwarder.scala
index 6529fe4a79..3d723a1feb 100644
--- a/src/library/scala/collection/generic/TraversableForwarder.scala
+++ b/src/library/scala/collection/generic/TraversableForwarder.scala
@@ -61,7 +61,7 @@ trait TraversableForwarder[+A] extends Traversable[A] {
override def toList: List[A] = underlying.toList
override def toIterable: Iterable[A] = underlying.toIterable
override def toSeq: Seq[A] = underlying.toSeq
- override def toIndexedSeq[B >: A] = underlying.toIndexedSeq
+ override def toIndexedSeq = underlying.toIndexedSeq
override def toBuffer[B >: A] = underlying.toBuffer
override def toStream: Stream[A] = underlying.toStream
override def toSet[B >: A]: immutable.Set[B] = underlying.toSet
diff --git a/src/library/scala/collection/immutable/IndexedSeq.scala b/src/library/scala/collection/immutable/IndexedSeq.scala
index bbbef158af..e3939001d8 100644
--- a/src/library/scala/collection/immutable/IndexedSeq.scala
+++ b/src/library/scala/collection/immutable/IndexedSeq.scala
@@ -22,7 +22,7 @@ trait IndexedSeq[+A] extends Seq[A]
with GenericTraversableTemplate[A, IndexedSeq]
with IndexedSeqLike[A, IndexedSeq[A]] {
override def companion: GenericCompanion[IndexedSeq] = IndexedSeq
- override def toIndexedSeq[B >: A]: IndexedSeq[B] = this
+ override def toIndexedSeq: IndexedSeq[A] = this
override def seq: IndexedSeq[A] = this
}
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index c6f056bd81..e9ecc75e0f 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -316,28 +316,7 @@ final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extend
override def tail : List[B] = tl
override def isEmpty: Boolean = false
- import java.io._
- private def writeObject(out: ObjectOutputStream) {
- var xs: List[B] = this
- while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail }
- out.writeObject(ListSerializeEnd)
- }
-
- private def readObject(in: ObjectInputStream) {
- hd = in.readObject.asInstanceOf[B]
- assert(hd != ListSerializeEnd)
- var current: ::[B] = this
- while (true) in.readObject match {
- case ListSerializeEnd =>
- current.tl = Nil
- return
- case a : Any =>
- val list : ::[B] = new ::(a.asInstanceOf[B], Nil)
- current.tl = list
- current = list
- }
- }
}
/** $factoryInfo
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index c92c0268b6..7537558f0b 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -286,18 +286,36 @@ extends collection.AbstractSeq[Int]
object Range {
private[immutable] val MAX_PRINT = 512 // some arbitrary value
- /** Counts in "Long arithmetic" so we can recognize overflow.
+ /** Counts the number of range elements.
+ * @pre step != 0
+ * If the size of the range exceeds Int.MaxValue, the
+ * result will be negative.
*/
- def count(start: Int, end: Int, step: Int): Int =
- count(start, end, step, false)
-
def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = {
- // faster path for the common counting range
- if (start >= 0 && end > start && end < scala.Int.MaxValue && step == 1)
- (end - start) + ( if (isInclusive) 1 else 0 )
- else
- NumericRange.count[Long](start, end, step, isInclusive)
+ if (step == 0)
+ throw new IllegalArgumentException("step cannot be 0.")
+
+ val isEmpty = (
+ if (start == end) !isInclusive
+ else if (start < end) step < 0
+ else step > 0
+ )
+ if (isEmpty) 0
+ else {
+ // Counts with Longs so we can recognize too-large ranges.
+ val gap: Long = end.toLong - start.toLong
+ val jumps: Long = gap / step
+ // Whether the size of this range is one larger than the
+ // number of full-sized jumps.
+ val hasStub = isInclusive || (gap % step != 0)
+ val result: Long = jumps + ( if (hasStub) 1 else 0 )
+
+ if (result > scala.Int.MaxValue) -1
+ else result.toInt
+ }
}
+ def count(start: Int, end: Int, step: Int): Int =
+ count(start, end, step, false)
class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) {
// override def par = new ParRange(this)
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index e6587f9615..2eb2f8eb09 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -929,13 +929,19 @@ self =>
/** A specialized, extra-lazy implementation of a stream iterator, so it can
* iterate as lazily as it traverses the tail.
*/
-final class StreamIterator[+A](self: Stream[A]) extends AbstractIterator[A] with Iterator[A] {
+final class StreamIterator[+A] private() extends AbstractIterator[A] with Iterator[A] {
+ def this(self: Stream[A]) {
+ this()
+ these = new LazyCell(self)
+ }
+
// A call-by-need cell.
class LazyCell(st: => Stream[A]) {
lazy val v = st
}
- private var these = new LazyCell(self)
+ private var these: LazyCell = _
+
def hasNext: Boolean = these.v.nonEmpty
def next(): A =
if (isEmpty) Iterator.empty.next
diff --git a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
index 5e1325fef6..471e977134 100644
--- a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
+++ b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
@@ -48,7 +48,7 @@ trait TraversableOnceMethods[+A] {
// conversions
def toArray[B >: A : ClassManifest]: Array[B]
def toBuffer[B >: A]: mutable.Buffer[B]
- def toIndexedSeq[B >: A]: immutable.IndexedSeq[B]
+ def toIndexedSeq: immutable.IndexedSeq[A]
def toIterable: Iterable[A]
def toIterator: Iterator[A]
def toList: List[A]
diff --git a/src/library/scala/collection/mutable/AVLTree.scala b/src/library/scala/collection/mutable/AVLTree.scala
new file mode 100644
index 0000000000..0cf6cb06e5
--- /dev/null
+++ b/src/library/scala/collection/mutable/AVLTree.scala
@@ -0,0 +1,206 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package mutable
+
+import annotation.tailrec
+
+/**
+ * An immutable AVL Tree implementation used by mutable.TreeSet
+ *
+ * @author Lucien Pereira
+ *
+ */
+private[mutable] sealed trait AVLTree[+A] extends Serializable {
+ def balance: Int
+
+ def depth: Int
+
+}
+
+private case class Node[A](val data: A, val left: AVLTree[A], val right: AVLTree[A]) extends AVLTree[A] {
+ override val balance: Int = right.depth - left.depth
+
+ override val depth: Int = math.max(left.depth, right.depth) + 1
+
+}
+
+private case object Leaf extends AVLTree[Nothing] {
+ override val balance: Int = 0
+
+ override val depth: Int = -1
+
+}
+
+private[mutable] object AVLTree {
+
+ /**
+ * Returns a new tree containing the given element.
+ * Thows an IllegalArgumentException if element is already present.
+ *
+ */
+ def insert[A](value: A, tree: AVLTree[A], ordering: Ordering[A]): AVLTree[A] = {
+ @tailrec
+ def insertTC(value: A, tree: AVLTree[A], reassemble: AVLTree[A] => AVLTree[A]): AVLTree[A] = tree match {
+ case Leaf => reassemble(Node(value, Leaf, Leaf))
+
+ case Node(a, left, right) => if (0 == ordering.compare(value, a)) {
+ throw new IllegalArgumentException()
+ } else if (-1 == ordering.compare(value, a)) {
+ insertTC(value, left, x => reassemble(rebalance(Node(a, x, right))))
+ } else {
+ insertTC(value, right, x => reassemble(rebalance(Node(a, left, x))))
+ }
+ }
+
+ insertTC(value, tree, x => rebalance(x))
+ }
+
+ def contains[A](value: A, tree: AVLTree[A], ordering: Ordering[A]): Boolean = tree match {
+ case Leaf => false
+
+ case Node(a, left, right) => if (0 == ordering.compare(value, a)) {
+ true
+ } else if (-1 == ordering.compare(value, a)) {
+ contains(value, left, ordering)
+ } else {
+ contains(value, right, ordering)
+ }
+ }
+
+ /**
+ * Return a new tree which not contains given element.
+ *
+ */
+ def remove[A](value: A, tree: AVLTree[A], ordering: Ordering[A]): AVLTree[A] = tree match {
+ case Leaf => throw new NoSuchElementException()
+
+ case Node(a, Leaf, Leaf) => if (0 == ordering.compare(value, a)) {
+ Leaf
+ } else {
+ throw new NoSuchElementException()
+ }
+
+ case Node(a, left, right@Node(_, _, _)) => if (0 == ordering.compare(value, a)) {
+ val (min, newRight) = removeMin(right)
+ rebalance(Node(min, left, newRight))
+ } else if (-1 == ordering.compare(value, a)) {
+ rebalance(Node(a, remove(value, left, ordering), right))
+ } else {
+ rebalance(Node(a, left, remove(value, right, ordering)))
+ }
+
+ case Node(a, left@Node(_, _, _), right) => if (0 == ordering.compare(value, a)) {
+ val (max, newLeft) = removeMax(left)
+ rebalance(Node(max, newLeft, right))
+ } else if (-1 == ordering.compare(value, a)) {
+ rebalance(Node(a, remove(value, left, ordering), right))
+ } else {
+ rebalance(Node(a, left, remove(value, right, ordering)))
+ }
+ }
+
+ /**
+ * Return a tuple containing the biggest element of the provided tree
+ * and a new tree from which this element has been extracted.
+ *
+ */
+ def removeMax[A](tree: Node[A]): (A, AVLTree[A]) = {
+ @tailrec
+ def removeMaxTC(tree: AVLTree[A], assemble: (A, AVLTree[A]) => (A, AVLTree[A])): (A, AVLTree[A]) = tree match {
+ case Node(a, Leaf, Leaf) => assemble(a, Leaf)
+ case Node(a, left, Leaf) => assemble(a, left)
+ case Node(a, left, right) => removeMaxTC(right,
+ (max: A, avl: AVLTree[A]) => assemble(max, rebalance(Node(a, left, avl))))
+ case Leaf => sys.error("Should not happen.")
+ }
+
+ removeMaxTC(tree, (a, b) => (a, b))
+ }
+
+ /**
+ * Return a tuple containing the smallest element of the provided tree
+ * and a new tree from which this element has been extracted.
+ *
+ */
+ def removeMin[A](tree: Node[A]): (A, AVLTree[A]) = {
+ @tailrec
+ def removeMinTC(tree: AVLTree[A], assemble: (A, AVLTree[A]) => (A, AVLTree[A])): (A, AVLTree[A]) = tree match {
+ case Node(a, Leaf, Leaf) => assemble(a, Leaf)
+ case Node(a, Leaf, right) => assemble(a, right)
+ case Node(a, left, right) => removeMinTC(left,
+ (min: A, avl: AVLTree[A]) => assemble(min, rebalance(Node(a, avl, right))))
+ case Leaf => sys.error("Should not happen.")
+ }
+
+ removeMinTC(tree, (a, b) => (a, b))
+ }
+
+ /**
+ * Returns a bounded stream of elements in the tree.
+ *
+ */
+ def toStream[A](tree: AVLTree[A], isLeftAcceptable: A => Boolean, isRightAcceptable: A => Boolean): Stream[A] = tree match {
+ case Leaf => Stream.empty
+
+ case Node(a, left, right) => if (isLeftAcceptable(a)) {
+ if (isRightAcceptable(a)) {
+ toStream(left, isLeftAcceptable, isRightAcceptable) ++ Stream(a) ++ toStream(right, isLeftAcceptable, isRightAcceptable)
+ } else {
+ toStream(left, isLeftAcceptable, isRightAcceptable)
+ }
+ } else if (isRightAcceptable(a)) {
+ toStream(right, isLeftAcceptable, isRightAcceptable)
+ } else {
+ Stream.empty
+ }
+ }
+
+ /**
+ * Returns a bounded iterator of elements in the tree.
+ *
+ */
+ def iterator[A](tree: AVLTree[A], isLeftAcceptable: A => Boolean, isRightAcceptable: A => Boolean): Iterator[A] =
+ toStream(tree, isLeftAcceptable, isRightAcceptable).iterator
+
+ def rebalance[A](tree: AVLTree[A]): AVLTree[A] = (tree, tree.balance) match {
+ case (node@Node(_, left, _), -2) => left.balance match {
+ case 1 => doubleRightRotation(node)
+ case _ => rightRotation(node)
+ }
+
+ case (node@Node(_, _, right), 2) => right.balance match {
+ case -1 => doubleLeftRotation(node)
+ case _ => leftRotation(node)
+ }
+
+ case _ => tree
+ }
+
+ def leftRotation[A](tree: Node[A]): AVLTree[A] = tree.right match {
+ case Node(b, left, right) => Node(b, Node(tree.data, tree.left, left), right)
+ case _ => sys.error("Should not happen.")
+ }
+
+ def rightRotation[A](tree: Node[A]): AVLTree[A] = tree.left match {
+ case Node(b, left, right) => Node(b, left, Node(tree.data, right, tree.right))
+ case _ => sys.error("Should not happen.")
+ }
+
+ def doubleLeftRotation[A](tree: Node[A]): AVLTree[A] = tree.right match {
+ case right@Node(b, l, r) => leftRotation(Node(tree.data, tree.left, rightRotation(right)))
+ case _ => sys.error("Should not happen.")
+ }
+
+ def doubleRightRotation[A](tree: Node[A]): AVLTree[A] = tree.left match {
+ case left@Node(b, l, r) => rightRotation(Node(tree.data, leftRotation(left), tree.right))
+ case _ => sys.error("Should not happen.")
+ }
+
+}
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index 131cdd0005..eb871135df 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -13,6 +13,7 @@ package mutable
import generic._
import immutable.{List, Nil, ::}
+import java.io._
/** A `Buffer` implementation back up by a list. It provides constant time
* prepend and append. Most other operations are linear.
@@ -53,6 +54,7 @@ final class ListBuffer[A]
override def companion: GenericCompanion[ListBuffer] = ListBuffer
import scala.collection.Traversable
+ import scala.collection.immutable.ListSerializeEnd
private var start: List[A] = Nil
private var last0: ::[A] = _
@@ -60,7 +62,49 @@ final class ListBuffer[A]
private var len = 0
protected def underlying: immutable.Seq[A] = start
-
+
+ private def writeObject(out: ObjectOutputStream) {
+ // write start
+ var xs: List[A] = start
+ while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail }
+ out.writeObject(ListSerializeEnd)
+
+ // no need to write last0
+
+ // write if exported
+ out.writeBoolean(exported)
+
+ // write the length
+ out.writeInt(len)
+ }
+
+ private def readObject(in: ObjectInputStream) {
+ // read start, set last0 appropriately
+ var elem: A = in.readObject.asInstanceOf[A]
+ if (elem == ListSerializeEnd) {
+ start = Nil
+ last0 = null
+ } else {
+ var current = new ::(elem, Nil)
+ start = current
+ elem = in.readObject.asInstanceOf[A]
+ while (elem != ListSerializeEnd) {
+ val list = new ::(elem, Nil)
+ current.tl = list
+ current = list
+ elem = in.readObject.asInstanceOf[A]
+ }
+ last0 = current
+ start
+ }
+
+ // read if exported
+ exported = in.readBoolean()
+
+ // read the length
+ len = in.readInt()
+ }
+
/** The current length of the buffer.
*
* This operation takes constant time.
diff --git a/src/library/scala/collection/mutable/SortedSet.scala b/src/library/scala/collection/mutable/SortedSet.scala
new file mode 100644
index 0000000000..d87fc0b4a2
--- /dev/null
+++ b/src/library/scala/collection/mutable/SortedSet.scala
@@ -0,0 +1,49 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package mutable
+
+import generic._
+
+/**
+ * Base trait for mutable sorted set.
+ *
+ * @define Coll mutable.SortedSet
+ * @define coll mutable sorted set
+ *
+ * @author Lucien Pereira
+ *
+ */
+trait SortedSet[A] extends collection.SortedSet[A] with collection.SortedSetLike[A,SortedSet[A]]
+ with mutable.Set[A] with mutable.SetLike[A, SortedSet[A]] {
+
+ /** Needs to be overridden in subclasses. */
+ override def empty: SortedSet[A] = SortedSet.empty[A]
+
+}
+
+/**
+ * A template for mutable sorted set companion objects.
+ *
+ * @define Coll mutable.SortedSet
+ * @define coll mutable sorted set
+ * @define factoryInfo
+ * This object provides a set of operations needed to create sorted sets of type mutable.SortedSet.
+ * @define sortedSetCanBuildFromInfo
+ * Standard `CanBuildFrom` instance for sorted sets.
+ *
+ * @author Lucien Pereira
+ *
+ */
+object SortedSet extends MutableSortedSetFactory[SortedSet] {
+ implicit def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, SortedSet[A]] = new SortedSetCanBuildFrom[A]
+
+ def empty[A](implicit ord: Ordering[A]): SortedSet[A] = TreeSet.empty[A]
+
+}
diff --git a/src/library/scala/collection/mutable/TreeSet.scala b/src/library/scala/collection/mutable/TreeSet.scala
new file mode 100644
index 0000000000..38fa0c953f
--- /dev/null
+++ b/src/library/scala/collection/mutable/TreeSet.scala
@@ -0,0 +1,123 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package mutable
+
+import generic._
+
+/**
+ * @define Coll mutable.TreeSet
+ * @define coll mutable tree set
+ * @factoryInfo
+ * Companion object of TreeSet providing factory related utilities.
+ *
+ * @author Lucien Pereira
+ *
+ */
+object TreeSet extends MutableSortedSetFactory[TreeSet] {
+ /**
+ * The empty set of this type
+ */
+ def empty[A](implicit ordering: Ordering[A]) = new TreeSet[A]()
+
+}
+
+/**
+ * A mutable SortedSet using an immutable AVL Tree as underlying data structure.
+ *
+ * @author Lucien Pereira
+ *
+ */
+class TreeSet[A](implicit val ordering: Ordering[A]) extends SortedSet[A] with SetLike[A, TreeSet[A]]
+ with SortedSetLike[A, TreeSet[A]] with Set[A] with Serializable {
+
+ // Projection constructor
+ private def this(base: Option[TreeSet[A]], from: Option[A], until: Option[A])(implicit ordering: Ordering[A]) {
+ this();
+ this.base = base
+ this.from = from
+ this.until = until
+ }
+
+ private var base: Option[TreeSet[A]] = None
+
+ private var from: Option[A] = None
+
+ private var until: Option[A] = None
+
+ private var avl: AVLTree[A] = Leaf
+
+ private var cardinality: Int = 0
+
+ def resolve: TreeSet[A] = base.getOrElse(this)
+
+ private def isLeftAcceptable(from: Option[A], ordering: Ordering[A])(a: A): Boolean =
+ from.map(x => ordering.gteq(a, x)).getOrElse(true)
+
+ private def isRightAcceptable(until: Option[A], ordering: Ordering[A])(a: A): Boolean =
+ until.map(x => ordering.lt(a, x)).getOrElse(true)
+
+ /**
+ * Cardinality store the set size, unfortunately a
+ * set view (given by rangeImpl)
+ * cannot take advantage of this optimisation
+ *
+ */
+ override def size: Int = base.map(_ => super.size).getOrElse(cardinality)
+
+ override def stringPrefix = "TreeSet"
+
+ override def empty: TreeSet[A] = TreeSet.empty
+
+ override def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] = new TreeSet(Some(this), from, until)
+
+ override def -=(elem: A): this.type = {
+ try {
+ resolve.avl = AVLTree.remove(elem, resolve.avl, ordering)
+ resolve.cardinality = resolve.cardinality - 1
+ } catch {
+ case e: NoSuchElementException => ()
+ }
+ this
+ }
+
+ override def +=(elem: A): this.type = {
+ try {
+ resolve.avl = AVLTree.insert(elem, resolve.avl, ordering)
+ resolve.cardinality = resolve.cardinality + 1
+ } catch {
+ case e: IllegalArgumentException => ()
+ }
+ this
+ }
+
+ /**
+ * Thanks to the nature immutable of the
+ * underlying AVL Tree, we can share it with
+ * the clone. So clone complexity in time is O(1).
+ *
+ */
+ override def clone: TreeSet[A] = {
+ val clone = new TreeSet[A](base, from, until)
+ clone.avl = resolve.avl
+ clone.cardinality = resolve.cardinality
+ clone
+ }
+
+ override def contains(elem: A): Boolean = {
+ isLeftAcceptable(from, ordering)(elem) &&
+ isRightAcceptable(until, ordering)(elem) &&
+ AVLTree.contains(elem, resolve.avl, ordering)
+ }
+
+ override def iterator: Iterator[A] =
+ AVLTree.iterator(resolve.avl,
+ isLeftAcceptable(from, ordering),
+ isRightAcceptable(until, ordering))
+}
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index f0d79ada9d..90b64c17f9 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -801,7 +801,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
override def toList: List[T] = seq.toList
- override def toIndexedSeq[U >: T]: collection.immutable.IndexedSeq[U] = seq.toIndexedSeq[U]
+ override def toIndexedSeq: collection.immutable.IndexedSeq[T] = seq.toIndexedSeq
override def toStream: Stream[T] = seq.toStream
diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala
index 1a27df1c10..d9cef0edb1 100644
--- a/src/library/scala/io/Codec.scala
+++ b/src/library/scala/io/Codec.scala
@@ -38,6 +38,9 @@ class Codec(val charSet: Charset) {
private[this] var _decodingReplacement: String = null
private[this] var _onCodingException: Handler = e => throw e
+ /** The name of the Codec. */
+ override def toString = name
+
// these methods can be chained to configure the variables above
def onMalformedInput(newAction: Action): this.type = { _onMalformedInput = newAction ; this }
def onUnmappableCharacter(newAction: Action): this.type = { _onUnmappableCharacter = newAction ; this }
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index be08409636..8bd45c0e33 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -60,7 +60,7 @@ trait Manifest[T] extends ClassManifest[T] with Equals {
override def hashCode = this.erasure.##
}
-sealed abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals {
+abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals {
override def <:<(that: ClassManifest[_]): Boolean =
(that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal)
override def canEqual(other: Any) = other match {
diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala
index b63a8645de..dfadfb4976 100644
--- a/src/library/scala/reflect/ReflectionUtils.scala
+++ b/src/library/scala/reflect/ReflectionUtils.scala
@@ -27,11 +27,15 @@ object ReflectionUtils {
case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex))
}
- // Retrieves the MODULE$ field for the given class name.
- def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): Option[AnyRef] = {
+ def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): AnyRef = {
val name = if (className endsWith "$") className else className + "$"
+ val clazz = java.lang.Class.forName(name, true, cl)
+ val singleton = clazz getField "MODULE$" get null
+ singleton
+ }
- try Some(java.lang.Class.forName(name, true, cl) getField "MODULE$" get null)
+ // Retrieves the MODULE$ field for the given class name.
+ def singletonInstanceOpt(className: String, cl: ClassLoader = getClass.getClassLoader): Option[AnyRef] =
+ try Some(singletonInstance(className, cl))
catch { case _: ClassNotFoundException => None }
- }
}
diff --git a/src/library/scala/reflect/api/Mirror.scala b/src/library/scala/reflect/api/Mirror.scala
index 53ac84f8cb..136f52b05f 100644
--- a/src/library/scala/reflect/api/Mirror.scala
+++ b/src/library/scala/reflect/api/Mirror.scala
@@ -13,7 +13,11 @@ trait Mirror extends Universe with RuntimeTypes with TreeBuildUtil {
* to do: throws anything else?
*/
def classWithName(name: String): Symbol
-
+
+ /** Return a reference to the companion object of this class symbol
+ */
+ def getCompanionObject(clazz: Symbol): AnyRef
+
/** The Scala class symbol corresponding to the runtime class of given object
* @param The object from which the class is returned
* @throws ?
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index 31bcdebe7e..8b4b170847 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -150,10 +150,10 @@ trait Symbols { self: Universe =>
*/
def asTypeIn(site: Type): Type
- /** A fresh symbol with given position `pos` and name `name` that has
+ /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
* the current symbol as its owner.
*/
- def newNestedSymbol(pos: Position, name: Name): Symbol // needed by LiftCode
+ def newNestedSymbol(name: Name, pos: Position, flags: Long): Symbol // needed by LiftCode
/** Low-level operation to set the symbol's flags
* @return the symbol itself
diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala
index 15fba0e418..88ef450ed9 100644
--- a/src/library/scala/reflect/api/TreePrinters.scala
+++ b/src/library/scala/reflect/api/TreePrinters.scala
@@ -28,7 +28,21 @@ trait TreePrinters { self: Universe =>
*/
def newTreePrinter(out: PrintWriter): TreePrinter
+ // emits more or less verbatim representation of the provided tree
+ // todo. when LiftCode becomes a macro, throw this code away and use that macro
class RawTreePrinter(out: PrintWriter) extends TreePrinter {
+ import scala.reflect.api.Modifier
+ import scala.reflect.api.Modifier._
+
+ def copypasteModifier(mod: Modifier.Value): String = mod match {
+ case mod @ (
+ `protected` | `private` | `override` |
+ `abstract` | `final` | `sealed` |
+ `implicit` | `lazy` | `macro` |
+ `case` | `trait`) => "`" + mod.toString + "`"
+ case mod => mod.toString
+ }
+
def print(args: Any*): Unit = args foreach {
case EmptyTree =>
print("EmptyTree")
@@ -48,10 +62,35 @@ trait TreePrinters { self: Universe =>
case arg =>
print(arg)
}
- print(if (it.hasNext) ", " else ")")
+ print(if (it.hasNext) ", " else "")
}
+ print(")")
if (typesPrinted)
print(".setType(", tree.tpe, ")")
+ case list: List[_] =>
+ print("List(")
+ val it = list.iterator
+ while (it.hasNext) {
+ print(it.next())
+ print(if (it.hasNext) ", " else "")
+ }
+ print(")")
+ case mods: Modifiers =>
+ val parts = collection.mutable.ListBuffer[String]()
+ parts += "Set(" + mods.allModifiers.map{copypasteModifier}.mkString(", ") + ")"
+ parts += "newTypeName(\"" + mods.privateWithin.toString + "\")"
+ parts += "List(" + mods.annotations.map{showRaw}.mkString(", ") + ")"
+
+ var keep = 3
+ if (keep == 3 && mods.annotations.isEmpty) keep -= 1
+ if (keep == 2 && mods.privateWithin == EmptyTypeName) keep -= 1
+ if (keep == 1 && mods.allModifiers.isEmpty) keep -= 1
+
+ print("Modifiers(", parts.take(keep).mkString(", "), ")")
+ case name: Name =>
+ if (name.isTermName) print("newTermName(\"") else print("newTypeName(\"")
+ print(name.toString)
+ print("\")")
case arg =>
out.print(arg)
}
diff --git a/src/library/scala/reflect/api/MacroContext.scala b/src/library/scala/reflect/macro/Context.scala
index e23357d26e..d0a2787fdf 100644
--- a/src/library/scala/reflect/api/MacroContext.scala
+++ b/src/library/scala/reflect/macro/Context.scala
@@ -1,7 +1,7 @@
package scala.reflect
-package api
+package macro
-trait MacroContext extends Universe {
+trait Context extends api.Universe {
/** Mark a variable as captured; i.e. force boxing in a *Ref type.
*/
@@ -12,4 +12,4 @@ trait MacroContext extends Universe {
*/
def referenceCapturedVariable(id: Ident): Tree
-} \ No newline at end of file
+}
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index 62592baa27..1c3e618520 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -8,7 +8,7 @@ package object reflect {
// initialization, but in response to a doomed attempt to utilize it.
lazy val mirror: api.Mirror = {
// we use (Java) reflection here so that we can keep reflect.runtime and reflect.internals in a seperate jar
- ReflectionUtils.singletonInstance("scala.reflect.runtime.Mirror") collect { case x: api.Mirror => x } getOrElse {
+ ReflectionUtils.singletonInstanceOpt("scala.reflect.runtime.Mirror") collect { case x: api.Mirror => x } getOrElse {
throw new UnsupportedOperationException("Scala reflection not available on this platform")
}
}
diff --git a/src/library/scala/xml/include/sax/Main.scala b/src/library/scala/xml/include/sax/Main.scala
index 6b6f6c1593..f58097bcb9 100644
--- a/src/library/scala/xml/include/sax/Main.scala
+++ b/src/library/scala/xml/include/sax/Main.scala
@@ -10,11 +10,11 @@
package scala.xml
package include.sax
-import scala.xml.include._
import scala.util.control.Exception.{ catching, ignoring }
import org.xml.sax.XMLReader
import org.xml.sax.helpers.XMLReaderFactory
+@deprecated("Code example will be moved to documentation.", "2.10.0")
object Main {
private val namespacePrefixes = "http://xml.org/sax/features/namespace-prefixes"
private val lexicalHandler = "http://xml.org/sax/properties/lexical-handler"
diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala
index a08100a33f..a90a61a9aa 100644
--- a/src/partest/scala/tools/partest/PartestTask.scala
+++ b/src/partest/scala/tools/partest/PartestTask.scala
@@ -281,6 +281,26 @@ class PartestTask extends Task with CompilationPathProperty {
}
} getOrElse sys.error("Provided classpath does not contain a Scala library.")
+ val scalaCompiler = {
+ (classpath.list map { fs => new File(fs) }) find { f =>
+ f.getName match {
+ case "scala-compiler.jar" => true
+ case "compiler" if (f.getParentFile.getName == "classes") => true
+ case _ => false
+ }
+ }
+ } getOrElse sys.error("Provided classpath does not contain a Scala compiler.")
+
+ val scalaPartest = {
+ (classpath.list map { fs => new File(fs) }) find { f =>
+ f.getName match {
+ case "scala-partest.jar" => true
+ case "partest" if (f.getParentFile.getName == "classes") => true
+ case _ => false
+ }
+ }
+ } getOrElse sys.error("Provided classpath does not contain a Scala partest.")
+
def scalacArgsFlat: Option[Seq[String]] = scalacArgs map (_ flatMap { a =>
val parts = a.getParts
if(parts eq null) Seq[String]() else parts.toSeq
@@ -294,6 +314,8 @@ class PartestTask extends Task with CompilationPathProperty {
antFileManager.failed = runFailed
antFileManager.CLASSPATH = ClassPath.join(classpath.list: _*)
antFileManager.LATEST_LIB = scalaLibrary.getAbsolutePath
+ antFileManager.LATEST_COMP = scalaCompiler.getAbsolutePath
+ antFileManager.LATEST_PARTEST = scalaPartest.getAbsolutePath
javacmd foreach (x => antFileManager.JAVACMD = x.getAbsolutePath)
javaccmd foreach (x => antFileManager.JAVAC_CMD = x.getAbsolutePath)
@@ -361,18 +383,18 @@ class PartestTask extends Task with CompilationPathProperty {
private def oneResult(res: (String, Int)) =
<testcase name={res._1}>{
- res._2 match {
- case 0 => scala.xml.NodeSeq.Empty
+ res._2 match {
+ case 0 => scala.xml.NodeSeq.Empty
case 1 => <failure message="Test failed"/>
case 2 => <failure message="Test timed out"/>
- }
- }</testcase>
+ }
+ }</testcase>
private def testReport(kind: String, results: Iterable[(String, Int)], succs: Int, fails: Int) =
<testsuite name={kind} tests={(succs + fails).toString} failures={fails.toString}>
- <properties/>
- {
- results.map(oneResult(_))
- }
+ <properties/>
+ {
+ results.map(oneResult(_))
+ }
</testsuite>
}
diff --git a/src/partest/scala/tools/partest/nest/AntRunner.scala b/src/partest/scala/tools/partest/nest/AntRunner.scala
index 002e454b7b..4795e5551a 100644
--- a/src/partest/scala/tools/partest/nest/AntRunner.scala
+++ b/src/partest/scala/tools/partest/nest/AntRunner.scala
@@ -20,6 +20,8 @@ class AntRunner extends DirectRunner {
var JAVAC_CMD: String = "javac"
var CLASSPATH: String = _
var LATEST_LIB: String = _
+ var LATEST_COMP: String = _
+ var LATEST_PARTEST: String = _
val testRootPath: String = "test"
val testRootDir: Directory = Directory(testRootPath)
}
diff --git a/src/partest/scala/tools/partest/nest/CompileManager.scala b/src/partest/scala/tools/partest/nest/CompileManager.scala
index 68688ff949..aea6bcc03a 100644
--- a/src/partest/scala/tools/partest/nest/CompileManager.scala
+++ b/src/partest/scala/tools/partest/nest/CompileManager.scala
@@ -111,6 +111,7 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {
try {
NestUI.verbose("compiling "+toCompile)
+ NestUI.verbose("with classpath: "+global.classPath.toString)
try new global.Run compile toCompile
catch {
case FatalError(msg) =>
diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
index b9b371d6cb..3d72227b04 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
@@ -157,9 +157,13 @@ class ConsoleFileManager extends FileManager {
}
LATEST_LIB = latestLibFile.getAbsolutePath
+ LATEST_COMP = latestCompFile.getAbsolutePath
+ LATEST_PARTEST = latestPartestFile.getAbsolutePath
}
var LATEST_LIB: String = ""
+ var LATEST_COMP: String = ""
+ var LATEST_PARTEST: String = ""
var latestFile: File = _
var latestLibFile: File = _
diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala
index 78184664c2..d3d50ca58c 100644
--- a/src/partest/scala/tools/partest/nest/DirectRunner.scala
+++ b/src/partest/scala/tools/partest/nest/DirectRunner.scala
@@ -52,8 +52,15 @@ trait DirectRunner {
val kindFiles = onlyValidTestPaths(_kindFiles)
val groupSize = (kindFiles.length / numActors) + 1
- val consFM = new ConsoleFileManager
- import consFM.{ latestCompFile, latestLibFile, latestPartestFile }
+ // @partest maintainer: we cannot create a fresh file manager here
+ // since the FM must respect --buildpath and --classpath from the command line
+ // for example, see how it's done in ReflectiveRunner
+ //val consFM = new ConsoleFileManager
+ //import consFM.{ latestCompFile, latestLibFile, latestPartestFile }
+ val latestCompFile = new File(fileManager.LATEST_COMP);
+ val latestLibFile = new File(fileManager.LATEST_LIB);
+ val latestPartestFile = new File(fileManager.LATEST_PARTEST);
+
val scalacheckURL = PathSettings.scalaCheck.toURL
val scalaCheckParentClassLoader = ScalaClassLoader.fromURLs(
List(scalacheckURL, latestCompFile.toURI.toURL, latestLibFile.toURI.toURL, latestPartestFile.toURI.toURL)
diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala
index 780f7a35e5..a4a94fe93e 100644
--- a/src/partest/scala/tools/partest/nest/FileManager.scala
+++ b/src/partest/scala/tools/partest/nest/FileManager.scala
@@ -60,6 +60,8 @@ trait FileManager extends FileUtil {
var CLASSPATH: String
var LATEST_LIB: String
+ var LATEST_COMP: String
+ var LATEST_PARTEST: String
var showDiff = false
var updateCheck = false
diff --git a/src/partest/scala/tools/partest/nest/PathSettings.scala b/src/partest/scala/tools/partest/nest/PathSettings.scala
index f6353faa6f..04f36ffa11 100644
--- a/src/partest/scala/tools/partest/nest/PathSettings.scala
+++ b/src/partest/scala/tools/partest/nest/PathSettings.scala
@@ -16,6 +16,9 @@ object PathSettings {
private def cwd = Directory.Current getOrElse sys.error("user.dir property not set")
private def isPartestDir(d: Directory) = (d.name == "test") && (d / srcDirName isDirectory)
+ private def findJar(d: Directory, name: String): Option[File] = findJar(d.files, name)
+ private def findJar(files: Iterator[File], name: String): Option[File] =
+ files filter (_ hasExtension "jar") find { _.name startsWith name }
// Directory <root>/test
lazy val testRoot: Directory = testRootDir getOrElse {
@@ -33,7 +36,7 @@ object PathSettings {
// Directory <root>/test/files/speclib
lazy val srcSpecLibDir = Directory(srcDir / "speclib")
- lazy val srcSpecLib: File = srcSpecLibDir.files find (_.name startsWith "instrumented") getOrElse {
+ lazy val srcSpecLib: File = findJar(srcSpecLibDir, "instrumented") getOrElse {
sys.error("No instrumented.jar found in %s".format(srcSpecLibDir))
}
@@ -51,7 +54,7 @@ object PathSettings {
lazy val buildPackLibDir = Directory(buildDir / "pack" / "lib")
lazy val scalaCheck: File =
- buildPackLibDir.files ++ srcLibDir.files find (_.name startsWith "scalacheck") getOrElse {
+ findJar(buildPackLibDir.files ++ srcLibDir.files, "scalacheck") getOrElse {
sys.error("No scalacheck jar found in '%s' or '%s'".format(buildPackLibDir, srcLibDir))
}
}
diff --git a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
index f39debf31d..7c6dd0848f 100644
--- a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
+++ b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
@@ -58,10 +58,17 @@ class ReflectiveRunner {
if (isPartestDebug)
println("Loading classes from:\n" + sepUrls.mkString("\n"))
- val paths = classPath match {
- case Some(cp) => Nil
- case _ => files.toList map (_.path)
- }
+ // @partest maintainer: it seems to me that commented lines are incorrect
+ // if classPath is not empty, then it has been provided by the --classpath option
+ // which points to the root of Scala home (see ConsoleFileManager's testClasses and the true flag in the ctor for more information)
+ // this doesn't mean that we had custom Java classpath set, so we don't have to override latestXXXFiles from the file manager
+ //
+ //val paths = classPath match {
+ // case Some(cp) => Nil
+ // case _ => files.toList map (_.path)
+ //}
+ val paths = files.toList map (_.path)
+
val newClasspath = ClassPath.join(paths: _*)
setProp("java.class.path", newClasspath)
diff --git a/src/partest/scala/tools/partest/nest/SBTRunner.scala b/src/partest/scala/tools/partest/nest/SBTRunner.scala
index ae54e51761..4c6f417df5 100644
--- a/src/partest/scala/tools/partest/nest/SBTRunner.scala
+++ b/src/partest/scala/tools/partest/nest/SBTRunner.scala
@@ -7,16 +7,18 @@ import scala.util.Properties.setProp
object SBTRunner extends DirectRunner {
-
+
val fileManager = new FileManager {
var JAVACMD: String = "java"
var JAVAC_CMD: String = "javac"
var CLASSPATH: String = _
var LATEST_LIB: String = _
+ var LATEST_COMP: String = _
+ var LATEST_PARTEST: String = _
val testRootPath: String = "test"
val testRootDir: Directory = Directory(testRootPath)
}
-
+
def reflectiveRunTestsForFiles(kindFiles: Array[File], kind: String):java.util.HashMap[String,Int] = {
def convert(scalaM:scala.collection.immutable.Map[String,Int]):java.util.HashMap[String,Int] = {
val javaM = new java.util.HashMap[String,Int]()
@@ -25,9 +27,9 @@ object SBTRunner extends DirectRunner {
}
def failedOnlyIfRequired(files:List[File]):List[File]={
- if (fileManager.failed) files filter (x => fileManager.logFileExists(x, kind)) else files
+ if (fileManager.failed) files filter (x => fileManager.logFileExists(x, kind)) else files
}
- convert(runTestsForFiles(failedOnlyIfRequired(kindFiles.toList), kind))
+ convert(runTestsForFiles(failedOnlyIfRequired(kindFiles.toList), kind))
}
case class CommandLineOptions(classpath: Option[String] = None,
@@ -38,7 +40,7 @@ object SBTRunner extends DirectRunner {
def mainReflect(args: Array[String]): java.util.Map[String,Int] = {
setProp("partest.debug", "true")
setProperties()
-
+
val Argument = new scala.util.matching.Regex("-(.*)")
def parseArgs(args: Seq[String], data: CommandLineOptions): CommandLineOptions = args match {
case Seq("--failed", rest @ _*) => parseArgs(rest, data.copy(justFailedTests = true))
@@ -50,10 +52,14 @@ object SBTRunner extends DirectRunner {
}
val config = parseArgs(args, CommandLineOptions())
fileManager.SCALAC_OPTS = config.scalacOptions
- fileManager.CLASSPATH = config.classpath getOrElse error("No classpath set")
+ fileManager.CLASSPATH = config.classpath getOrElse sys.error("No classpath set")
// Find scala library jar file...
val lib: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-library.*\\.jar")).headOption
- fileManager.LATEST_LIB = lib getOrElse error("No scala-library found! Classpath = " + fileManager.CLASSPATH)
+ fileManager.LATEST_LIB = lib getOrElse sys.error("No scala-library found! Classpath = " + fileManager.CLASSPATH)
+ val comp: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-compiler.*\\.jar")).headOption
+ fileManager.LATEST_COMP = comp getOrElse sys.error("No scala-compiler found! Classpath = " + fileManager.CLASSPATH)
+ val partest: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-partest.*\\.jar")).headOption
+ fileManager.LATEST_PARTEST = partest getOrElse sys.error("No scala-partest found! Classpath = " + fileManager.CLASSPATH)
// TODO - Do something useful here!!!
fileManager.JAVAC_CMD = "javac"
fileManager.failed = config.justFailedTests
@@ -63,7 +69,7 @@ object SBTRunner extends DirectRunner {
val runs = config.tests.filterNot(_._2.isEmpty)
// This next bit uses java maps...
import collection.JavaConverters._
- (for {
+ (for {
(testType, files) <- runs
(path, result) <- reflectiveRunTestsForFiles(files,testType).asScala
} yield (path, result)).seq asJava
@@ -71,14 +77,12 @@ object SBTRunner extends DirectRunner {
def main(args: Array[String]): Unit = {
import collection.JavaConverters._
- val failures = for {
- (path, result) <- mainReflect(args).asScala
- if result == 1 || result == 2
- val resultName = (if(result == 1) " [FAILED]" else " [TIMEOUT]")
- } yield path + resultName
+ val failures = (
+ for ((path, result) <- mainReflect(args).asScala ; if result == 1 || result == 2) yield
+ path + ( if (result == 1) " [FAILED]" else " [TIMEOUT]" )
+ )
// Re-list all failures so we can go figure out what went wrong.
failures foreach System.err.println
if(!failures.isEmpty) sys.exit(1)
}
}
-
diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala
index 9c61097cb0..3e5fe35f9e 100644
--- a/src/partest/scala/tools/partest/nest/TestFile.scala
+++ b/src/partest/scala/tools/partest/nest/TestFile.scala
@@ -12,6 +12,7 @@ import java.io.{ File => JFile }
import scala.tools.nsc.Settings
import scala.tools.nsc.util.ClassPath
import scala.tools.nsc.io._
+import scala.util.Properties.{ propIsSet, propOrElse, setProp }
trait TestFileCommon {
def file: JFile
@@ -61,6 +62,10 @@ case class SpecializedTestFile(file: JFile, fileManager: FileManager) extends Te
super.defineSettings(settings, setOutDir) && {
// add the instrumented library version to classpath
settings.classpath prepend PathSettings.srcSpecLib.toString
+ // @partest maintainer: if we use a custom Scala build (specified via --classpath)
+ // then the classes provided by it will come earlier than instrumented.jar in the resulting classpath
+ // this entire classpath business needs a thorough solution
+ if (propIsSet("java.class.path")) setProp("java.class.path", PathSettings.srcSpecLib.toString + ";" + propOrElse("java.class.path", ""))
true
}
}
diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala
index f74182e81c..952d99c318 100644
--- a/src/partest/scala/tools/partest/nest/Worker.scala
+++ b/src/partest/scala/tools/partest/nest/Worker.scala
@@ -53,6 +53,8 @@ class ScalaCheckFileManager(val origmanager: FileManager) extends FileManager {
var CLASSPATH: String = join(origmanager.CLASSPATH, PathSettings.scalaCheck.path)
var LATEST_LIB: String = origmanager.LATEST_LIB
+ var LATEST_COMP: String = origmanager.LATEST_COMP
+ var LATEST_PARTEST: String = origmanager.LATEST_PARTEST
}
object Output {
diff --git a/test/benchmarking/AVL-insert-random.scala b/test/benchmarking/AVL-insert-random.scala
new file mode 100644
index 0000000000..7299e330f5
--- /dev/null
+++ b/test/benchmarking/AVL-insert-random.scala
@@ -0,0 +1,67 @@
+package scala.collection
+
+
+
+
+
+class Dummy(val a: Int) extends math.Ordered[Dummy] {
+ def compare(other: Dummy) = this.a - other.a
+ override def toString = a.toString
+}
+
+
+object RandomGlobal {
+ val sz = 500000
+ val data = util.Random.shuffle((0 until sz) map { new Dummy(_) }) toArray;
+}
+
+
+import RandomGlobal._
+
+
+object RandomAVL extends testing.Benchmark {
+
+ def run() {
+ val avl = new collection.mutable.TreeSet[Dummy]
+
+ var i = 0
+ while (i < sz) {
+ val elem = data(i)
+ avl += elem
+ i += 1
+ }
+ }
+
+}
+
+
+object RandomImmutableTreeSet extends testing.Benchmark {
+
+ def run() {
+ var tree = new collection.immutable.TreeSet[Dummy]
+
+ var i = 0
+ while (i < sz) {
+ val elem = data(i)
+ tree += elem
+ i += 1
+ }
+ }
+
+}
+
+
+object RandomJavaTreeSet extends testing.Benchmark {
+
+ def run() {
+ val tree = new java.util.TreeSet[Dummy]
+
+ var i = 0
+ while (i < sz) {
+ val elem = data(i)
+ tree add elem
+ i += 1
+ }
+ }
+
+}
diff --git a/test/benchmarking/AVL-insert.scala b/test/benchmarking/AVL-insert.scala
new file mode 100644
index 0000000000..4f3ab390c9
--- /dev/null
+++ b/test/benchmarking/AVL-insert.scala
@@ -0,0 +1,67 @@
+package scala.collection
+
+
+
+
+
+class Dummy(val a: Int) extends math.Ordered[Dummy] {
+ def compare(other: Dummy) = this.a - other.a
+ override def toString = a.toString
+}
+
+
+object Global {
+ val sz = 500000
+ val data = (0 until sz) map { new Dummy(_) } toArray
+}
+
+
+import Global._
+
+
+object AVL extends testing.Benchmark {
+
+ def run() {
+ val avl = new collection.mutable.TreeSet[Dummy]
+
+ var i = 0
+ while (i < sz) {
+ val elem = data(i)
+ avl += elem
+ i += 1
+ }
+ }
+
+}
+
+
+object ImmutableTreeSet extends testing.Benchmark {
+
+ def run() {
+ var tree = new collection.immutable.TreeSet[Dummy]
+
+ var i = 0
+ while (i < sz) {
+ val elem = data(i)
+ tree += elem
+ i += 1
+ }
+ }
+
+}
+
+
+object JavaTreeSet extends testing.Benchmark {
+
+ def run() {
+ val tree = new java.util.TreeSet[Dummy]
+
+ var i = 0
+ while (i < sz) {
+ val elem = data(i)
+ tree add elem
+ i += 1
+ }
+ }
+
+}
diff --git a/test/files/continuations-neg/t2949.check b/test/files/continuations-neg/t2949.check
index 411aed1b5b..dd9768807c 100644
--- a/test/files/continuations-neg/t2949.check
+++ b/test/files/continuations-neg/t2949.check
@@ -1,6 +1,6 @@
t2949.scala:13: error: type mismatch;
found : Int
- required: ? @scala.util.continuations.cpsParam[List[?],?]
+ required: ? @scala.util.continuations.cpsParam[List[?],Any]
x * y
^
one error found
diff --git a/test/files/jvm/serialization.check b/test/files/jvm/serialization.check
index 15708f0c3b..f58f763a76 100644
--- a/test/files/jvm/serialization.check
+++ b/test/files/jvm/serialization.check
@@ -188,6 +188,10 @@ x = WrappedArray(1, 2, 3)
y = WrappedArray(1, 2, 3)
x equals y: true, y equals x: true
+x = TreeSet(1, 2, 3)
+y = TreeSet(1, 2, 3)
+x equals y: true, y equals x: true
+
x = xml:src="hello"
y = xml:src="hello"
x equals y: true, y equals x: true
@@ -202,7 +206,7 @@ x equals y: true, y equals x: true
x = <html>
<body>
- <table cellspacing="0" cellpadding="2">
+ <table cellpadding="2" cellspacing="0">
<tr>
<th>Last Name</th>
<th>First Name</th>
@@ -222,7 +226,7 @@ x = <html>
</html>
y = <html>
<body>
- <table cellspacing="0" cellpadding="2">
+ <table cellpadding="2" cellspacing="0">
<tr>
<th>Last Name</th>
<th>First Name</th>
diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala
index 9391b60e46..73bed2d46b 100644
--- a/test/files/jvm/serialization.scala
+++ b/test/files/jvm/serialization.scala
@@ -286,7 +286,7 @@ object Test3_mutable {
import scala.collection.mutable.{
ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList,
HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue,
- Stack, StringBuilder, WrappedArray}
+ Stack, StringBuilder, WrappedArray, TreeSet}
// in alphabetic order
try {
@@ -380,6 +380,11 @@ object Test3_mutable {
val wa1 = WrappedArray.make(Array(1, 2, 3))
val _wa1: WrappedArray[Int] = read(write(wa1))
check(wa1, _wa1)
+
+ // TreeSet
+ val ts1 = TreeSet[Int]() ++= Array(1, 2, 3)
+ val _ts1: TreeSet[Int] = read(write(ts1))
+ check(ts1, _ts1)
}
catch {
case e: Exception =>
diff --git a/test/files/macros/Printf.scala b/test/files/macros/Printf.scala
new file mode 100644
index 0000000000..4a88e5b069
--- /dev/null
+++ b/test/files/macros/Printf.scala
@@ -0,0 +1,39 @@
+// macros should be built separately from their clients, so simple "scalac Printf.scala Test.scala" won't work
+// 1) first build this file with "scalac -Xmacros Printf.scala"
+// 2) the build the test with "scalac -cp <output directory of compiling Printf.scala> Test.scala"
+
+object Printf extends App {
+ def macro printf(format: String, params: Any*) : String = {
+ var i = 0
+ def gensym(name: String) = { i += 1; newTermName(name + i) }
+
+ def createTempValDef(value: Tree, clazz: Class[_]): (Option[Tree], Tree) = {
+ val local = gensym("temp")
+ val tpe = if (clazz == classOf[Int]) Ident(newTypeName("Int"))
+ else if (clazz == classOf[String]) Select(Select(Ident(newTermName("java")), newTermName("lang")), newTypeName("String"))
+ else throw new Exception("unknown class " + clazz.toString)
+ (Some(ValDef(Modifiers(), local, tpe, value)), Ident(local))
+ }
+
+ def tree_printf(format: Tree, params: Tree*) = {
+ val Literal(Constant(s_format: String)) = format
+ val paramsStack = scala.collection.mutable.Stack(params: _*)
+ val parsed = s_format.split("(?<=%[\\w%])|(?=%[\\w%])") map {
+ case "%d" => createTempValDef(paramsStack.pop, classOf[Int])
+ case "%s" => createTempValDef(paramsStack.pop, classOf[String])
+ case "%%" => (None, Literal(Constant("%")))
+ case part => (None, Literal(Constant(part)))
+ }
+
+ val evals = for ((Some(eval), _) <- parsed if eval != None) yield eval
+ val prints = for ((_, ref) <- parsed) yield {
+ val print = Select(Select(Ident(newTermName("scala")), newTermName("Predef")), newTermName("print"))
+ Apply(print, List(ref))
+ }
+
+ Block((evals ++ prints).toList, Literal(Constant(())))
+ }
+
+ tree_printf(format, params: _*)
+ }
+}
diff --git a/test/files/macros/Test.scala b/test/files/macros/Test.scala
new file mode 100644
index 0000000000..d8cdcf6756
--- /dev/null
+++ b/test/files/macros/Test.scala
@@ -0,0 +1,8 @@
+// macros should be built separately from their clients, so simple "scalac Printf.scala Test.scala" won't work
+// 1) first build the printf macro with "scalac -Xmacros Printf.scala"
+// 2) the build this file with "scalac -cp <output directory of compiling Printf.scala> Test.scala"
+
+object Test extends App {
+ import Printf._
+ printf("hello %s", "world")
+} \ No newline at end of file
diff --git a/test/files/macros/macros_v0001.bat b/test/files/macros/macros_v0001.bat
new file mode 100644
index 0000000000..3395d2e3c1
--- /dev/null
+++ b/test/files/macros/macros_v0001.bat
@@ -0,0 +1,40 @@
+@echo off
+
+set scalahome=%~dp0\..\..\..
+set scaladeps=%scalahome%\lib\jline.jar;%scalahome%\lib\fjbg.jar
+set scalalib=%scalahome%\build\pack\lib\scala-library.jar
+if not exist "%scalalib%" set scalalib=%scalahome%\build\locker\classes\library
+set scalacomp="%scalahome%\build\pack\lib\scala-compiler.jar"
+if not exist "%scalacomp%" set scalacomp=%scalahome%\build\locker\classes\compiler
+set stdcp=%scaladeps%;%scalalib%;%scalacomp%
+
+echo Compiling macros...
+set cp=%stdcp%
+call :scalac -Xmacros "%~dp0\Printf.scala"
+
+echo Compiling the program...
+set cp=%stdcp%;%~dp0.
+call :scalac "%~dp0\Test.scala"
+
+echo.
+echo NOW LOOK!!!
+echo ===============================================
+set cp=%stdcp%;%~dp0.
+call :scala Test
+echo.
+echo ===============================================
+goto :eof
+
+:scalac
+setlocal
+call set args=%*
+rem echo java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.Main %args%
+java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.Main %args%
+endlocal&goto :eof
+
+:scala
+setlocal
+call set args=%*
+rem echo java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner %args%
+java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner %args%
+endlocal&goto :eof
diff --git a/test/files/macros/macros_v0001.sh b/test/files/macros/macros_v0001.sh
new file mode 100644
index 0000000000..abe09836bb
--- /dev/null
+++ b/test/files/macros/macros_v0001.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+set -o errexit
+
+if [[ $(uname -s) == CYGWIN* ]]; then cpsep=";"; else cpsep=":"; fi
+scripthome="$(dirname "$0")"
+scalahome="$scripthome/../../.."
+scaladeps="$scalahome/lib/jline.jar;$scalahome/lib/fjbg.jar"
+scalalib="$scalahome/build/pack/lib/scala-library.jar"
+if [ ! -f "$scalalib" ]; then scalalib="$scalahome/build/locker/classes/library"; fi
+scalacomp="$scalahome/build/pack/lib/scala-compiler.jar"
+if [ ! -f "$scalacomp" ]; then scalacomp="$scalahome/build/locker/classes/compiler"; fi
+stdcp="$scaladeps$cpsep$scalalib$cpsep$scalacomp"
+function scalac { java -cp "$cp" -Dscala.usejavacp=true scala.tools.nsc.Main $*; }
+function scala { java -cp "$cp" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner $*; }
+
+echo "Compiling macros..."
+cp="$stdcp"
+scalac -Xmacros "$scripthome/Printf.scala"
+
+echo "Compiling the program..."
+cp="$stdcp$cpsep$scripthome"
+scalac "$scripthome/Test.scala"
+
+echo ""
+echo "NOW LOOK"
+echo "==============================================="
+cp="$stdcp$cpsep$scripthome"
+scala Test
+echo ""
+echo "==============================================="
diff --git a/test/files/neg/cyclics-import.check b/test/files/neg/cyclics-import.check
new file mode 100644
index 0000000000..ef355fab0a
--- /dev/null
+++ b/test/files/neg/cyclics-import.check
@@ -0,0 +1,15 @@
+cyclics-import.scala:1: error: encountered unrecoverable cycle resolving import.
+Note: this is often due in part to a class depending on a definition nested within its companion.
+If applicable, you may wish to try moving some members into another object.
+import User.UserStatus._
+ ^
+cyclics-import.scala:12: error: not found: type Value
+ type UserStatus = Value
+ ^
+cyclics-import.scala:14: error: not found: value Value
+ val Active = Value("1")
+ ^
+cyclics-import.scala:15: error: not found: value Value
+ val Disabled = Value("2")
+ ^
+four errors found
diff --git a/test/files/neg/cyclics-import.scala b/test/files/neg/cyclics-import.scala
new file mode 100644
index 0000000000..7b510b58e2
--- /dev/null
+++ b/test/files/neg/cyclics-import.scala
@@ -0,0 +1,17 @@
+import User.UserStatus._
+
+class User {
+ var id: Int = 0
+ var email: String = null
+ var password: String = null
+ var userStatus: UserStatus = null
+}
+
+object User {
+ object UserStatus extends Enumeration {
+ type UserStatus = Value
+
+ val Active = Value("1")
+ val Disabled = Value("2")
+ }
+}
diff --git a/test/files/neg/main1.check b/test/files/neg/main1.check
index 734c78e54d..1a7a13e1e9 100644
--- a/test/files/neg/main1.check
+++ b/test/files/neg/main1.check
@@ -1,25 +1,25 @@
-main1.scala:3: error: Foo has a main method, but foo1.Foo will not be a runnable program.
- Its companion is a trait, which means no static forwarder can be generated.
+main1.scala:3: error: Foo has a main method with parameter type Array[String], but foo1.Foo will not be a runnable program.
+ Reason: companion is a trait, which means no static forwarder can be generated.
object Foo { // companion is trait
^
-main1.scala:10: error: Foo has a main method, but foo2.Foo will not be a runnable program.
- Its companion contains its own main method, which means no static forwarder can be generated.
+main1.scala:10: error: Foo has a main method with parameter type Array[String], but foo2.Foo will not be a runnable program.
+ Reason: companion contains its own main method, which means no static forwarder can be generated.
object Foo { // companion has its own main
^
-main1.scala:22: error: Foo has a main method, but foo3.Foo will not be a runnable program.
- Its companion contains its own main method (implementation restriction: no main is allowed, regardless of signature), which means no static forwarder can be generated.
+main1.scala:22: error: Foo has a main method with parameter type Array[String], but foo3.Foo will not be a runnable program.
+ Reason: companion contains its own main method (implementation restriction: no main is allowed, regardless of signature), which means no static forwarder can be generated.
object Foo { // Companion contains main, but not an interfering main.
^
-main1.scala:31: error: Foo has a main method, but foo4.Foo will not be a runnable program.
- Its companion contains its own main method (implementation restriction: no main is allowed, regardless of signature), which means no static forwarder can be generated.
+main1.scala:31: error: Foo has a main method with parameter type Array[String], but foo4.Foo will not be a runnable program.
+ Reason: companion contains its own main method, which means no static forwarder can be generated.
object Foo extends Foo { // Inherits main from the class
^
-main1.scala:39: error: Foo has a main method, but foo5.Foo will not be a runnable program.
- Its companion contains its own main method (implementation restriction: no main is allowed, regardless of signature), which means no static forwarder can be generated.
+main1.scala:39: error: Foo has a main method with parameter type Array[String], but foo5.Foo will not be a runnable program.
+ Reason: companion contains its own main method, which means no static forwarder can be generated.
object Foo extends Foo { // Overrides main from the class
^
diff --git a/test/files/neg/nested-fn-print.check b/test/files/neg/nested-fn-print.check
new file mode 100644
index 0000000000..ea278554d4
--- /dev/null
+++ b/test/files/neg/nested-fn-print.check
@@ -0,0 +1,20 @@
+nested-fn-print.scala:4: error: only classes can have declared but undefined members
+(Note that variables need to be initialized to be defined)
+ var x3: Int => Double
+ ^
+nested-fn-print.scala:7: error: type mismatch;
+ found : String("a")
+ required: Int => (Float => Double)
+ x1 = "a"
+ ^
+nested-fn-print.scala:8: error: type mismatch;
+ found : String("b")
+ required: (Int => Float) => Double
+ x2 = "b"
+ ^
+nested-fn-print.scala:9: error: type mismatch;
+ found : String("c")
+ required: Int => Double
+ x3 = "c"
+ ^
+four errors found
diff --git a/test/files/neg/nested-fn-print.scala b/test/files/neg/nested-fn-print.scala
new file mode 100644
index 0000000000..9a4bd162c0
--- /dev/null
+++ b/test/files/neg/nested-fn-print.scala
@@ -0,0 +1,11 @@
+object Test {
+ var x1: Int => Float => Double = _
+ var x2: (Int => Float) => Double = _
+ var x3: Int => Double
+
+ def main(args: Array[String]): Unit = {
+ x1 = "a"
+ x2 = "b"
+ x3 = "c"
+ }
+}
diff --git a/test/files/neg/specification-scopes.check b/test/files/neg/specification-scopes.check
new file mode 100644
index 0000000000..7af9842379
--- /dev/null
+++ b/test/files/neg/specification-scopes.check
@@ -0,0 +1,12 @@
+P_2.scala:14: error: reference to x is ambiguous;
+it is both defined in object C and imported subsequently by
+import Q.X._
+ println("L14: "+x) // reference to 'x' is ambiguous here
+ ^
+P_2.scala:19: error: reference to y is ambiguous;
+it is imported twice in the same scope by
+import P.X._
+and import X.y
+ println("L19: "+y) // reference to 'y' is ambiguous here
+ ^
+two errors found
diff --git a/test/files/neg/specification-scopes/P_1.scala b/test/files/neg/specification-scopes/P_1.scala
new file mode 100644
index 0000000000..3b11f1167d
--- /dev/null
+++ b/test/files/neg/specification-scopes/P_1.scala
@@ -0,0 +1,6 @@
+package P {
+ object X { val x = 1; val y = 2; }
+}
+package Q {
+ object X { val x = true; val y = "" }
+}
diff --git a/test/files/neg/specification-scopes/P_2.scala b/test/files/neg/specification-scopes/P_2.scala
new file mode 100644
index 0000000000..d59f82e90d
--- /dev/null
+++ b/test/files/neg/specification-scopes/P_2.scala
@@ -0,0 +1,21 @@
+package P { // 'X' bound by package clause
+ import Console._ // 'println' bound by wildcard import
+ object A {
+ println("L4: "+X) // 'X' refers to 'P.X' here
+ object B {
+ import Q._ // 'X' bound by wildcard import
+ println("L7: "+X) // 'X' refers to 'Q.X' here
+ import X._ // 'x' and 'y' bound by wildcard import
+ println("L8: "+x) // 'x' refers to 'Q.X.x' here
+ object C {
+ val x = 3 // 'x' bound by local definition
+ println("L12: "+x); // 'x' refers to constant '3' here
+ { import Q.X._ // 'x' and 'y' bound by wildcard
+ println("L14: "+x) // reference to 'x' is ambiguous here
+ import X.y // 'y' bound by explicit import
+ println("L16: "+y); // 'y' refers to 'Q.X.y' here
+ { val x = "abc" // 'x' bound by local definition
+ import P.X._ // 'x' and 'y' bound by wildcard
+ println("L19: "+y) // reference to 'y' is ambiguous here
+ println("L20: "+x) // 'x' refers to string ''abc'' here
+}}}}}}
diff --git a/test/files/neg/t0003.check b/test/files/neg/t0003.check
index 1913dde9dd..8bab55db3f 100644
--- a/test/files/neg/t0003.check
+++ b/test/files/neg/t0003.check
@@ -1,5 +1,5 @@
t0003.scala:2: error: type mismatch;
- found : A => B => B
+ found : A => (B => B)
required: A => B
def foo[A, B, C](l: List[A], f: A => B=>B, g: B=>B=>C): List[C] = l map (g compose f)
^
diff --git a/test/files/neg/t1845.check b/test/files/neg/t1845.check
index 7c0bddbc20..a6c82f5659 100644
--- a/test/files/neg/t1845.check
+++ b/test/files/neg/t1845.check
@@ -1,4 +1,6 @@
-t1845.scala:9: error: illegal cyclic reference involving value <import>
- val lexical = new StdLexical
- ^
+t1845.scala:6: error: encountered unrecoverable cycle resolving import.
+Note: this is often due in part to a class depending on a definition nested within its companion.
+If applicable, you may wish to try moving some members into another object.
+ import lexical._
+ ^
one error found
diff --git a/test/files/neg/t2870.check b/test/files/neg/t2870.check
index 72bc0d98a1..ab962d48c8 100644
--- a/test/files/neg/t2870.check
+++ b/test/files/neg/t2870.check
@@ -1,7 +1,9 @@
t2870.scala:1: error: not found: type Jar (similar: Jars)
class Jars(jar: Jar)
^
-t2870.scala:6: error: illegal cyclic reference involving value <import>
- val scala = fromClasspathString(javaClassPath)
- ^
+t2870.scala:4: error: encountered unrecoverable cycle resolving import.
+Note: this is often due in part to a class depending on a definition nested within its companion.
+If applicable, you may wish to try moving some members into another object.
+ import scala.util.Properties.javaClassPath
+ ^
two errors found
diff --git a/test/files/neg/t3240.check b/test/files/neg/t3240.check
index 7ebabd5fcd..efae682c66 100644
--- a/test/files/neg/t3240.check
+++ b/test/files/neg/t3240.check
@@ -1,7 +1,4 @@
t3240.scala:3: error: only classes can have declared but undefined members
type t
^
-t3240.scala:5: error: type arguments [this.t] do not conform to method asInstanceOf's type parameter bounds [T0]
- a.getOrElse(defVal).asInstanceOf[t]
- ^
-two errors found
+one error found
diff --git a/test/files/neg/t4271.check b/test/files/neg/t4271.check
new file mode 100644
index 0000000000..91d9fbcfa1
--- /dev/null
+++ b/test/files/neg/t4271.check
@@ -0,0 +1,10 @@
+t4271.scala:9: error: value to is not a member of Int
+ 3 to 5
+ ^
+t4271.scala:10: error: value ensuring is not a member of Int
+ 5 ensuring true
+ ^
+t4271.scala:11: error: value -> is not a member of Int
+ 3 -> 5
+ ^
+three errors found
diff --git a/test/files/neg/t4271.scala b/test/files/neg/t4271.scala
new file mode 100644
index 0000000000..50526c8958
--- /dev/null
+++ b/test/files/neg/t4271.scala
@@ -0,0 +1,12 @@
+object foo {
+ object Donotuseme
+ implicit def any2Ensuring[A](x: A) = Donotuseme
+ implicit def doubleWrapper(x: Int) = Donotuseme
+ implicit def floatWrapper(x: Int) = Donotuseme
+ implicit def intWrapper(x: Int) = Donotuseme
+ implicit def longWrapper(x: Int) = Donotuseme
+ implicit def any2ArrowAssoc[A](x: A) = Donotuseme
+ 3 to 5
+ 5 ensuring true
+ 3 -> 5
+}
diff --git a/test/files/neg/t4749.check b/test/files/neg/t4749.check
new file mode 100644
index 0000000000..93ad3935fa
--- /dev/null
+++ b/test/files/neg/t4749.check
@@ -0,0 +1,28 @@
+t4749.scala:2: error: Fail1 has a main method with parameter type Array[String], but bippy.Fail1 will not be a runnable program.
+ Reason: main method must have exact signature (Array[String])Unit
+ object Fail1 {
+ ^
+t4749.scala:6: error: Fail2 has a main method with parameter type Array[String], but bippy.Fail2 will not be a runnable program.
+ Reason: main methods cannot be generic.
+ object Fail2 {
+ ^
+t4749.scala:13: error: Fail3 has a main method with parameter type Array[String], but bippy.Fail3 will not be a runnable program.
+ Reason: main methods cannot refer to type parameters or abstract types.
+ object Fail3 extends Bippy[Unit] { }
+ ^
+t4749.scala:16: error: Fail4 has a main method with parameter type Array[String], but bippy.Fail4 will not be a runnable program.
+ Reason: companion is a trait, which means no static forwarder can be generated.
+
+ object Fail4 {
+ ^
+t4749.scala:21: error: Fail5 has a main method with parameter type Array[String], but bippy.Fail5 will not be a runnable program.
+ Reason: companion contains its own main method, which means no static forwarder can be generated.
+
+ object Fail5 extends Fail5 { }
+ ^
+t4749.scala:26: error: Fail6 has a main method with parameter type Array[String], but bippy.Fail6 will not be a runnable program.
+ Reason: companion contains its own main method (implementation restriction: no main is allowed, regardless of signature), which means no static forwarder can be generated.
+
+ object Fail6 {
+ ^
+6 errors found
diff --git a/test/files/neg/t4749.flags b/test/files/neg/t4749.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/neg/t4749.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/t4749.scala b/test/files/neg/t4749.scala
new file mode 100644
index 0000000000..0973c36097
--- /dev/null
+++ b/test/files/neg/t4749.scala
@@ -0,0 +1,44 @@
+package bippy {
+ object Fail1 {
+ def main(args: Array[String]): Any = ()
+ }
+
+ object Fail2 {
+ def main[T](args: Array[String]): T = null.asInstanceOf[T]
+ }
+
+ abstract class Bippy[T] {
+ def main(args: Array[String]): T = null.asInstanceOf[T]
+ }
+ object Fail3 extends Bippy[Unit] { }
+
+
+ object Fail4 {
+ def main(args: Array[String]): Unit = ()
+ }
+ trait Fail4 { }
+
+ object Fail5 extends Fail5 { }
+ class Fail5 {
+ def main(args: Array[String]): Unit = ()
+ }
+
+ object Fail6 {
+ def main(args: Array[String]): Unit = ()
+ }
+ class Fail6 {
+ def main = "bippy"
+ }
+
+ object Win1 {
+ def main(args: Array[String]): Unit = ()
+ }
+ object Win2 extends Bippy[Unit] {
+ override def main(args: Array[String]): Unit = ()
+ }
+ trait WinBippy[T] {
+ def main(args: Array[String]): T = null.asInstanceOf[T]
+ }
+ object Win3 extends WinBippy[Unit] { }
+}
+
diff --git a/test/files/neg/t692.check b/test/files/neg/t692.check
index 12b7d40ba5..4149366309 100644
--- a/test/files/neg/t692.check
+++ b/test/files/neg/t692.check
@@ -13,12 +13,7 @@ t692.scala:13: error: class Foo takes type parameters
t692.scala:14: error: class Foo takes type parameters
implicit def typeOfBar[T4 <: Foo](implicit elem : RefType[T4]) : RefType[Bar[T4]] =
^
-t692.scala:15: error: type mismatch;
- found : test3.this.BarType[T4]
- required: test3.this.RefType[test3.this.Bar[T4]]
- BarType(elem);
- ^
t692.scala:19: error: class Foo takes type parameters
class Bar[A <: Foo](implicit tpeA : Type[A]) extends Foo;
^
-7 errors found
+6 errors found
diff --git a/test/files/pos/macros.flags b/test/files/pos/macros.flags
index e1b37447c9..7fea2ff901 100644
--- a/test/files/pos/macros.flags
+++ b/test/files/pos/macros.flags
@@ -1 +1 @@
--Xexperimental \ No newline at end of file
+-Xmacros \ No newline at end of file
diff --git a/test/files/pos/macros.scala b/test/files/pos/macros.scala
index 8a98195978..303610d464 100644
--- a/test/files/pos/macros.scala
+++ b/test/files/pos/macros.scala
@@ -1,10 +1,8 @@
object Test {
- class C {
+ class C {
def macro foo[T](xs: List[T]): T = (T, xs) match {
- case (t1: glob.Type, t2: glob.Tree) => t2
+ case (t1: Type, t2: Tree) => t2
}
}
}
-
-
diff --git a/test/files/pos/package-implicit/ActorRef.scala b/test/files/pos/package-implicit/ActorRef.scala
new file mode 100644
index 0000000000..e3f93c5e72
--- /dev/null
+++ b/test/files/pos/package-implicit/ActorRef.scala
@@ -0,0 +1,7 @@
+package t1000647.foo
+
+trait ActorRef {
+ def stop(): Unit = {}
+}
+
+trait ScalaActorRef { self: ActorRef => } \ No newline at end of file
diff --git a/test/files/pos/package-implicit/DataFlow.scala b/test/files/pos/package-implicit/DataFlow.scala
new file mode 100644
index 0000000000..d948280d0d
--- /dev/null
+++ b/test/files/pos/package-implicit/DataFlow.scala
@@ -0,0 +1,7 @@
+package t1000647.bar
+
+import t1000647.foo.{ScalaActorRef}
+
+object DataFlow {
+ def foo(ref: ScalaActorRef) = ref.stop()
+}
diff --git a/test/files/pos/package-implicit/package.scala b/test/files/pos/package-implicit/package.scala
new file mode 100644
index 0000000000..96c4b133f8
--- /dev/null
+++ b/test/files/pos/package-implicit/package.scala
@@ -0,0 +1,6 @@
+package t1000647
+
+package object foo {
+ implicit def scala2ActorRef(ref: ScalaActorRef): ActorRef =
+ ref.asInstanceOf[ActorRef]
+} \ No newline at end of file
diff --git a/test/files/pos/raw-map/J_1.java b/test/files/pos/raw-map/J_1.java
new file mode 100644
index 0000000000..bd43bcac81
--- /dev/null
+++ b/test/files/pos/raw-map/J_1.java
@@ -0,0 +1,4 @@
+public class J_1 {
+ public void setRawType(java.util.Map x) {
+ }
+}
diff --git a/test/files/pos/raw-map/S_2.scala b/test/files/pos/raw-map/S_2.scala
new file mode 100644
index 0000000000..de6c4ee5c2
--- /dev/null
+++ b/test/files/pos/raw-map/S_2.scala
@@ -0,0 +1,6 @@
+class Foo {
+ def foo {
+ val x: J_1 = null
+ x.setRawType(new java.util.HashMap)
+ }
+}
diff --git a/test/files/pos/t3999/a_1.scala b/test/files/pos/t3999/a_1.scala
new file mode 100644
index 0000000000..25366ee9c4
--- /dev/null
+++ b/test/files/pos/t3999/a_1.scala
@@ -0,0 +1,9 @@
+package foo
+
+class Outside
+
+package object bar {
+ class Val(b: Boolean)
+ implicit def boolean2Val(b: Boolean) = new Val(b)
+ implicit def boolean2Outside(b: Boolean) = new Outside
+} \ No newline at end of file
diff --git a/test/files/pos/t3999/b_2.scala b/test/files/pos/t3999/b_2.scala
new file mode 100644
index 0000000000..1af82c8c5b
--- /dev/null
+++ b/test/files/pos/t3999/b_2.scala
@@ -0,0 +1,7 @@
+package foo
+package bar
+
+class A {
+ val s: Val = false
+ val o: Outside = false
+} \ No newline at end of file
diff --git a/test/files/pos/t4176.scala b/test/files/pos/t4176.scala
new file mode 100644
index 0000000000..b4f1e705b1
--- /dev/null
+++ b/test/files/pos/t4176.scala
@@ -0,0 +1,6 @@
+// a.scala
+// Fri Jan 20 12:22:51 PST 2012
+
+class A(xs: Int*) { def getXs = xs }
+
+class B extends A { override def getXs = Nil }
diff --git a/test/files/pos/t4869.scala b/test/files/pos/t4869.scala
new file mode 100644
index 0000000000..f84aa4ed07
--- /dev/null
+++ b/test/files/pos/t4869.scala
@@ -0,0 +1,8 @@
+// /scala/trac/4869/a.scala
+// Wed Jan 4 21:17:29 PST 2012
+
+class C[T]
+class A {
+ def f[T](x: T): C[_ <: T] = null
+ def g = List(1d) map f
+}
diff --git a/test/files/pos/t5120.scala b/test/files/pos/t5120.scala
new file mode 100644
index 0000000000..2c193d129d
--- /dev/null
+++ b/test/files/pos/t5120.scala
@@ -0,0 +1,26 @@
+// An example extracted from SBT by Iulian
+// that showed that the previous fix to t5120
+// was too strict.
+class Test {
+ class ScopedKey[T]
+ class Value[T]
+
+ class Compiled[T](val settings: Seq[Pair[T]])
+
+ case class Pair[T](k: ScopedKey[T], v: ScopedKey[T])
+
+ def transform[T](x: T) = x
+
+ def test(compiledSettings: Seq[Compiled[_]]) = {
+ compiledSettings flatMap { cs => // cd: Compiled[_] in both versions
+ (cs.settings map { s => // cs.settings: Seq[Compiled[$1]] in trunk, Seq[Compiled[$1]] forSome $1 in 2.9.1
+ // s: Pair[$1] in trunk, Pair[$1] in 2.9.1
+ val t = transform(s.v) // t: ScopedKey[_] in trunk, ScopedKey[$1] in 2.9.1
+ foo(s.k, t)
+ t
+ }) : Seq[ScopedKey[_]]
+ }
+ }
+
+ def foo[T](x: ScopedKey[T], v: ScopedKey[T]) {}
+}
diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check
index ca99a5afc5..3385ef12b7 100644
--- a/test/files/presentation/callcc-interpreter.check
+++ b/test/files/presentation/callcc-interpreter.check
@@ -23,7 +23,7 @@ retrieved 64 members
`method add(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[_ >: callccInterpreter.Num with callccInterpreter.Wrong.type <: Product with Serializable with callccInterpreter.Value]`
`method apply(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[callccInterpreter.Value]`
`method asInstanceOf[T0]=> T0`
-`method callCC[A](h: A => callccInterpreter.M[A] => callccInterpreter.M[A])callccInterpreter.M[A]`
+`method callCC[A](h: (A => callccInterpreter.M[A]) => callccInterpreter.M[A])callccInterpreter.M[A]`
`method clone()Object`
`method ensuring(cond: Boolean)callccInterpreter.type`
`method ensuring(cond: Boolean, msg: => Any)callccInterpreter.type`
diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check
index 04cea738f5..ae202001eb 100644
--- a/test/files/presentation/ide-bug-1000531.check
+++ b/test/files/presentation/ide-bug-1000531.check
@@ -101,7 +101,7 @@ retrieved 123 members
`method takeWhile(p: B => Boolean)Iterator[B]`
`method toArray[B >: B](implicit evidence$1: ClassManifest[B])Array[B]`
`method toBuffer[B >: B]=> scala.collection.mutable.Buffer[B]`
-`method toIndexedSeq[B >: B]=> scala.collection.immutable.IndexedSeq[B]`
+`method toIndexedSeq=> scala.collection.immutable.IndexedSeq[B]`
`method toIterable=> Iterable[B]`
`method toIterator=> Iterator[B]`
`method toList=> List[B]`
diff --git a/test/files/run/Predef.readLine.check b/test/files/run/Predef.readLine.check
new file mode 100644
index 0000000000..4fb2bc4c6a
--- /dev/null
+++ b/test/files/run/Predef.readLine.check
@@ -0,0 +1,3 @@
+prompt
+fancy prompt
+immensely fancy prompt \ No newline at end of file
diff --git a/test/files/run/Predef.readLine.scala b/test/files/run/Predef.readLine.scala
new file mode 100644
index 0000000000..9f07936638
--- /dev/null
+++ b/test/files/run/Predef.readLine.scala
@@ -0,0 +1,10 @@
+import java.io.StringReader
+
+object Test extends App {
+ Console.withIn(new StringReader("")) {
+ readLine()
+ readLine("prompt\n")
+ readLine("%s prompt\n", "fancy")
+ readLine("%s %s prompt\n", "immensely", "fancy")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/interpolation.check b/test/files/run/interpolation.check
new file mode 100644
index 0000000000..09579a800a
--- /dev/null
+++ b/test/files/run/interpolation.check
@@ -0,0 +1,26 @@
+Bob is 1 years old
+Bob is 1 years old
+Bob will be 2 years old
+Bob will be 2 years old
+1+1 = 2
+1+1 = 2
+Bob is 12 years old
+Bob is 12 years old
+Bob will be 13 years old
+Bob will be 13 years old
+12+1 = 13
+12+1 = 13
+Bob is 123 years old
+Bob is 123 years old
+Bob will be 124 years old
+Bob will be 124 years old
+123+1 = 124
+123+1 = 124
+Best price: 10.0
+Best price: 10.00
+10.0% discount included
+10.00% discount included
+Best price: 13.345
+Best price: 13.35
+13.345% discount included
+13.35% discount included
diff --git a/test/files/run/stringInterpolation.flags b/test/files/run/interpolation.flags
index 48fd867160..48fd867160 100644
--- a/test/files/run/stringInterpolation.flags
+++ b/test/files/run/interpolation.flags
diff --git a/test/files/run/interpolation.scala b/test/files/run/interpolation.scala
new file mode 100644
index 0000000000..a0a185eaab
--- /dev/null
+++ b/test/files/run/interpolation.scala
@@ -0,0 +1,26 @@
+object Test extends App {
+
+ def test1(n: Int) = {
+ println(s"Bob is $n years old")
+ println(f"Bob is $n%2d years old")
+ println(s"Bob will be ${n+1} years old")
+ println(f"Bob will be ${n+1}%2d years old")
+ println(s"$n+1 = ${n+1}")
+ println(f"$n%d+1 = ${n+1}%d")
+ }
+
+ def test2(f: Float) = {
+ println(s"Best price: $f")
+ println(f"Best price: $f%.2f")
+ println(s"$f% discount included")
+ println(f"$f%3.2f% discount included")
+ }
+
+ test1(1)
+ test1(12)
+ test1(123)
+
+ test2(10.0f)
+ test2(13.345f)
+
+}
diff --git a/test/files/run/interpolationArgs.check b/test/files/run/interpolationArgs.check
new file mode 100644
index 0000000000..155991e618
--- /dev/null
+++ b/test/files/run/interpolationArgs.check
@@ -0,0 +1,2 @@
+java.lang.IllegalArgumentException: wrong number of arguments for interpolated string
+java.lang.IllegalArgumentException: wrong number of arguments for interpolated string
diff --git a/test/files/run/interpolationArgs.flags b/test/files/run/interpolationArgs.flags
new file mode 100644
index 0000000000..e1b37447c9
--- /dev/null
+++ b/test/files/run/interpolationArgs.flags
@@ -0,0 +1 @@
+-Xexperimental \ No newline at end of file
diff --git a/test/files/run/interpolationArgs.scala b/test/files/run/interpolationArgs.scala
new file mode 100644
index 0000000000..eb13767907
--- /dev/null
+++ b/test/files/run/interpolationArgs.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ try { scala.StringContext("p1", "p2", "p3").s("e1") } catch { case ex => println(ex) }
+ try { scala.StringContext("p1").s("e1") } catch { case ex => println(ex) }
+}
+
diff --git a/test/files/run/macro-range.check b/test/files/run/macro-range.check
new file mode 100644
index 0000000000..0719398930
--- /dev/null
+++ b/test/files/run/macro-range.check
@@ -0,0 +1,9 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
diff --git a/test/files/run/macro-range.flags b/test/files/run/macro-range.flags
new file mode 100644
index 0000000000..06a7b31f11
--- /dev/null
+++ b/test/files/run/macro-range.flags
@@ -0,0 +1 @@
+-Xmacros
diff --git a/test/files/run/macro-range/macro_range_1.scala b/test/files/run/macro-range/macro_range_1.scala
new file mode 100644
index 0000000000..fdfe7169ad
--- /dev/null
+++ b/test/files/run/macro-range/macro_range_1.scala
@@ -0,0 +1,99 @@
+import reflect.api.Modifier
+import reflect.macro.Context
+
+abstract class RangeDefault {
+ val from, to: Int
+ def foreach(f: Int => Unit) = {
+ var i = from
+ while (i < to) { f(i); i += 1 }
+ }
+}
+
+/** This class should go into reflect.macro once it is a bit more stable. */
+abstract class Utils {
+ val context: Context
+ import context._
+
+ class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer {
+ override def transform(tree: Tree): Tree = tree match {
+ case Ident(_) =>
+ def subst(from: List[Symbol], to: List[Tree]): Tree =
+ if (from.isEmpty) tree
+ else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`?
+ else subst(from.tail, to.tail);
+ subst(from, to)
+ case _ =>
+ val tree1 = super.transform(tree)
+ if (tree1 ne tree) tree1.tpe = null
+ tree1
+ }
+ }
+ def makeApply(fn: Tree, args: List[Tree]): Tree = fn match {
+ case Function(vparams, body) =>
+ new TreeSubstituter(vparams map (_.symbol), args) transform body
+ case Block(stats, expr) =>
+ Block(stats, makeApply(expr, args))
+ case _ =>
+ // todo. read the compiler config and print if -Ydebug is set
+ //println("no beta on "+fn+" "+fn.getClass)
+ Apply(fn, args)
+ }
+ def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = {
+ val continu = Apply(Ident(lname), Nil)
+ val rhs = If(cond, Block(List(body), continu), Literal(Constant()))
+ LabelDef(lname, Nil, rhs)
+ }
+ def makeBinop(left: Tree, op: String, right: Tree): Tree =
+ Apply(Select(left, newTermName(op)), List(right))
+}
+
+class Range(val from: Int, val to: Int) extends RangeDefault {
+ override def macro foreach(f: Int => Unit): Unit = {
+ // todo. read the compiler config and print if -Ydebug is set
+ //println("macro-expand, _this = "+ _this)
+ import _context._
+ object utils extends Utils {
+ val context: _context.type = _context
+ }
+ import utils._
+
+ val initName = newTermName("<init>")
+ // Either:
+ // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } }
+ // or:
+ // scala"($_this: RangeDefault).foreach($f)"
+ _this match {
+ case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" =>
+ val iname = newTermName("$i")
+ val hname = newTermName("$h")
+ def iref = Ident(iname)
+ def href = Ident(hname)
+ val labelname = newTermName("$while")
+ val cond = makeBinop(iref, "$less", href)
+ val body = Block(
+ List(makeApply(f, List(iref))),
+ Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1)))))
+ val generated =
+ Block(
+ List(
+ ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo),
+ ValDef(Modifiers(), hname, TypeTree(), hi)),
+ makeWhile(labelname, cond, body))
+ // todo. read the compiler config and print if -Ydebug is set
+ //tools.nsc.util.trace("generated: ")(generated)
+ generated
+ case _ =>
+ Apply(
+ Select(
+ Typed(_this, Ident(newTypeName("RangeDefault"))),
+ newTermName("foreach")),
+ List(f))
+ }
+ }
+}
+
+object Test extends App {
+
+ new Range(1, 10) foreach println
+
+}
diff --git a/test/files/run/macro-range/macro_range_2.scala b/test/files/run/macro-range/macro_range_2.scala
new file mode 100644
index 0000000000..fdfe7169ad
--- /dev/null
+++ b/test/files/run/macro-range/macro_range_2.scala
@@ -0,0 +1,99 @@
+import reflect.api.Modifier
+import reflect.macro.Context
+
+abstract class RangeDefault {
+ val from, to: Int
+ def foreach(f: Int => Unit) = {
+ var i = from
+ while (i < to) { f(i); i += 1 }
+ }
+}
+
+/** This class should go into reflect.macro once it is a bit more stable. */
+abstract class Utils {
+ val context: Context
+ import context._
+
+ class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer {
+ override def transform(tree: Tree): Tree = tree match {
+ case Ident(_) =>
+ def subst(from: List[Symbol], to: List[Tree]): Tree =
+ if (from.isEmpty) tree
+ else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`?
+ else subst(from.tail, to.tail);
+ subst(from, to)
+ case _ =>
+ val tree1 = super.transform(tree)
+ if (tree1 ne tree) tree1.tpe = null
+ tree1
+ }
+ }
+ def makeApply(fn: Tree, args: List[Tree]): Tree = fn match {
+ case Function(vparams, body) =>
+ new TreeSubstituter(vparams map (_.symbol), args) transform body
+ case Block(stats, expr) =>
+ Block(stats, makeApply(expr, args))
+ case _ =>
+ // todo. read the compiler config and print if -Ydebug is set
+ //println("no beta on "+fn+" "+fn.getClass)
+ Apply(fn, args)
+ }
+ def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = {
+ val continu = Apply(Ident(lname), Nil)
+ val rhs = If(cond, Block(List(body), continu), Literal(Constant()))
+ LabelDef(lname, Nil, rhs)
+ }
+ def makeBinop(left: Tree, op: String, right: Tree): Tree =
+ Apply(Select(left, newTermName(op)), List(right))
+}
+
+class Range(val from: Int, val to: Int) extends RangeDefault {
+ override def macro foreach(f: Int => Unit): Unit = {
+ // todo. read the compiler config and print if -Ydebug is set
+ //println("macro-expand, _this = "+ _this)
+ import _context._
+ object utils extends Utils {
+ val context: _context.type = _context
+ }
+ import utils._
+
+ val initName = newTermName("<init>")
+ // Either:
+ // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } }
+ // or:
+ // scala"($_this: RangeDefault).foreach($f)"
+ _this match {
+ case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" =>
+ val iname = newTermName("$i")
+ val hname = newTermName("$h")
+ def iref = Ident(iname)
+ def href = Ident(hname)
+ val labelname = newTermName("$while")
+ val cond = makeBinop(iref, "$less", href)
+ val body = Block(
+ List(makeApply(f, List(iref))),
+ Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1)))))
+ val generated =
+ Block(
+ List(
+ ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo),
+ ValDef(Modifiers(), hname, TypeTree(), hi)),
+ makeWhile(labelname, cond, body))
+ // todo. read the compiler config and print if -Ydebug is set
+ //tools.nsc.util.trace("generated: ")(generated)
+ generated
+ case _ =>
+ Apply(
+ Select(
+ Typed(_this, Ident(newTypeName("RangeDefault"))),
+ newTermName("foreach")),
+ List(f))
+ }
+ }
+}
+
+object Test extends App {
+
+ new Range(1, 10) foreach println
+
+}
diff --git a/test/files/run/range-unit.check b/test/files/run/range-unit.check
new file mode 100644
index 0000000000..3daf91cd64
--- /dev/null
+++ b/test/files/run/range-unit.check
@@ -0,0 +1,4178 @@
+>>> Range.inclusive <<<
+
+start end step length/first/last
+-----------------------------------------
+0 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 0 -1 1/0/0
+0 0 1 1/0/0
+0 0 -2 1/0/0
+0 0 2 1/0/0
+0 0 -3 1/0/0
+0 0 3 1/0/0
+0 0 17 1/0/0
+0 0 127 1/0/0
+0 0 MIN+1 1/0/0
+0 0 MAX 1/0/0
+0 0 MIN 1/0/0
+0 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 -1 -1 2/0/-1
+0 -1 1 0
+0 -1 -2 1/0/0
+0 -1 2 0
+0 -1 -3 1/0/0
+0 -1 3 0
+0 -1 17 0
+0 -1 127 0
+0 -1 MIN+1 1/0/0
+0 -1 MAX 0
+0 -1 MIN 1/0/0
+0 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 1 -1 0
+0 1 1 2/0/1
+0 1 -2 0
+0 1 2 1/0/0
+0 1 -3 0
+0 1 3 1/0/0
+0 1 17 1/0/0
+0 1 127 1/0/0
+0 1 MIN+1 0
+0 1 MAX 1/0/0
+0 1 MIN 0
+0 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 3 -1 0
+0 3 1 4/0/3
+0 3 -2 0
+0 3 2 2/0/2
+0 3 -3 0
+0 3 3 2/0/3
+0 3 17 1/0/0
+0 3 127 1/0/0
+0 3 MIN+1 0
+0 3 MAX 1/0/0
+0 3 MIN 0
+0 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 0 to -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+0 MIN+1 1 0
+0 MIN+1 -2 1073741824/0/MIN+2
+0 MIN+1 2 0
+0 MIN+1 -3 715827883/0/MIN+2
+0 MIN+1 3 0
+0 MIN+1 17 0
+0 MIN+1 127 0
+0 MIN+1 MIN+1 2/0/MIN+1
+0 MIN+1 MAX 0
+0 MIN+1 MIN 1/0/0
+0 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MAX -1 0
+0 MAX 1 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX -2 0
+0 MAX 2 1073741824/0/MAX-1
+0 MAX -3 0
+0 MAX 3 715827883/0/MAX-1
+0 MAX 17 126322568/0/MAX-8
+0 MAX 127 16909321/0/MAX-7
+0 MAX MIN+1 0
+0 MAX MAX 2/0/MAX
+0 MAX MIN 0
+0 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MIN -1 ---
+ java.lang.IllegalArgumentException: 0 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+0 MIN 1 0
+0 MIN -2 1073741825/0/MIN
+0 MIN 2 0
+0 MIN -3 715827883/0/MIN+2
+0 MIN 3 0
+0 MIN 17 0
+0 MIN 127 0
+0 MIN MIN+1 2/0/MIN+1
+0 MIN MAX 0
+0 MIN MIN 2/0/MIN
+
+start end step length/first/last
+-----------------------------------------
+-1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 0 -1 0
+-1 0 1 2/-1/0
+-1 0 -2 0
+-1 0 2 1/-1/-1
+-1 0 -3 0
+-1 0 3 1/-1/-1
+-1 0 17 1/-1/-1
+-1 0 127 1/-1/-1
+-1 0 MIN+1 0
+-1 0 MAX 1/-1/-1
+-1 0 MIN 0
+-1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 -1 -1 1/-1/-1
+-1 -1 1 1/-1/-1
+-1 -1 -2 1/-1/-1
+-1 -1 2 1/-1/-1
+-1 -1 -3 1/-1/-1
+-1 -1 3 1/-1/-1
+-1 -1 17 1/-1/-1
+-1 -1 127 1/-1/-1
+-1 -1 MIN+1 1/-1/-1
+-1 -1 MAX 1/-1/-1
+-1 -1 MIN 1/-1/-1
+-1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 1 -1 0
+-1 1 1 3/-1/1
+-1 1 -2 0
+-1 1 2 2/-1/1
+-1 1 -3 0
+-1 1 3 1/-1/-1
+-1 1 17 1/-1/-1
+-1 1 127 1/-1/-1
+-1 1 MIN+1 0
+-1 1 MAX 1/-1/-1
+-1 1 MIN 0
+-1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 3 -1 0
+-1 3 1 5/-1/3
+-1 3 -2 0
+-1 3 2 3/-1/3
+-1 3 -3 0
+-1 3 3 2/-1/2
+-1 3 17 1/-1/-1
+-1 3 127 1/-1/-1
+-1 3 MIN+1 0
+-1 3 MAX 1/-1/-1
+-1 3 MIN 0
+-1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MIN+1 -1 MAX/-1/MIN+1
+-1 MIN+1 1 0
+-1 MIN+1 -2 1073741824/-1/MIN+1
+-1 MIN+1 2 0
+-1 MIN+1 -3 715827883/-1/MIN+1
+-1 MIN+1 3 0
+-1 MIN+1 17 0
+-1 MIN+1 127 0
+-1 MIN+1 MIN+1 1/-1/-1
+-1 MIN+1 MAX 0
+-1 MIN+1 MIN 1/-1/-1
+-1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MAX -1 0
+-1 MAX 1 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -2 0
+-1 MAX 2 1073741825/-1/MAX
+-1 MAX -3 0
+-1 MAX 3 715827883/-1/MAX-2
+-1 MAX 17 126322568/-1/MAX-9
+-1 MAX 127 16909321/-1/MAX-8
+-1 MAX MIN+1 0
+-1 MAX MAX 2/-1/MAX-1
+-1 MAX MIN 0
+-1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MIN -1 ---
+ java.lang.IllegalArgumentException: -1 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+-1 MIN 1 0
+-1 MIN -2 1073741824/-1/MIN+1
+-1 MIN 2 0
+-1 MIN -3 715827883/-1/MIN+1
+-1 MIN 3 0
+-1 MIN 17 0
+-1 MIN 127 0
+-1 MIN MIN+1 2/-1/MIN
+-1 MIN MAX 0
+-1 MIN MIN 1/-1/-1
+
+start end step length/first/last
+-----------------------------------------
+1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 0 -1 2/1/0
+1 0 1 0
+1 0 -2 1/1/1
+1 0 2 0
+1 0 -3 1/1/1
+1 0 3 0
+1 0 17 0
+1 0 127 0
+1 0 MIN+1 1/1/1
+1 0 MAX 0
+1 0 MIN 1/1/1
+1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 -1 -1 3/1/-1
+1 -1 1 0
+1 -1 -2 2/1/-1
+1 -1 2 0
+1 -1 -3 1/1/1
+1 -1 3 0
+1 -1 17 0
+1 -1 127 0
+1 -1 MIN+1 1/1/1
+1 -1 MAX 0
+1 -1 MIN 1/1/1
+1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 1 -1 1/1/1
+1 1 1 1/1/1
+1 1 -2 1/1/1
+1 1 2 1/1/1
+1 1 -3 1/1/1
+1 1 3 1/1/1
+1 1 17 1/1/1
+1 1 127 1/1/1
+1 1 MIN+1 1/1/1
+1 1 MAX 1/1/1
+1 1 MIN 1/1/1
+1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 3 -1 0
+1 3 1 3/1/3
+1 3 -2 0
+1 3 2 2/1/3
+1 3 -3 0
+1 3 3 1/1/1
+1 3 17 1/1/1
+1 3 127 1/1/1
+1 3 MIN+1 0
+1 3 MAX 1/1/1
+1 3 MIN 0
+1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 1 to -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+1 MIN+1 1 0
+1 MIN+1 -2 1073741825/1/MIN+1
+1 MIN+1 2 0
+1 MIN+1 -3 715827883/1/MIN+3
+1 MIN+1 3 0
+1 MIN+1 17 0
+1 MIN+1 127 0
+1 MIN+1 MIN+1 2/1/MIN+2
+1 MIN+1 MAX 0
+1 MIN+1 MIN 2/1/MIN+1
+1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MAX -1 0
+1 MAX 1 MAX/1/MAX
+1 MAX -2 0
+1 MAX 2 1073741824/1/MAX
+1 MAX -3 0
+1 MAX 3 715827883/1/MAX
+1 MAX 17 126322568/1/MAX-7
+1 MAX 127 16909321/1/MAX-6
+1 MAX MIN+1 0
+1 MAX MAX 1/1/1
+1 MAX MIN 0
+1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MIN -1 ---
+ java.lang.IllegalArgumentException: 1 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+1 MIN 1 0
+1 MIN -2 1073741825/1/MIN+1
+1 MIN 2 0
+1 MIN -3 715827884/1/MIN
+1 MIN 3 0
+1 MIN 17 0
+1 MIN 127 0
+1 MIN MIN+1 2/1/MIN+2
+1 MIN MAX 0
+1 MIN MIN 2/1/MIN+1
+
+start end step length/first/last
+-----------------------------------------
+3 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 0 -1 4/3/0
+3 0 1 0
+3 0 -2 2/3/1
+3 0 2 0
+3 0 -3 2/3/0
+3 0 3 0
+3 0 17 0
+3 0 127 0
+3 0 MIN+1 1/3/3
+3 0 MAX 0
+3 0 MIN 1/3/3
+3 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 -1 -1 5/3/-1
+3 -1 1 0
+3 -1 -2 3/3/-1
+3 -1 2 0
+3 -1 -3 2/3/0
+3 -1 3 0
+3 -1 17 0
+3 -1 127 0
+3 -1 MIN+1 1/3/3
+3 -1 MAX 0
+3 -1 MIN 1/3/3
+3 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 1 -1 3/3/1
+3 1 1 0
+3 1 -2 2/3/1
+3 1 2 0
+3 1 -3 1/3/3
+3 1 3 0
+3 1 17 0
+3 1 127 0
+3 1 MIN+1 1/3/3
+3 1 MAX 0
+3 1 MIN 1/3/3
+3 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 3 -1 1/3/3
+3 3 1 1/3/3
+3 3 -2 1/3/3
+3 3 2 1/3/3
+3 3 -3 1/3/3
+3 3 3 1/3/3
+3 3 17 1/3/3
+3 3 127 1/3/3
+3 3 MIN+1 1/3/3
+3 3 MAX 1/3/3
+3 3 MIN 1/3/3
+3 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 3 to -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+3 MIN+1 1 0
+3 MIN+1 -2 1073741826/3/MIN+1
+3 MIN+1 2 0
+3 MIN+1 -3 715827884/3/MIN+2
+3 MIN+1 3 0
+3 MIN+1 17 0
+3 MIN+1 127 0
+3 MIN+1 MIN+1 2/3/MIN+4
+3 MIN+1 MAX 0
+3 MIN+1 MIN 2/3/MIN+3
+3 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MAX -1 0
+3 MAX 1 MAX-2/3/MAX
+3 MAX -2 0
+3 MAX 2 1073741823/3/MAX
+3 MAX -3 0
+3 MAX 3 715827882/3/MAX-1
+3 MAX 17 126322568/3/MAX-5
+3 MAX 127 16909321/3/MAX-4
+3 MAX MIN+1 0
+3 MAX MAX 1/3/3
+3 MAX MIN 0
+3 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MIN -1 ---
+ java.lang.IllegalArgumentException: 3 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+3 MIN 1 0
+3 MIN -2 1073741826/3/MIN+1
+3 MIN 2 0
+3 MIN -3 715827884/3/MIN+2
+3 MIN 3 0
+3 MIN 17 0
+3 MIN 127 0
+3 MIN MIN+1 2/3/MIN+4
+3 MIN MAX 0
+3 MIN MIN 2/3/MIN+3
+
+start end step length/first/last
+-----------------------------------------
+MIN+1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 0 -1 0
+MIN+1 0 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 -2 0
+MIN+1 0 2 1073741824/MIN+1/-1
+MIN+1 0 -3 0
+MIN+1 0 3 715827883/MIN+1/-1
+MIN+1 0 17 126322568/MIN+1/-8
+MIN+1 0 127 16909321/MIN+1/-7
+MIN+1 0 MIN+1 0
+MIN+1 0 MAX 2/MIN+1/0
+MIN+1 0 MIN 0
+MIN+1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 -1 -1 0
+MIN+1 -1 1 MAX/MIN+1/-1
+MIN+1 -1 -2 0
+MIN+1 -1 2 1073741824/MIN+1/-1
+MIN+1 -1 -3 0
+MIN+1 -1 3 715827883/MIN+1/-1
+MIN+1 -1 17 126322568/MIN+1/-8
+MIN+1 -1 127 16909321/MIN+1/-7
+MIN+1 -1 MIN+1 0
+MIN+1 -1 MAX 1/MIN+1/MIN+1
+MIN+1 -1 MIN 0
+MIN+1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 1 -1 0
+MIN+1 1 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -2 0
+MIN+1 1 2 1073741825/MIN+1/1
+MIN+1 1 -3 0
+MIN+1 1 3 715827883/MIN+1/-1
+MIN+1 1 17 126322568/MIN+1/-8
+MIN+1 1 127 16909321/MIN+1/-7
+MIN+1 1 MIN+1 0
+MIN+1 1 MAX 2/MIN+1/0
+MIN+1 1 MIN 0
+MIN+1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 3 -1 0
+MIN+1 3 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -2 0
+MIN+1 3 2 1073741826/MIN+1/3
+MIN+1 3 -3 0
+MIN+1 3 3 715827884/MIN+1/2
+MIN+1 3 17 126322568/MIN+1/-8
+MIN+1 3 127 16909321/MIN+1/-7
+MIN+1 3 MIN+1 0
+MIN+1 3 MAX 2/MIN+1/0
+MIN+1 3 MIN 0
+MIN+1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MIN+1 -1 1/MIN+1/MIN+1
+MIN+1 MIN+1 1 1/MIN+1/MIN+1
+MIN+1 MIN+1 -2 1/MIN+1/MIN+1
+MIN+1 MIN+1 2 1/MIN+1/MIN+1
+MIN+1 MIN+1 -3 1/MIN+1/MIN+1
+MIN+1 MIN+1 3 1/MIN+1/MIN+1
+MIN+1 MIN+1 17 1/MIN+1/MIN+1
+MIN+1 MIN+1 127 1/MIN+1/MIN+1
+MIN+1 MIN+1 MIN+1 1/MIN+1/MIN+1
+MIN+1 MIN+1 MAX 1/MIN+1/MIN+1
+MIN+1 MIN+1 MIN 1/MIN+1/MIN+1
+MIN+1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MAX -1 0
+MIN+1 MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -2 0
+MIN+1 MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 2: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -3 0
+MIN+1 MAX 3 1431655765/MIN+1/MAX-2
+MIN+1 MAX 17 252645135/MIN+1/MAX-16
+MIN+1 MAX 127 33818641/MIN+1/MAX-14
+MIN+1 MAX MIN+1 0
+MIN+1 MAX MAX 3/MIN+1/MAX
+MIN+1 MAX MIN 0
+MIN+1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MIN -1 2/MIN+1/MIN
+MIN+1 MIN 1 0
+MIN+1 MIN -2 1/MIN+1/MIN+1
+MIN+1 MIN 2 0
+MIN+1 MIN -3 1/MIN+1/MIN+1
+MIN+1 MIN 3 0
+MIN+1 MIN 17 0
+MIN+1 MIN 127 0
+MIN+1 MIN MIN+1 1/MIN+1/MIN+1
+MIN+1 MIN MAX 0
+MIN+1 MIN MIN 1/MIN+1/MIN+1
+
+start end step length/first/last
+-----------------------------------------
+MAX 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 0 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 to 0 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX 0 1 0
+MAX 0 -2 1073741824/MAX/1
+MAX 0 2 0
+MAX 0 -3 715827883/MAX/1
+MAX 0 3 0
+MAX 0 17 0
+MAX 0 127 0
+MAX 0 MIN+1 2/MAX/0
+MAX 0 MAX 0
+MAX 0 MIN 1/MAX/MAX
+MAX -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX -1 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 to -1 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX -1 1 0
+MAX -1 -2 1073741825/MAX/-1
+MAX -1 2 0
+MAX -1 -3 715827883/MAX/1
+MAX -1 3 0
+MAX -1 17 0
+MAX -1 127 0
+MAX -1 MIN+1 2/MAX/0
+MAX -1 MAX 0
+MAX -1 MIN 2/MAX/-1
+MAX 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 1 -1 MAX/MAX/1
+MAX 1 1 0
+MAX 1 -2 1073741824/MAX/1
+MAX 1 2 0
+MAX 1 -3 715827883/MAX/1
+MAX 1 3 0
+MAX 1 17 0
+MAX 1 127 0
+MAX 1 MIN+1 1/MAX/MAX
+MAX 1 MAX 0
+MAX 1 MIN 1/MAX/MAX
+MAX 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 3 -1 MAX-2/MAX/3
+MAX 3 1 0
+MAX 3 -2 1073741823/MAX/3
+MAX 3 2 0
+MAX 3 -3 715827882/MAX/4
+MAX 3 3 0
+MAX 3 17 0
+MAX 3 127 0
+MAX 3 MIN+1 1/MAX/MAX
+MAX 3 MAX 0
+MAX 3 MIN 1/MAX/MAX
+MAX MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 to -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN+1 1 0
+MAX MIN+1 -2 ---
+ java.lang.IllegalArgumentException: 2147483647 to -2147483647 by -2: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN+1 2 0
+MAX MIN+1 -3 1431655765/MAX/MIN+3
+MAX MIN+1 3 0
+MAX MIN+1 17 0
+MAX MIN+1 127 0
+MAX MIN+1 MIN+1 3/MAX/MIN+1
+MAX MIN+1 MAX 0
+MAX MIN+1 MIN 2/MAX/-1
+MAX MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MAX -1 1/MAX/MAX
+MAX MAX 1 1/MAX/MAX
+MAX MAX -2 1/MAX/MAX
+MAX MAX 2 1/MAX/MAX
+MAX MAX -3 1/MAX/MAX
+MAX MAX 3 1/MAX/MAX
+MAX MAX 17 1/MAX/MAX
+MAX MAX 127 1/MAX/MAX
+MAX MAX MIN+1 1/MAX/MAX
+MAX MAX MAX 1/MAX/MAX
+MAX MAX MIN 1/MAX/MAX
+MAX MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MIN -1 ---
+ java.lang.IllegalArgumentException: 2147483647 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN 1 0
+MAX MIN -2 ---
+ java.lang.IllegalArgumentException: 2147483647 to -2147483648 by -2: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN 2 0
+MAX MIN -3 1431655766/MAX/MIN
+MAX MIN 3 0
+MAX MIN 17 0
+MAX MIN 127 0
+MAX MIN MIN+1 3/MAX/MIN+1
+MAX MIN MAX 0
+MAX MIN MIN 2/MAX/-1
+
+start end step length/first/last
+-----------------------------------------
+MIN 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 0 -1 0
+MIN 0 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -2 0
+MIN 0 2 1073741825/MIN/0
+MIN 0 -3 0
+MIN 0 3 715827883/MIN/-2
+MIN 0 17 126322568/MIN/-9
+MIN 0 127 16909321/MIN/-8
+MIN 0 MIN+1 0
+MIN 0 MAX 2/MIN/-1
+MIN 0 MIN 0
+MIN -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN -1 -1 0
+MIN -1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 -2 0
+MIN -1 2 1073741824/MIN/-2
+MIN -1 -3 0
+MIN -1 3 715827883/MIN/-2
+MIN -1 17 126322568/MIN/-9
+MIN -1 127 16909321/MIN/-8
+MIN -1 MIN+1 0
+MIN -1 MAX 2/MIN/-1
+MIN -1 MIN 0
+MIN 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 1 -1 0
+MIN 1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -2 0
+MIN 1 2 1073741825/MIN/0
+MIN 1 -3 0
+MIN 1 3 715827884/MIN/1
+MIN 1 17 126322568/MIN/-9
+MIN 1 127 16909321/MIN/-8
+MIN 1 MIN+1 0
+MIN 1 MAX 2/MIN/-1
+MIN 1 MIN 0
+MIN 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 3 -1 0
+MIN 3 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -2 0
+MIN 3 2 1073741826/MIN/2
+MIN 3 -3 0
+MIN 3 3 715827884/MIN/1
+MIN 3 17 126322568/MIN/-9
+MIN 3 127 16909321/MIN/-8
+MIN 3 MIN+1 0
+MIN 3 MAX 2/MIN/-1
+MIN 3 MIN 0
+MIN MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MIN+1 -1 0
+MIN MIN+1 1 2/MIN/MIN+1
+MIN MIN+1 -2 0
+MIN MIN+1 2 1/MIN/MIN
+MIN MIN+1 -3 0
+MIN MIN+1 3 1/MIN/MIN
+MIN MIN+1 17 1/MIN/MIN
+MIN MIN+1 127 1/MIN/MIN
+MIN MIN+1 MIN+1 0
+MIN MIN+1 MAX 1/MIN/MIN
+MIN MIN+1 MIN 0
+MIN MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MAX -1 0
+MIN MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -2 0
+MIN MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 2: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -3 0
+MIN MAX 3 1431655766/MIN/MAX
+MIN MAX 17 252645136/MIN/MAX
+MIN MAX 127 33818641/MIN/MAX-15
+MIN MAX MIN+1 0
+MIN MAX MAX 3/MIN/MAX-1
+MIN MAX MIN 0
+MIN MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MIN -1 1/MIN/MIN
+MIN MIN 1 1/MIN/MIN
+MIN MIN -2 1/MIN/MIN
+MIN MIN 2 1/MIN/MIN
+MIN MIN -3 1/MIN/MIN
+MIN MIN 3 1/MIN/MIN
+MIN MIN 17 1/MIN/MIN
+MIN MIN 127 1/MIN/MIN
+MIN MIN MIN+1 1/MIN/MIN
+MIN MIN MAX 1/MIN/MIN
+MIN MIN MIN 1/MIN/MIN
+
+>>> Range.apply <<<
+
+start end step length/first/last
+-----------------------------------------
+0 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 0 -1 0
+0 0 1 0
+0 0 -2 0
+0 0 2 0
+0 0 -3 0
+0 0 3 0
+0 0 17 0
+0 0 127 0
+0 0 MIN+1 0
+0 0 MAX 0
+0 0 MIN 0
+0 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 -1 -1 1/0/0
+0 -1 1 0
+0 -1 -2 1/0/0
+0 -1 2 0
+0 -1 -3 1/0/0
+0 -1 3 0
+0 -1 17 0
+0 -1 127 0
+0 -1 MIN+1 1/0/0
+0 -1 MAX 0
+0 -1 MIN 1/0/0
+0 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 1 -1 0
+0 1 1 1/0/0
+0 1 -2 0
+0 1 2 1/0/0
+0 1 -3 0
+0 1 3 1/0/0
+0 1 17 1/0/0
+0 1 127 1/0/0
+0 1 MIN+1 0
+0 1 MAX 1/0/0
+0 1 MIN 0
+0 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 3 -1 0
+0 3 1 3/0/2
+0 3 -2 0
+0 3 2 2/0/2
+0 3 -3 0
+0 3 3 1/0/0
+0 3 17 1/0/0
+0 3 127 1/0/0
+0 3 MIN+1 0
+0 3 MAX 1/0/0
+0 3 MIN 0
+0 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MIN+1 -1 MAX/0/MIN+2
+0 MIN+1 1 0
+0 MIN+1 -2 1073741824/0/MIN+2
+0 MIN+1 2 0
+0 MIN+1 -3 715827883/0/MIN+2
+0 MIN+1 3 0
+0 MIN+1 17 0
+0 MIN+1 127 0
+0 MIN+1 MIN+1 1/0/0
+0 MIN+1 MAX 0
+0 MIN+1 MIN 1/0/0
+0 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MAX -1 0
+0 MAX 1 MAX/0/MAX-1
+0 MAX -2 0
+0 MAX 2 1073741824/0/MAX-1
+0 MAX -3 0
+0 MAX 3 715827883/0/MAX-1
+0 MAX 17 126322568/0/MAX-8
+0 MAX 127 16909321/0/MAX-7
+0 MAX MIN+1 0
+0 MAX MAX 1/0/0
+0 MAX MIN 0
+0 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MIN -1 ---
+ java.lang.IllegalArgumentException: 0 until -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+0 MIN 1 0
+0 MIN -2 1073741824/0/MIN+2
+0 MIN 2 0
+0 MIN -3 715827883/0/MIN+2
+0 MIN 3 0
+0 MIN 17 0
+0 MIN 127 0
+0 MIN MIN+1 2/0/MIN+1
+0 MIN MAX 0
+0 MIN MIN 1/0/0
+
+start end step length/first/last
+-----------------------------------------
+-1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 0 -1 0
+-1 0 1 1/-1/-1
+-1 0 -2 0
+-1 0 2 1/-1/-1
+-1 0 -3 0
+-1 0 3 1/-1/-1
+-1 0 17 1/-1/-1
+-1 0 127 1/-1/-1
+-1 0 MIN+1 0
+-1 0 MAX 1/-1/-1
+-1 0 MIN 0
+-1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 -1 -1 0
+-1 -1 1 0
+-1 -1 -2 0
+-1 -1 2 0
+-1 -1 -3 0
+-1 -1 3 0
+-1 -1 17 0
+-1 -1 127 0
+-1 -1 MIN+1 0
+-1 -1 MAX 0
+-1 -1 MIN 0
+-1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 1 -1 0
+-1 1 1 2/-1/0
+-1 1 -2 0
+-1 1 2 1/-1/-1
+-1 1 -3 0
+-1 1 3 1/-1/-1
+-1 1 17 1/-1/-1
+-1 1 127 1/-1/-1
+-1 1 MIN+1 0
+-1 1 MAX 1/-1/-1
+-1 1 MIN 0
+-1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 3 -1 0
+-1 3 1 4/-1/2
+-1 3 -2 0
+-1 3 2 2/-1/1
+-1 3 -3 0
+-1 3 3 2/-1/2
+-1 3 17 1/-1/-1
+-1 3 127 1/-1/-1
+-1 3 MIN+1 0
+-1 3 MAX 1/-1/-1
+-1 3 MIN 0
+-1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MIN+1 -1 MAX-1/-1/MIN+2
+-1 MIN+1 1 0
+-1 MIN+1 -2 1073741823/-1/MIN+3
+-1 MIN+1 2 0
+-1 MIN+1 -3 715827882/-1/MIN+4
+-1 MIN+1 3 0
+-1 MIN+1 17 0
+-1 MIN+1 127 0
+-1 MIN+1 MIN+1 1/-1/-1
+-1 MIN+1 MAX 0
+-1 MIN+1 MIN 1/-1/-1
+-1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MAX -1 0
+-1 MAX 1 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -2 0
+-1 MAX 2 1073741824/-1/MAX-2
+-1 MAX -3 0
+-1 MAX 3 715827883/-1/MAX-2
+-1 MAX 17 126322568/-1/MAX-9
+-1 MAX 127 16909321/-1/MAX-8
+-1 MAX MIN+1 0
+-1 MAX MAX 2/-1/MAX-1
+-1 MAX MIN 0
+-1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MIN -1 MAX/-1/MIN+1
+-1 MIN 1 0
+-1 MIN -2 1073741824/-1/MIN+1
+-1 MIN 2 0
+-1 MIN -3 715827883/-1/MIN+1
+-1 MIN 3 0
+-1 MIN 17 0
+-1 MIN 127 0
+-1 MIN MIN+1 1/-1/-1
+-1 MIN MAX 0
+-1 MIN MIN 1/-1/-1
+
+start end step length/first/last
+-----------------------------------------
+1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 0 -1 1/1/1
+1 0 1 0
+1 0 -2 1/1/1
+1 0 2 0
+1 0 -3 1/1/1
+1 0 3 0
+1 0 17 0
+1 0 127 0
+1 0 MIN+1 1/1/1
+1 0 MAX 0
+1 0 MIN 1/1/1
+1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 -1 -1 2/1/0
+1 -1 1 0
+1 -1 -2 1/1/1
+1 -1 2 0
+1 -1 -3 1/1/1
+1 -1 3 0
+1 -1 17 0
+1 -1 127 0
+1 -1 MIN+1 1/1/1
+1 -1 MAX 0
+1 -1 MIN 1/1/1
+1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 1 -1 0
+1 1 1 0
+1 1 -2 0
+1 1 2 0
+1 1 -3 0
+1 1 3 0
+1 1 17 0
+1 1 127 0
+1 1 MIN+1 0
+1 1 MAX 0
+1 1 MIN 0
+1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 3 -1 0
+1 3 1 2/1/2
+1 3 -2 0
+1 3 2 1/1/1
+1 3 -3 0
+1 3 3 1/1/1
+1 3 17 1/1/1
+1 3 127 1/1/1
+1 3 MIN+1 0
+1 3 MAX 1/1/1
+1 3 MIN 0
+1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 1 until -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+1 MIN+1 1 0
+1 MIN+1 -2 1073741824/1/MIN+3
+1 MIN+1 2 0
+1 MIN+1 -3 715827883/1/MIN+3
+1 MIN+1 3 0
+1 MIN+1 17 0
+1 MIN+1 127 0
+1 MIN+1 MIN+1 2/1/MIN+2
+1 MIN+1 MAX 0
+1 MIN+1 MIN 1/1/1
+1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MAX -1 0
+1 MAX 1 MAX-1/1/MAX-1
+1 MAX -2 0
+1 MAX 2 1073741823/1/MAX-2
+1 MAX -3 0
+1 MAX 3 715827882/1/MAX-3
+1 MAX 17 126322568/1/MAX-7
+1 MAX 127 16909321/1/MAX-6
+1 MAX MIN+1 0
+1 MAX MAX 1/1/1
+1 MAX MIN 0
+1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MIN -1 ---
+ java.lang.IllegalArgumentException: 1 until -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+1 MIN 1 0
+1 MIN -2 1073741825/1/MIN+1
+1 MIN 2 0
+1 MIN -3 715827883/1/MIN+3
+1 MIN 3 0
+1 MIN 17 0
+1 MIN 127 0
+1 MIN MIN+1 2/1/MIN+2
+1 MIN MAX 0
+1 MIN MIN 2/1/MIN+1
+
+start end step length/first/last
+-----------------------------------------
+3 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 0 -1 3/3/1
+3 0 1 0
+3 0 -2 2/3/1
+3 0 2 0
+3 0 -3 1/3/3
+3 0 3 0
+3 0 17 0
+3 0 127 0
+3 0 MIN+1 1/3/3
+3 0 MAX 0
+3 0 MIN 1/3/3
+3 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 -1 -1 4/3/0
+3 -1 1 0
+3 -1 -2 2/3/1
+3 -1 2 0
+3 -1 -3 2/3/0
+3 -1 3 0
+3 -1 17 0
+3 -1 127 0
+3 -1 MIN+1 1/3/3
+3 -1 MAX 0
+3 -1 MIN 1/3/3
+3 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 1 -1 2/3/2
+3 1 1 0
+3 1 -2 1/3/3
+3 1 2 0
+3 1 -3 1/3/3
+3 1 3 0
+3 1 17 0
+3 1 127 0
+3 1 MIN+1 1/3/3
+3 1 MAX 0
+3 1 MIN 1/3/3
+3 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 3 -1 0
+3 3 1 0
+3 3 -2 0
+3 3 2 0
+3 3 -3 0
+3 3 3 0
+3 3 17 0
+3 3 127 0
+3 3 MIN+1 0
+3 3 MAX 0
+3 3 MIN 0
+3 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 3 until -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+3 MIN+1 1 0
+3 MIN+1 -2 1073741825/3/MIN+3
+3 MIN+1 2 0
+3 MIN+1 -3 715827884/3/MIN+2
+3 MIN+1 3 0
+3 MIN+1 17 0
+3 MIN+1 127 0
+3 MIN+1 MIN+1 2/3/MIN+4
+3 MIN+1 MAX 0
+3 MIN+1 MIN 2/3/MIN+3
+3 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MAX -1 0
+3 MAX 1 MAX-3/3/MAX-1
+3 MAX -2 0
+3 MAX 2 1073741822/3/MAX-2
+3 MAX -3 0
+3 MAX 3 715827882/3/MAX-1
+3 MAX 17 126322568/3/MAX-5
+3 MAX 127 16909321/3/MAX-4
+3 MAX MIN+1 0
+3 MAX MAX 1/3/3
+3 MAX MIN 0
+3 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MIN -1 ---
+ java.lang.IllegalArgumentException: 3 until -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+3 MIN 1 0
+3 MIN -2 1073741826/3/MIN+1
+3 MIN 2 0
+3 MIN -3 715827884/3/MIN+2
+3 MIN 3 0
+3 MIN 17 0
+3 MIN 127 0
+3 MIN MIN+1 2/3/MIN+4
+3 MIN MAX 0
+3 MIN MIN 2/3/MIN+3
+
+start end step length/first/last
+-----------------------------------------
+MIN+1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 0 -1 0
+MIN+1 0 1 MAX/MIN+1/-1
+MIN+1 0 -2 0
+MIN+1 0 2 1073741824/MIN+1/-1
+MIN+1 0 -3 0
+MIN+1 0 3 715827883/MIN+1/-1
+MIN+1 0 17 126322568/MIN+1/-8
+MIN+1 0 127 16909321/MIN+1/-7
+MIN+1 0 MIN+1 0
+MIN+1 0 MAX 1/MIN+1/MIN+1
+MIN+1 0 MIN 0
+MIN+1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 -1 -1 0
+MIN+1 -1 1 MAX-1/MIN+1/-2
+MIN+1 -1 -2 0
+MIN+1 -1 2 1073741823/MIN+1/-3
+MIN+1 -1 -3 0
+MIN+1 -1 3 715827882/MIN+1/-4
+MIN+1 -1 17 126322568/MIN+1/-8
+MIN+1 -1 127 16909321/MIN+1/-7
+MIN+1 -1 MIN+1 0
+MIN+1 -1 MAX 1/MIN+1/MIN+1
+MIN+1 -1 MIN 0
+MIN+1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 1 -1 0
+MIN+1 1 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -2 0
+MIN+1 1 2 1073741824/MIN+1/-1
+MIN+1 1 -3 0
+MIN+1 1 3 715827883/MIN+1/-1
+MIN+1 1 17 126322568/MIN+1/-8
+MIN+1 1 127 16909321/MIN+1/-7
+MIN+1 1 MIN+1 0
+MIN+1 1 MAX 2/MIN+1/0
+MIN+1 1 MIN 0
+MIN+1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 3 -1 0
+MIN+1 3 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -2 0
+MIN+1 3 2 1073741825/MIN+1/1
+MIN+1 3 -3 0
+MIN+1 3 3 715827884/MIN+1/2
+MIN+1 3 17 126322568/MIN+1/-8
+MIN+1 3 127 16909321/MIN+1/-7
+MIN+1 3 MIN+1 0
+MIN+1 3 MAX 2/MIN+1/0
+MIN+1 3 MIN 0
+MIN+1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MIN+1 -1 0
+MIN+1 MIN+1 1 0
+MIN+1 MIN+1 -2 0
+MIN+1 MIN+1 2 0
+MIN+1 MIN+1 -3 0
+MIN+1 MIN+1 3 0
+MIN+1 MIN+1 17 0
+MIN+1 MIN+1 127 0
+MIN+1 MIN+1 MIN+1 0
+MIN+1 MIN+1 MAX 0
+MIN+1 MIN+1 MIN 0
+MIN+1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MAX -1 0
+MIN+1 MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -2 0
+MIN+1 MAX 2 MAX/MIN+1/MAX-2
+MIN+1 MAX -3 0
+MIN+1 MAX 3 1431655765/MIN+1/MAX-2
+MIN+1 MAX 17 252645135/MIN+1/MAX-16
+MIN+1 MAX 127 33818641/MIN+1/MAX-14
+MIN+1 MAX MIN+1 0
+MIN+1 MAX MAX 2/MIN+1/0
+MIN+1 MAX MIN 0
+MIN+1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MIN -1 1/MIN+1/MIN+1
+MIN+1 MIN 1 0
+MIN+1 MIN -2 1/MIN+1/MIN+1
+MIN+1 MIN 2 0
+MIN+1 MIN -3 1/MIN+1/MIN+1
+MIN+1 MIN 3 0
+MIN+1 MIN 17 0
+MIN+1 MIN 127 0
+MIN+1 MIN MIN+1 1/MIN+1/MIN+1
+MIN+1 MIN MAX 0
+MIN+1 MIN MIN 1/MIN+1/MIN+1
+
+start end step length/first/last
+-----------------------------------------
+MAX 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 0 -1 MAX/MAX/1
+MAX 0 1 0
+MAX 0 -2 1073741824/MAX/1
+MAX 0 2 0
+MAX 0 -3 715827883/MAX/1
+MAX 0 3 0
+MAX 0 17 0
+MAX 0 127 0
+MAX 0 MIN+1 1/MAX/MAX
+MAX 0 MAX 0
+MAX 0 MIN 1/MAX/MAX
+MAX -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX -1 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 until -1 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX -1 1 0
+MAX -1 -2 1073741824/MAX/1
+MAX -1 2 0
+MAX -1 -3 715827883/MAX/1
+MAX -1 3 0
+MAX -1 17 0
+MAX -1 127 0
+MAX -1 MIN+1 2/MAX/0
+MAX -1 MAX 0
+MAX -1 MIN 1/MAX/MAX
+MAX 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 1 -1 MAX-1/MAX/2
+MAX 1 1 0
+MAX 1 -2 1073741823/MAX/3
+MAX 1 2 0
+MAX 1 -3 715827882/MAX/4
+MAX 1 3 0
+MAX 1 17 0
+MAX 1 127 0
+MAX 1 MIN+1 1/MAX/MAX
+MAX 1 MAX 0
+MAX 1 MIN 1/MAX/MAX
+MAX 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 3 -1 MAX-3/MAX/4
+MAX 3 1 0
+MAX 3 -2 1073741822/MAX/5
+MAX 3 2 0
+MAX 3 -3 715827882/MAX/4
+MAX 3 3 0
+MAX 3 17 0
+MAX 3 127 0
+MAX 3 MIN+1 1/MAX/MAX
+MAX 3 MAX 0
+MAX 3 MIN 1/MAX/MAX
+MAX MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 until -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN+1 1 0
+MAX MIN+1 -2 MAX/MAX/MIN+3
+MAX MIN+1 2 0
+MAX MIN+1 -3 1431655765/MAX/MIN+3
+MAX MIN+1 3 0
+MAX MIN+1 17 0
+MAX MIN+1 127 0
+MAX MIN+1 MIN+1 2/MAX/0
+MAX MIN+1 MAX 0
+MAX MIN+1 MIN 2/MAX/-1
+MAX MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MAX -1 0
+MAX MAX 1 0
+MAX MAX -2 0
+MAX MAX 2 0
+MAX MAX -3 0
+MAX MAX 3 0
+MAX MAX 17 0
+MAX MAX 127 0
+MAX MAX MIN+1 0
+MAX MAX MAX 0
+MAX MAX MIN 0
+MAX MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MIN -1 ---
+ java.lang.IllegalArgumentException: 2147483647 until -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN 1 0
+MAX MIN -2 ---
+ java.lang.IllegalArgumentException: 2147483647 until -2147483648 by -2: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN 2 0
+MAX MIN -3 1431655765/MAX/MIN+3
+MAX MIN 3 0
+MAX MIN 17 0
+MAX MIN 127 0
+MAX MIN MIN+1 3/MAX/MIN+1
+MAX MIN MAX 0
+MAX MIN MIN 2/MAX/-1
+
+start end step length/first/last
+-----------------------------------------
+MIN 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 0 -1 0
+MIN 0 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -2 0
+MIN 0 2 1073741824/MIN/-2
+MIN 0 -3 0
+MIN 0 3 715827883/MIN/-2
+MIN 0 17 126322568/MIN/-9
+MIN 0 127 16909321/MIN/-8
+MIN 0 MIN+1 0
+MIN 0 MAX 2/MIN/-1
+MIN 0 MIN 0
+MIN -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN -1 -1 0
+MIN -1 1 MAX/MIN/-2
+MIN -1 -2 0
+MIN -1 2 1073741824/MIN/-2
+MIN -1 -3 0
+MIN -1 3 715827883/MIN/-2
+MIN -1 17 126322568/MIN/-9
+MIN -1 127 16909321/MIN/-8
+MIN -1 MIN+1 0
+MIN -1 MAX 1/MIN/MIN
+MIN -1 MIN 0
+MIN 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 1 -1 0
+MIN 1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -2 0
+MIN 1 2 1073741825/MIN/0
+MIN 1 -3 0
+MIN 1 3 715827883/MIN/-2
+MIN 1 17 126322568/MIN/-9
+MIN 1 127 16909321/MIN/-8
+MIN 1 MIN+1 0
+MIN 1 MAX 2/MIN/-1
+MIN 1 MIN 0
+MIN 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 3 -1 0
+MIN 3 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -2 0
+MIN 3 2 1073741826/MIN/2
+MIN 3 -3 0
+MIN 3 3 715827884/MIN/1
+MIN 3 17 126322568/MIN/-9
+MIN 3 127 16909321/MIN/-8
+MIN 3 MIN+1 0
+MIN 3 MAX 2/MIN/-1
+MIN 3 MIN 0
+MIN MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MIN+1 -1 0
+MIN MIN+1 1 1/MIN/MIN
+MIN MIN+1 -2 0
+MIN MIN+1 2 1/MIN/MIN
+MIN MIN+1 -3 0
+MIN MIN+1 3 1/MIN/MIN
+MIN MIN+1 17 1/MIN/MIN
+MIN MIN+1 127 1/MIN/MIN
+MIN MIN+1 MIN+1 0
+MIN MIN+1 MAX 1/MIN/MIN
+MIN MIN+1 MIN 0
+MIN MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MAX -1 0
+MIN MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -2 0
+MIN MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 2: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -3 0
+MIN MAX 3 1431655765/MIN/MAX-3
+MIN MAX 17 252645135/MIN/MAX-17
+MIN MAX 127 33818641/MIN/MAX-15
+MIN MAX MIN+1 0
+MIN MAX MAX 3/MIN/MAX-1
+MIN MAX MIN 0
+MIN MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MIN -1 0
+MIN MIN 1 0
+MIN MIN -2 0
+MIN MIN 2 0
+MIN MIN -3 0
+MIN MIN 3 0
+MIN MIN 17 0
+MIN MIN 127 0
+MIN MIN MIN+1 0
+MIN MIN MAX 0
+MIN MIN MIN 0
+
+>>> start to end <<<
+
+start end step length/first/last
+-----------------------------------------
+0 0 0 1/0/0
+0 0 -1 1/0/0
+0 0 1 1/0/0
+0 0 -2 1/0/0
+0 0 2 1/0/0
+0 0 -3 1/0/0
+0 0 3 1/0/0
+0 0 17 1/0/0
+0 0 127 1/0/0
+0 0 MIN+1 1/0/0
+0 0 MAX 1/0/0
+0 0 MIN 1/0/0
+0 -1 0 0
+0 -1 -1 0
+0 -1 1 0
+0 -1 -2 0
+0 -1 2 0
+0 -1 -3 0
+0 -1 3 0
+0 -1 17 0
+0 -1 127 0
+0 -1 MIN+1 0
+0 -1 MAX 0
+0 -1 MIN 0
+0 1 0 2/0/1
+0 1 -1 2/0/1
+0 1 1 2/0/1
+0 1 -2 2/0/1
+0 1 2 2/0/1
+0 1 -3 2/0/1
+0 1 3 2/0/1
+0 1 17 2/0/1
+0 1 127 2/0/1
+0 1 MIN+1 2/0/1
+0 1 MAX 2/0/1
+0 1 MIN 2/0/1
+0 3 0 4/0/3
+0 3 -1 4/0/3
+0 3 1 4/0/3
+0 3 -2 4/0/3
+0 3 2 4/0/3
+0 3 -3 4/0/3
+0 3 3 4/0/3
+0 3 17 4/0/3
+0 3 127 4/0/3
+0 3 MIN+1 4/0/3
+0 3 MAX 4/0/3
+0 3 MIN 4/0/3
+0 MIN+1 0 0
+0 MIN+1 -1 0
+0 MIN+1 1 0
+0 MIN+1 -2 0
+0 MIN+1 2 0
+0 MIN+1 -3 0
+0 MIN+1 3 0
+0 MIN+1 17 0
+0 MIN+1 127 0
+0 MIN+1 MIN+1 0
+0 MIN+1 MAX 0
+0 MIN+1 MIN 0
+0 MAX 0 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX -1 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX 1 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX -2 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX 2 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX -3 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX 3 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX 17 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX 127 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX MIN+1 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX MAX ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX MIN ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MIN 0 0
+0 MIN -1 0
+0 MIN 1 0
+0 MIN -2 0
+0 MIN 2 0
+0 MIN -3 0
+0 MIN 3 0
+0 MIN 17 0
+0 MIN 127 0
+0 MIN MIN+1 0
+0 MIN MAX 0
+0 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+-1 0 0 2/-1/0
+-1 0 -1 2/-1/0
+-1 0 1 2/-1/0
+-1 0 -2 2/-1/0
+-1 0 2 2/-1/0
+-1 0 -3 2/-1/0
+-1 0 3 2/-1/0
+-1 0 17 2/-1/0
+-1 0 127 2/-1/0
+-1 0 MIN+1 2/-1/0
+-1 0 MAX 2/-1/0
+-1 0 MIN 2/-1/0
+-1 -1 0 1/-1/-1
+-1 -1 -1 1/-1/-1
+-1 -1 1 1/-1/-1
+-1 -1 -2 1/-1/-1
+-1 -1 2 1/-1/-1
+-1 -1 -3 1/-1/-1
+-1 -1 3 1/-1/-1
+-1 -1 17 1/-1/-1
+-1 -1 127 1/-1/-1
+-1 -1 MIN+1 1/-1/-1
+-1 -1 MAX 1/-1/-1
+-1 -1 MIN 1/-1/-1
+-1 1 0 3/-1/1
+-1 1 -1 3/-1/1
+-1 1 1 3/-1/1
+-1 1 -2 3/-1/1
+-1 1 2 3/-1/1
+-1 1 -3 3/-1/1
+-1 1 3 3/-1/1
+-1 1 17 3/-1/1
+-1 1 127 3/-1/1
+-1 1 MIN+1 3/-1/1
+-1 1 MAX 3/-1/1
+-1 1 MIN 3/-1/1
+-1 3 0 5/-1/3
+-1 3 -1 5/-1/3
+-1 3 1 5/-1/3
+-1 3 -2 5/-1/3
+-1 3 2 5/-1/3
+-1 3 -3 5/-1/3
+-1 3 3 5/-1/3
+-1 3 17 5/-1/3
+-1 3 127 5/-1/3
+-1 3 MIN+1 5/-1/3
+-1 3 MAX 5/-1/3
+-1 3 MIN 5/-1/3
+-1 MIN+1 0 0
+-1 MIN+1 -1 0
+-1 MIN+1 1 0
+-1 MIN+1 -2 0
+-1 MIN+1 2 0
+-1 MIN+1 -3 0
+-1 MIN+1 3 0
+-1 MIN+1 17 0
+-1 MIN+1 127 0
+-1 MIN+1 MIN+1 0
+-1 MIN+1 MAX 0
+-1 MIN+1 MIN 0
+-1 MAX 0 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -1 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 1 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -2 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 2 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -3 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 3 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 17 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 127 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX MIN+1 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX MAX ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX MIN ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MIN 0 0
+-1 MIN -1 0
+-1 MIN 1 0
+-1 MIN -2 0
+-1 MIN 2 0
+-1 MIN -3 0
+-1 MIN 3 0
+-1 MIN 17 0
+-1 MIN 127 0
+-1 MIN MIN+1 0
+-1 MIN MAX 0
+-1 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+1 0 0 0
+1 0 -1 0
+1 0 1 0
+1 0 -2 0
+1 0 2 0
+1 0 -3 0
+1 0 3 0
+1 0 17 0
+1 0 127 0
+1 0 MIN+1 0
+1 0 MAX 0
+1 0 MIN 0
+1 -1 0 0
+1 -1 -1 0
+1 -1 1 0
+1 -1 -2 0
+1 -1 2 0
+1 -1 -3 0
+1 -1 3 0
+1 -1 17 0
+1 -1 127 0
+1 -1 MIN+1 0
+1 -1 MAX 0
+1 -1 MIN 0
+1 1 0 1/1/1
+1 1 -1 1/1/1
+1 1 1 1/1/1
+1 1 -2 1/1/1
+1 1 2 1/1/1
+1 1 -3 1/1/1
+1 1 3 1/1/1
+1 1 17 1/1/1
+1 1 127 1/1/1
+1 1 MIN+1 1/1/1
+1 1 MAX 1/1/1
+1 1 MIN 1/1/1
+1 3 0 3/1/3
+1 3 -1 3/1/3
+1 3 1 3/1/3
+1 3 -2 3/1/3
+1 3 2 3/1/3
+1 3 -3 3/1/3
+1 3 3 3/1/3
+1 3 17 3/1/3
+1 3 127 3/1/3
+1 3 MIN+1 3/1/3
+1 3 MAX 3/1/3
+1 3 MIN 3/1/3
+1 MIN+1 0 0
+1 MIN+1 -1 0
+1 MIN+1 1 0
+1 MIN+1 -2 0
+1 MIN+1 2 0
+1 MIN+1 -3 0
+1 MIN+1 3 0
+1 MIN+1 17 0
+1 MIN+1 127 0
+1 MIN+1 MIN+1 0
+1 MIN+1 MAX 0
+1 MIN+1 MIN 0
+1 MAX 0 MAX/1/MAX
+1 MAX -1 MAX/1/MAX
+1 MAX 1 MAX/1/MAX
+1 MAX -2 MAX/1/MAX
+1 MAX 2 MAX/1/MAX
+1 MAX -3 MAX/1/MAX
+1 MAX 3 MAX/1/MAX
+1 MAX 17 MAX/1/MAX
+1 MAX 127 MAX/1/MAX
+1 MAX MIN+1 MAX/1/MAX
+1 MAX MAX MAX/1/MAX
+1 MAX MIN MAX/1/MAX
+1 MIN 0 0
+1 MIN -1 0
+1 MIN 1 0
+1 MIN -2 0
+1 MIN 2 0
+1 MIN -3 0
+1 MIN 3 0
+1 MIN 17 0
+1 MIN 127 0
+1 MIN MIN+1 0
+1 MIN MAX 0
+1 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+3 0 0 0
+3 0 -1 0
+3 0 1 0
+3 0 -2 0
+3 0 2 0
+3 0 -3 0
+3 0 3 0
+3 0 17 0
+3 0 127 0
+3 0 MIN+1 0
+3 0 MAX 0
+3 0 MIN 0
+3 -1 0 0
+3 -1 -1 0
+3 -1 1 0
+3 -1 -2 0
+3 -1 2 0
+3 -1 -3 0
+3 -1 3 0
+3 -1 17 0
+3 -1 127 0
+3 -1 MIN+1 0
+3 -1 MAX 0
+3 -1 MIN 0
+3 1 0 0
+3 1 -1 0
+3 1 1 0
+3 1 -2 0
+3 1 2 0
+3 1 -3 0
+3 1 3 0
+3 1 17 0
+3 1 127 0
+3 1 MIN+1 0
+3 1 MAX 0
+3 1 MIN 0
+3 3 0 1/3/3
+3 3 -1 1/3/3
+3 3 1 1/3/3
+3 3 -2 1/3/3
+3 3 2 1/3/3
+3 3 -3 1/3/3
+3 3 3 1/3/3
+3 3 17 1/3/3
+3 3 127 1/3/3
+3 3 MIN+1 1/3/3
+3 3 MAX 1/3/3
+3 3 MIN 1/3/3
+3 MIN+1 0 0
+3 MIN+1 -1 0
+3 MIN+1 1 0
+3 MIN+1 -2 0
+3 MIN+1 2 0
+3 MIN+1 -3 0
+3 MIN+1 3 0
+3 MIN+1 17 0
+3 MIN+1 127 0
+3 MIN+1 MIN+1 0
+3 MIN+1 MAX 0
+3 MIN+1 MIN 0
+3 MAX 0 MAX-2/3/MAX
+3 MAX -1 MAX-2/3/MAX
+3 MAX 1 MAX-2/3/MAX
+3 MAX -2 MAX-2/3/MAX
+3 MAX 2 MAX-2/3/MAX
+3 MAX -3 MAX-2/3/MAX
+3 MAX 3 MAX-2/3/MAX
+3 MAX 17 MAX-2/3/MAX
+3 MAX 127 MAX-2/3/MAX
+3 MAX MIN+1 MAX-2/3/MAX
+3 MAX MAX MAX-2/3/MAX
+3 MAX MIN MAX-2/3/MAX
+3 MIN 0 0
+3 MIN -1 0
+3 MIN 1 0
+3 MIN -2 0
+3 MIN 2 0
+3 MIN -3 0
+3 MIN 3 0
+3 MIN 17 0
+3 MIN 127 0
+3 MIN MIN+1 0
+3 MIN MAX 0
+3 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+MIN+1 0 0 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 -1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 -2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 -3 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 3 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 17 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 127 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 MAX ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 MIN ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 -1 0 MAX/MIN+1/-1
+MIN+1 -1 -1 MAX/MIN+1/-1
+MIN+1 -1 1 MAX/MIN+1/-1
+MIN+1 -1 -2 MAX/MIN+1/-1
+MIN+1 -1 2 MAX/MIN+1/-1
+MIN+1 -1 -3 MAX/MIN+1/-1
+MIN+1 -1 3 MAX/MIN+1/-1
+MIN+1 -1 17 MAX/MIN+1/-1
+MIN+1 -1 127 MAX/MIN+1/-1
+MIN+1 -1 MIN+1 MAX/MIN+1/-1
+MIN+1 -1 MAX MAX/MIN+1/-1
+MIN+1 -1 MIN MAX/MIN+1/-1
+MIN+1 1 0 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -3 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 3 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 17 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 127 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 MAX ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 MIN ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 0 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -3 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 3 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 17 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 127 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 MAX ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 MIN ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MIN+1 0 1/MIN+1/MIN+1
+MIN+1 MIN+1 -1 1/MIN+1/MIN+1
+MIN+1 MIN+1 1 1/MIN+1/MIN+1
+MIN+1 MIN+1 -2 1/MIN+1/MIN+1
+MIN+1 MIN+1 2 1/MIN+1/MIN+1
+MIN+1 MIN+1 -3 1/MIN+1/MIN+1
+MIN+1 MIN+1 3 1/MIN+1/MIN+1
+MIN+1 MIN+1 17 1/MIN+1/MIN+1
+MIN+1 MIN+1 127 1/MIN+1/MIN+1
+MIN+1 MIN+1 MIN+1 1/MIN+1/MIN+1
+MIN+1 MIN+1 MAX 1/MIN+1/MIN+1
+MIN+1 MIN+1 MIN 1/MIN+1/MIN+1
+MIN+1 MAX 0 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -3 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 3 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 17 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 127 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX MAX ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX MIN ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MIN 0 0
+MIN+1 MIN -1 0
+MIN+1 MIN 1 0
+MIN+1 MIN -2 0
+MIN+1 MIN 2 0
+MIN+1 MIN -3 0
+MIN+1 MIN 3 0
+MIN+1 MIN 17 0
+MIN+1 MIN 127 0
+MIN+1 MIN MIN+1 0
+MIN+1 MIN MAX 0
+MIN+1 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+MAX 0 0 0
+MAX 0 -1 0
+MAX 0 1 0
+MAX 0 -2 0
+MAX 0 2 0
+MAX 0 -3 0
+MAX 0 3 0
+MAX 0 17 0
+MAX 0 127 0
+MAX 0 MIN+1 0
+MAX 0 MAX 0
+MAX 0 MIN 0
+MAX -1 0 0
+MAX -1 -1 0
+MAX -1 1 0
+MAX -1 -2 0
+MAX -1 2 0
+MAX -1 -3 0
+MAX -1 3 0
+MAX -1 17 0
+MAX -1 127 0
+MAX -1 MIN+1 0
+MAX -1 MAX 0
+MAX -1 MIN 0
+MAX 1 0 0
+MAX 1 -1 0
+MAX 1 1 0
+MAX 1 -2 0
+MAX 1 2 0
+MAX 1 -3 0
+MAX 1 3 0
+MAX 1 17 0
+MAX 1 127 0
+MAX 1 MIN+1 0
+MAX 1 MAX 0
+MAX 1 MIN 0
+MAX 3 0 0
+MAX 3 -1 0
+MAX 3 1 0
+MAX 3 -2 0
+MAX 3 2 0
+MAX 3 -3 0
+MAX 3 3 0
+MAX 3 17 0
+MAX 3 127 0
+MAX 3 MIN+1 0
+MAX 3 MAX 0
+MAX 3 MIN 0
+MAX MIN+1 0 0
+MAX MIN+1 -1 0
+MAX MIN+1 1 0
+MAX MIN+1 -2 0
+MAX MIN+1 2 0
+MAX MIN+1 -3 0
+MAX MIN+1 3 0
+MAX MIN+1 17 0
+MAX MIN+1 127 0
+MAX MIN+1 MIN+1 0
+MAX MIN+1 MAX 0
+MAX MIN+1 MIN 0
+MAX MAX 0 1/MAX/MAX
+MAX MAX -1 1/MAX/MAX
+MAX MAX 1 1/MAX/MAX
+MAX MAX -2 1/MAX/MAX
+MAX MAX 2 1/MAX/MAX
+MAX MAX -3 1/MAX/MAX
+MAX MAX 3 1/MAX/MAX
+MAX MAX 17 1/MAX/MAX
+MAX MAX 127 1/MAX/MAX
+MAX MAX MIN+1 1/MAX/MAX
+MAX MAX MAX 1/MAX/MAX
+MAX MAX MIN 1/MAX/MAX
+MAX MIN 0 0
+MAX MIN -1 0
+MAX MIN 1 0
+MAX MIN -2 0
+MAX MIN 2 0
+MAX MIN -3 0
+MAX MIN 3 0
+MAX MIN 17 0
+MAX MIN 127 0
+MAX MIN MIN+1 0
+MAX MIN MAX 0
+MAX MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+MIN 0 0 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -3 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 3 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 17 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 127 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 MAX ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 MIN ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 0 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 -1 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 -2 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 2 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 -3 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 3 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 17 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 127 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 MAX ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 MIN ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 0 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -3 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 3 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 17 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 127 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 MAX ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 MIN ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 0 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -3 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 3 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 17 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 127 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 MAX ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 MIN ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MIN+1 0 2/MIN/MIN+1
+MIN MIN+1 -1 2/MIN/MIN+1
+MIN MIN+1 1 2/MIN/MIN+1
+MIN MIN+1 -2 2/MIN/MIN+1
+MIN MIN+1 2 2/MIN/MIN+1
+MIN MIN+1 -3 2/MIN/MIN+1
+MIN MIN+1 3 2/MIN/MIN+1
+MIN MIN+1 17 2/MIN/MIN+1
+MIN MIN+1 127 2/MIN/MIN+1
+MIN MIN+1 MIN+1 2/MIN/MIN+1
+MIN MIN+1 MAX 2/MIN/MIN+1
+MIN MIN+1 MIN 2/MIN/MIN+1
+MIN MAX 0 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -3 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 3 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 17 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 127 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX MAX ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX MIN ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MIN 0 1/MIN/MIN
+MIN MIN -1 1/MIN/MIN
+MIN MIN 1 1/MIN/MIN
+MIN MIN -2 1/MIN/MIN
+MIN MIN 2 1/MIN/MIN
+MIN MIN -3 1/MIN/MIN
+MIN MIN 3 1/MIN/MIN
+MIN MIN 17 1/MIN/MIN
+MIN MIN 127 1/MIN/MIN
+MIN MIN MIN+1 1/MIN/MIN
+MIN MIN MAX 1/MIN/MIN
+MIN MIN MIN 1/MIN/MIN
+
+>>> start to end by step <<<
+
+start end step length/first/last
+-----------------------------------------
+0 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 0 -1 1/0/0
+0 0 1 1/0/0
+0 0 -2 1/0/0
+0 0 2 1/0/0
+0 0 -3 1/0/0
+0 0 3 1/0/0
+0 0 17 1/0/0
+0 0 127 1/0/0
+0 0 MIN+1 1/0/0
+0 0 MAX 1/0/0
+0 0 MIN 1/0/0
+0 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 -1 -1 2/0/-1
+0 -1 1 0
+0 -1 -2 1/0/0
+0 -1 2 0
+0 -1 -3 1/0/0
+0 -1 3 0
+0 -1 17 0
+0 -1 127 0
+0 -1 MIN+1 1/0/0
+0 -1 MAX 0
+0 -1 MIN 1/0/0
+0 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 1 -1 0
+0 1 1 2/0/1
+0 1 -2 0
+0 1 2 1/0/0
+0 1 -3 0
+0 1 3 1/0/0
+0 1 17 1/0/0
+0 1 127 1/0/0
+0 1 MIN+1 0
+0 1 MAX 1/0/0
+0 1 MIN 0
+0 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 3 -1 0
+0 3 1 4/0/3
+0 3 -2 0
+0 3 2 2/0/2
+0 3 -3 0
+0 3 3 2/0/3
+0 3 17 1/0/0
+0 3 127 1/0/0
+0 3 MIN+1 0
+0 3 MAX 1/0/0
+0 3 MIN 0
+0 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 0 to -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+0 MIN+1 1 0
+0 MIN+1 -2 1073741824/0/MIN+2
+0 MIN+1 2 0
+0 MIN+1 -3 715827883/0/MIN+2
+0 MIN+1 3 0
+0 MIN+1 17 0
+0 MIN+1 127 0
+0 MIN+1 MIN+1 2/0/MIN+1
+0 MIN+1 MAX 0
+0 MIN+1 MIN 1/0/0
+0 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MAX -1 0
+0 MAX 1 ---
+ java.lang.IllegalArgumentException: 0 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+0 MAX -2 0
+0 MAX 2 1073741824/0/MAX-1
+0 MAX -3 0
+0 MAX 3 715827883/0/MAX-1
+0 MAX 17 126322568/0/MAX-8
+0 MAX 127 16909321/0/MAX-7
+0 MAX MIN+1 0
+0 MAX MAX 2/0/MAX
+0 MAX MIN 0
+0 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MIN -1 ---
+ java.lang.IllegalArgumentException: 0 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+0 MIN 1 0
+0 MIN -2 1073741825/0/MIN
+0 MIN 2 0
+0 MIN -3 715827883/0/MIN+2
+0 MIN 3 0
+0 MIN 17 0
+0 MIN 127 0
+0 MIN MIN+1 2/0/MIN+1
+0 MIN MAX 0
+0 MIN MIN 2/0/MIN
+
+start end step length/first/last
+-----------------------------------------
+-1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 0 -1 0
+-1 0 1 2/-1/0
+-1 0 -2 0
+-1 0 2 1/-1/-1
+-1 0 -3 0
+-1 0 3 1/-1/-1
+-1 0 17 1/-1/-1
+-1 0 127 1/-1/-1
+-1 0 MIN+1 0
+-1 0 MAX 1/-1/-1
+-1 0 MIN 0
+-1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 -1 -1 1/-1/-1
+-1 -1 1 1/-1/-1
+-1 -1 -2 1/-1/-1
+-1 -1 2 1/-1/-1
+-1 -1 -3 1/-1/-1
+-1 -1 3 1/-1/-1
+-1 -1 17 1/-1/-1
+-1 -1 127 1/-1/-1
+-1 -1 MIN+1 1/-1/-1
+-1 -1 MAX 1/-1/-1
+-1 -1 MIN 1/-1/-1
+-1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 1 -1 0
+-1 1 1 3/-1/1
+-1 1 -2 0
+-1 1 2 2/-1/1
+-1 1 -3 0
+-1 1 3 1/-1/-1
+-1 1 17 1/-1/-1
+-1 1 127 1/-1/-1
+-1 1 MIN+1 0
+-1 1 MAX 1/-1/-1
+-1 1 MIN 0
+-1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 3 -1 0
+-1 3 1 5/-1/3
+-1 3 -2 0
+-1 3 2 3/-1/3
+-1 3 -3 0
+-1 3 3 2/-1/2
+-1 3 17 1/-1/-1
+-1 3 127 1/-1/-1
+-1 3 MIN+1 0
+-1 3 MAX 1/-1/-1
+-1 3 MIN 0
+-1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MIN+1 -1 MAX/-1/MIN+1
+-1 MIN+1 1 0
+-1 MIN+1 -2 1073741824/-1/MIN+1
+-1 MIN+1 2 0
+-1 MIN+1 -3 715827883/-1/MIN+1
+-1 MIN+1 3 0
+-1 MIN+1 17 0
+-1 MIN+1 127 0
+-1 MIN+1 MIN+1 1/-1/-1
+-1 MIN+1 MAX 0
+-1 MIN+1 MIN 1/-1/-1
+-1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MAX -1 0
+-1 MAX 1 ---
+ java.lang.IllegalArgumentException: -1 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -2 0
+-1 MAX 2 1073741825/-1/MAX
+-1 MAX -3 0
+-1 MAX 3 715827883/-1/MAX-2
+-1 MAX 17 126322568/-1/MAX-9
+-1 MAX 127 16909321/-1/MAX-8
+-1 MAX MIN+1 0
+-1 MAX MAX 2/-1/MAX-1
+-1 MAX MIN 0
+-1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MIN -1 ---
+ java.lang.IllegalArgumentException: -1 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+-1 MIN 1 0
+-1 MIN -2 1073741824/-1/MIN+1
+-1 MIN 2 0
+-1 MIN -3 715827883/-1/MIN+1
+-1 MIN 3 0
+-1 MIN 17 0
+-1 MIN 127 0
+-1 MIN MIN+1 2/-1/MIN
+-1 MIN MAX 0
+-1 MIN MIN 1/-1/-1
+
+start end step length/first/last
+-----------------------------------------
+1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 0 -1 2/1/0
+1 0 1 0
+1 0 -2 1/1/1
+1 0 2 0
+1 0 -3 1/1/1
+1 0 3 0
+1 0 17 0
+1 0 127 0
+1 0 MIN+1 1/1/1
+1 0 MAX 0
+1 0 MIN 1/1/1
+1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 -1 -1 3/1/-1
+1 -1 1 0
+1 -1 -2 2/1/-1
+1 -1 2 0
+1 -1 -3 1/1/1
+1 -1 3 0
+1 -1 17 0
+1 -1 127 0
+1 -1 MIN+1 1/1/1
+1 -1 MAX 0
+1 -1 MIN 1/1/1
+1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 1 -1 1/1/1
+1 1 1 1/1/1
+1 1 -2 1/1/1
+1 1 2 1/1/1
+1 1 -3 1/1/1
+1 1 3 1/1/1
+1 1 17 1/1/1
+1 1 127 1/1/1
+1 1 MIN+1 1/1/1
+1 1 MAX 1/1/1
+1 1 MIN 1/1/1
+1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 3 -1 0
+1 3 1 3/1/3
+1 3 -2 0
+1 3 2 2/1/3
+1 3 -3 0
+1 3 3 1/1/1
+1 3 17 1/1/1
+1 3 127 1/1/1
+1 3 MIN+1 0
+1 3 MAX 1/1/1
+1 3 MIN 0
+1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 1 to -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+1 MIN+1 1 0
+1 MIN+1 -2 1073741825/1/MIN+1
+1 MIN+1 2 0
+1 MIN+1 -3 715827883/1/MIN+3
+1 MIN+1 3 0
+1 MIN+1 17 0
+1 MIN+1 127 0
+1 MIN+1 MIN+1 2/1/MIN+2
+1 MIN+1 MAX 0
+1 MIN+1 MIN 2/1/MIN+1
+1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MAX -1 0
+1 MAX 1 MAX/1/MAX
+1 MAX -2 0
+1 MAX 2 1073741824/1/MAX
+1 MAX -3 0
+1 MAX 3 715827883/1/MAX
+1 MAX 17 126322568/1/MAX-7
+1 MAX 127 16909321/1/MAX-6
+1 MAX MIN+1 0
+1 MAX MAX 1/1/1
+1 MAX MIN 0
+1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MIN -1 ---
+ java.lang.IllegalArgumentException: 1 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+1 MIN 1 0
+1 MIN -2 1073741825/1/MIN+1
+1 MIN 2 0
+1 MIN -3 715827884/1/MIN
+1 MIN 3 0
+1 MIN 17 0
+1 MIN 127 0
+1 MIN MIN+1 2/1/MIN+2
+1 MIN MAX 0
+1 MIN MIN 2/1/MIN+1
+
+start end step length/first/last
+-----------------------------------------
+3 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 0 -1 4/3/0
+3 0 1 0
+3 0 -2 2/3/1
+3 0 2 0
+3 0 -3 2/3/0
+3 0 3 0
+3 0 17 0
+3 0 127 0
+3 0 MIN+1 1/3/3
+3 0 MAX 0
+3 0 MIN 1/3/3
+3 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 -1 -1 5/3/-1
+3 -1 1 0
+3 -1 -2 3/3/-1
+3 -1 2 0
+3 -1 -3 2/3/0
+3 -1 3 0
+3 -1 17 0
+3 -1 127 0
+3 -1 MIN+1 1/3/3
+3 -1 MAX 0
+3 -1 MIN 1/3/3
+3 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 1 -1 3/3/1
+3 1 1 0
+3 1 -2 2/3/1
+3 1 2 0
+3 1 -3 1/3/3
+3 1 3 0
+3 1 17 0
+3 1 127 0
+3 1 MIN+1 1/3/3
+3 1 MAX 0
+3 1 MIN 1/3/3
+3 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 3 -1 1/3/3
+3 3 1 1/3/3
+3 3 -2 1/3/3
+3 3 2 1/3/3
+3 3 -3 1/3/3
+3 3 3 1/3/3
+3 3 17 1/3/3
+3 3 127 1/3/3
+3 3 MIN+1 1/3/3
+3 3 MAX 1/3/3
+3 3 MIN 1/3/3
+3 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 3 to -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+3 MIN+1 1 0
+3 MIN+1 -2 1073741826/3/MIN+1
+3 MIN+1 2 0
+3 MIN+1 -3 715827884/3/MIN+2
+3 MIN+1 3 0
+3 MIN+1 17 0
+3 MIN+1 127 0
+3 MIN+1 MIN+1 2/3/MIN+4
+3 MIN+1 MAX 0
+3 MIN+1 MIN 2/3/MIN+3
+3 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MAX -1 0
+3 MAX 1 MAX-2/3/MAX
+3 MAX -2 0
+3 MAX 2 1073741823/3/MAX
+3 MAX -3 0
+3 MAX 3 715827882/3/MAX-1
+3 MAX 17 126322568/3/MAX-5
+3 MAX 127 16909321/3/MAX-4
+3 MAX MIN+1 0
+3 MAX MAX 1/3/3
+3 MAX MIN 0
+3 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MIN -1 ---
+ java.lang.IllegalArgumentException: 3 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+3 MIN 1 0
+3 MIN -2 1073741826/3/MIN+1
+3 MIN 2 0
+3 MIN -3 715827884/3/MIN+2
+3 MIN 3 0
+3 MIN 17 0
+3 MIN 127 0
+3 MIN MIN+1 2/3/MIN+4
+3 MIN MAX 0
+3 MIN MIN 2/3/MIN+3
+
+start end step length/first/last
+-----------------------------------------
+MIN+1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 0 -1 0
+MIN+1 0 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 0 -2 0
+MIN+1 0 2 1073741824/MIN+1/-1
+MIN+1 0 -3 0
+MIN+1 0 3 715827883/MIN+1/-1
+MIN+1 0 17 126322568/MIN+1/-8
+MIN+1 0 127 16909321/MIN+1/-7
+MIN+1 0 MIN+1 0
+MIN+1 0 MAX 2/MIN+1/0
+MIN+1 0 MIN 0
+MIN+1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 -1 -1 0
+MIN+1 -1 1 MAX/MIN+1/-1
+MIN+1 -1 -2 0
+MIN+1 -1 2 1073741824/MIN+1/-1
+MIN+1 -1 -3 0
+MIN+1 -1 3 715827883/MIN+1/-1
+MIN+1 -1 17 126322568/MIN+1/-8
+MIN+1 -1 127 16909321/MIN+1/-7
+MIN+1 -1 MIN+1 0
+MIN+1 -1 MAX 1/MIN+1/MIN+1
+MIN+1 -1 MIN 0
+MIN+1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 1 -1 0
+MIN+1 1 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -2 0
+MIN+1 1 2 1073741825/MIN+1/1
+MIN+1 1 -3 0
+MIN+1 1 3 715827883/MIN+1/-1
+MIN+1 1 17 126322568/MIN+1/-8
+MIN+1 1 127 16909321/MIN+1/-7
+MIN+1 1 MIN+1 0
+MIN+1 1 MAX 2/MIN+1/0
+MIN+1 1 MIN 0
+MIN+1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 3 -1 0
+MIN+1 3 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -2 0
+MIN+1 3 2 1073741826/MIN+1/3
+MIN+1 3 -3 0
+MIN+1 3 3 715827884/MIN+1/2
+MIN+1 3 17 126322568/MIN+1/-8
+MIN+1 3 127 16909321/MIN+1/-7
+MIN+1 3 MIN+1 0
+MIN+1 3 MAX 2/MIN+1/0
+MIN+1 3 MIN 0
+MIN+1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MIN+1 -1 1/MIN+1/MIN+1
+MIN+1 MIN+1 1 1/MIN+1/MIN+1
+MIN+1 MIN+1 -2 1/MIN+1/MIN+1
+MIN+1 MIN+1 2 1/MIN+1/MIN+1
+MIN+1 MIN+1 -3 1/MIN+1/MIN+1
+MIN+1 MIN+1 3 1/MIN+1/MIN+1
+MIN+1 MIN+1 17 1/MIN+1/MIN+1
+MIN+1 MIN+1 127 1/MIN+1/MIN+1
+MIN+1 MIN+1 MIN+1 1/MIN+1/MIN+1
+MIN+1 MIN+1 MAX 1/MIN+1/MIN+1
+MIN+1 MIN+1 MIN 1/MIN+1/MIN+1
+MIN+1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MAX -1 0
+MIN+1 MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -2 0
+MIN+1 MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483647 to 2147483647 by 2: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -3 0
+MIN+1 MAX 3 1431655765/MIN+1/MAX-2
+MIN+1 MAX 17 252645135/MIN+1/MAX-16
+MIN+1 MAX 127 33818641/MIN+1/MAX-14
+MIN+1 MAX MIN+1 0
+MIN+1 MAX MAX 3/MIN+1/MAX
+MIN+1 MAX MIN 0
+MIN+1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MIN -1 2/MIN+1/MIN
+MIN+1 MIN 1 0
+MIN+1 MIN -2 1/MIN+1/MIN+1
+MIN+1 MIN 2 0
+MIN+1 MIN -3 1/MIN+1/MIN+1
+MIN+1 MIN 3 0
+MIN+1 MIN 17 0
+MIN+1 MIN 127 0
+MIN+1 MIN MIN+1 1/MIN+1/MIN+1
+MIN+1 MIN MAX 0
+MIN+1 MIN MIN 1/MIN+1/MIN+1
+
+start end step length/first/last
+-----------------------------------------
+MAX 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 0 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 to 0 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX 0 1 0
+MAX 0 -2 1073741824/MAX/1
+MAX 0 2 0
+MAX 0 -3 715827883/MAX/1
+MAX 0 3 0
+MAX 0 17 0
+MAX 0 127 0
+MAX 0 MIN+1 2/MAX/0
+MAX 0 MAX 0
+MAX 0 MIN 1/MAX/MAX
+MAX -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX -1 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 to -1 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX -1 1 0
+MAX -1 -2 1073741825/MAX/-1
+MAX -1 2 0
+MAX -1 -3 715827883/MAX/1
+MAX -1 3 0
+MAX -1 17 0
+MAX -1 127 0
+MAX -1 MIN+1 2/MAX/0
+MAX -1 MAX 0
+MAX -1 MIN 2/MAX/-1
+MAX 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 1 -1 MAX/MAX/1
+MAX 1 1 0
+MAX 1 -2 1073741824/MAX/1
+MAX 1 2 0
+MAX 1 -3 715827883/MAX/1
+MAX 1 3 0
+MAX 1 17 0
+MAX 1 127 0
+MAX 1 MIN+1 1/MAX/MAX
+MAX 1 MAX 0
+MAX 1 MIN 1/MAX/MAX
+MAX 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 3 -1 MAX-2/MAX/3
+MAX 3 1 0
+MAX 3 -2 1073741823/MAX/3
+MAX 3 2 0
+MAX 3 -3 715827882/MAX/4
+MAX 3 3 0
+MAX 3 17 0
+MAX 3 127 0
+MAX 3 MIN+1 1/MAX/MAX
+MAX 3 MAX 0
+MAX 3 MIN 1/MAX/MAX
+MAX MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 to -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN+1 1 0
+MAX MIN+1 -2 ---
+ java.lang.IllegalArgumentException: 2147483647 to -2147483647 by -2: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN+1 2 0
+MAX MIN+1 -3 1431655765/MAX/MIN+3
+MAX MIN+1 3 0
+MAX MIN+1 17 0
+MAX MIN+1 127 0
+MAX MIN+1 MIN+1 3/MAX/MIN+1
+MAX MIN+1 MAX 0
+MAX MIN+1 MIN 2/MAX/-1
+MAX MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MAX -1 1/MAX/MAX
+MAX MAX 1 1/MAX/MAX
+MAX MAX -2 1/MAX/MAX
+MAX MAX 2 1/MAX/MAX
+MAX MAX -3 1/MAX/MAX
+MAX MAX 3 1/MAX/MAX
+MAX MAX 17 1/MAX/MAX
+MAX MAX 127 1/MAX/MAX
+MAX MAX MIN+1 1/MAX/MAX
+MAX MAX MAX 1/MAX/MAX
+MAX MAX MIN 1/MAX/MAX
+MAX MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MIN -1 ---
+ java.lang.IllegalArgumentException: 2147483647 to -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN 1 0
+MAX MIN -2 ---
+ java.lang.IllegalArgumentException: 2147483647 to -2147483648 by -2: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN 2 0
+MAX MIN -3 1431655766/MAX/MIN
+MAX MIN 3 0
+MAX MIN 17 0
+MAX MIN 127 0
+MAX MIN MIN+1 3/MAX/MIN+1
+MAX MIN MAX 0
+MAX MIN MIN 2/MAX/-1
+
+start end step length/first/last
+-----------------------------------------
+MIN 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 0 -1 0
+MIN 0 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -2 0
+MIN 0 2 1073741825/MIN/0
+MIN 0 -3 0
+MIN 0 3 715827883/MIN/-2
+MIN 0 17 126322568/MIN/-9
+MIN 0 127 16909321/MIN/-8
+MIN 0 MIN+1 0
+MIN 0 MAX 2/MIN/-1
+MIN 0 MIN 0
+MIN -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN -1 -1 0
+MIN -1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to -1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 -2 0
+MIN -1 2 1073741824/MIN/-2
+MIN -1 -3 0
+MIN -1 3 715827883/MIN/-2
+MIN -1 17 126322568/MIN/-9
+MIN -1 127 16909321/MIN/-8
+MIN -1 MIN+1 0
+MIN -1 MAX 2/MIN/-1
+MIN -1 MIN 0
+MIN 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 1 -1 0
+MIN 1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -2 0
+MIN 1 2 1073741825/MIN/0
+MIN 1 -3 0
+MIN 1 3 715827884/MIN/1
+MIN 1 17 126322568/MIN/-9
+MIN 1 127 16909321/MIN/-8
+MIN 1 MIN+1 0
+MIN 1 MAX 2/MIN/-1
+MIN 1 MIN 0
+MIN 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 3 -1 0
+MIN 3 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -2 0
+MIN 3 2 1073741826/MIN/2
+MIN 3 -3 0
+MIN 3 3 715827884/MIN/1
+MIN 3 17 126322568/MIN/-9
+MIN 3 127 16909321/MIN/-8
+MIN 3 MIN+1 0
+MIN 3 MAX 2/MIN/-1
+MIN 3 MIN 0
+MIN MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MIN+1 -1 0
+MIN MIN+1 1 2/MIN/MIN+1
+MIN MIN+1 -2 0
+MIN MIN+1 2 1/MIN/MIN
+MIN MIN+1 -3 0
+MIN MIN+1 3 1/MIN/MIN
+MIN MIN+1 17 1/MIN/MIN
+MIN MIN+1 127 1/MIN/MIN
+MIN MIN+1 MIN+1 0
+MIN MIN+1 MAX 1/MIN/MIN
+MIN MIN+1 MIN 0
+MIN MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MAX -1 0
+MIN MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -2 0
+MIN MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483648 to 2147483647 by 2: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -3 0
+MIN MAX 3 1431655766/MIN/MAX
+MIN MAX 17 252645136/MIN/MAX
+MIN MAX 127 33818641/MIN/MAX-15
+MIN MAX MIN+1 0
+MIN MAX MAX 3/MIN/MAX-1
+MIN MAX MIN 0
+MIN MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MIN -1 1/MIN/MIN
+MIN MIN 1 1/MIN/MIN
+MIN MIN -2 1/MIN/MIN
+MIN MIN 2 1/MIN/MIN
+MIN MIN -3 1/MIN/MIN
+MIN MIN 3 1/MIN/MIN
+MIN MIN 17 1/MIN/MIN
+MIN MIN 127 1/MIN/MIN
+MIN MIN MIN+1 1/MIN/MIN
+MIN MIN MAX 1/MIN/MIN
+MIN MIN MIN 1/MIN/MIN
+
+>>> start until end <<<
+
+start end step length/first/last
+-----------------------------------------
+0 0 0 0
+0 0 -1 0
+0 0 1 0
+0 0 -2 0
+0 0 2 0
+0 0 -3 0
+0 0 3 0
+0 0 17 0
+0 0 127 0
+0 0 MIN+1 0
+0 0 MAX 0
+0 0 MIN 0
+0 -1 0 0
+0 -1 -1 0
+0 -1 1 0
+0 -1 -2 0
+0 -1 2 0
+0 -1 -3 0
+0 -1 3 0
+0 -1 17 0
+0 -1 127 0
+0 -1 MIN+1 0
+0 -1 MAX 0
+0 -1 MIN 0
+0 1 0 1/0/0
+0 1 -1 1/0/0
+0 1 1 1/0/0
+0 1 -2 1/0/0
+0 1 2 1/0/0
+0 1 -3 1/0/0
+0 1 3 1/0/0
+0 1 17 1/0/0
+0 1 127 1/0/0
+0 1 MIN+1 1/0/0
+0 1 MAX 1/0/0
+0 1 MIN 1/0/0
+0 3 0 3/0/2
+0 3 -1 3/0/2
+0 3 1 3/0/2
+0 3 -2 3/0/2
+0 3 2 3/0/2
+0 3 -3 3/0/2
+0 3 3 3/0/2
+0 3 17 3/0/2
+0 3 127 3/0/2
+0 3 MIN+1 3/0/2
+0 3 MAX 3/0/2
+0 3 MIN 3/0/2
+0 MIN+1 0 0
+0 MIN+1 -1 0
+0 MIN+1 1 0
+0 MIN+1 -2 0
+0 MIN+1 2 0
+0 MIN+1 -3 0
+0 MIN+1 3 0
+0 MIN+1 17 0
+0 MIN+1 127 0
+0 MIN+1 MIN+1 0
+0 MIN+1 MAX 0
+0 MIN+1 MIN 0
+0 MAX 0 MAX/0/MAX-1
+0 MAX -1 MAX/0/MAX-1
+0 MAX 1 MAX/0/MAX-1
+0 MAX -2 MAX/0/MAX-1
+0 MAX 2 MAX/0/MAX-1
+0 MAX -3 MAX/0/MAX-1
+0 MAX 3 MAX/0/MAX-1
+0 MAX 17 MAX/0/MAX-1
+0 MAX 127 MAX/0/MAX-1
+0 MAX MIN+1 MAX/0/MAX-1
+0 MAX MAX MAX/0/MAX-1
+0 MAX MIN MAX/0/MAX-1
+0 MIN 0 0
+0 MIN -1 0
+0 MIN 1 0
+0 MIN -2 0
+0 MIN 2 0
+0 MIN -3 0
+0 MIN 3 0
+0 MIN 17 0
+0 MIN 127 0
+0 MIN MIN+1 0
+0 MIN MAX 0
+0 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+-1 0 0 1/-1/-1
+-1 0 -1 1/-1/-1
+-1 0 1 1/-1/-1
+-1 0 -2 1/-1/-1
+-1 0 2 1/-1/-1
+-1 0 -3 1/-1/-1
+-1 0 3 1/-1/-1
+-1 0 17 1/-1/-1
+-1 0 127 1/-1/-1
+-1 0 MIN+1 1/-1/-1
+-1 0 MAX 1/-1/-1
+-1 0 MIN 1/-1/-1
+-1 -1 0 0
+-1 -1 -1 0
+-1 -1 1 0
+-1 -1 -2 0
+-1 -1 2 0
+-1 -1 -3 0
+-1 -1 3 0
+-1 -1 17 0
+-1 -1 127 0
+-1 -1 MIN+1 0
+-1 -1 MAX 0
+-1 -1 MIN 0
+-1 1 0 2/-1/0
+-1 1 -1 2/-1/0
+-1 1 1 2/-1/0
+-1 1 -2 2/-1/0
+-1 1 2 2/-1/0
+-1 1 -3 2/-1/0
+-1 1 3 2/-1/0
+-1 1 17 2/-1/0
+-1 1 127 2/-1/0
+-1 1 MIN+1 2/-1/0
+-1 1 MAX 2/-1/0
+-1 1 MIN 2/-1/0
+-1 3 0 4/-1/2
+-1 3 -1 4/-1/2
+-1 3 1 4/-1/2
+-1 3 -2 4/-1/2
+-1 3 2 4/-1/2
+-1 3 -3 4/-1/2
+-1 3 3 4/-1/2
+-1 3 17 4/-1/2
+-1 3 127 4/-1/2
+-1 3 MIN+1 4/-1/2
+-1 3 MAX 4/-1/2
+-1 3 MIN 4/-1/2
+-1 MIN+1 0 0
+-1 MIN+1 -1 0
+-1 MIN+1 1 0
+-1 MIN+1 -2 0
+-1 MIN+1 2 0
+-1 MIN+1 -3 0
+-1 MIN+1 3 0
+-1 MIN+1 17 0
+-1 MIN+1 127 0
+-1 MIN+1 MIN+1 0
+-1 MIN+1 MAX 0
+-1 MIN+1 MIN 0
+-1 MAX 0 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -1 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 1 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -2 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 2 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -3 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 3 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 17 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX 127 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX MIN+1 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX MAX ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX MIN ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MIN 0 0
+-1 MIN -1 0
+-1 MIN 1 0
+-1 MIN -2 0
+-1 MIN 2 0
+-1 MIN -3 0
+-1 MIN 3 0
+-1 MIN 17 0
+-1 MIN 127 0
+-1 MIN MIN+1 0
+-1 MIN MAX 0
+-1 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+1 0 0 0
+1 0 -1 0
+1 0 1 0
+1 0 -2 0
+1 0 2 0
+1 0 -3 0
+1 0 3 0
+1 0 17 0
+1 0 127 0
+1 0 MIN+1 0
+1 0 MAX 0
+1 0 MIN 0
+1 -1 0 0
+1 -1 -1 0
+1 -1 1 0
+1 -1 -2 0
+1 -1 2 0
+1 -1 -3 0
+1 -1 3 0
+1 -1 17 0
+1 -1 127 0
+1 -1 MIN+1 0
+1 -1 MAX 0
+1 -1 MIN 0
+1 1 0 0
+1 1 -1 0
+1 1 1 0
+1 1 -2 0
+1 1 2 0
+1 1 -3 0
+1 1 3 0
+1 1 17 0
+1 1 127 0
+1 1 MIN+1 0
+1 1 MAX 0
+1 1 MIN 0
+1 3 0 2/1/2
+1 3 -1 2/1/2
+1 3 1 2/1/2
+1 3 -2 2/1/2
+1 3 2 2/1/2
+1 3 -3 2/1/2
+1 3 3 2/1/2
+1 3 17 2/1/2
+1 3 127 2/1/2
+1 3 MIN+1 2/1/2
+1 3 MAX 2/1/2
+1 3 MIN 2/1/2
+1 MIN+1 0 0
+1 MIN+1 -1 0
+1 MIN+1 1 0
+1 MIN+1 -2 0
+1 MIN+1 2 0
+1 MIN+1 -3 0
+1 MIN+1 3 0
+1 MIN+1 17 0
+1 MIN+1 127 0
+1 MIN+1 MIN+1 0
+1 MIN+1 MAX 0
+1 MIN+1 MIN 0
+1 MAX 0 MAX-1/1/MAX-1
+1 MAX -1 MAX-1/1/MAX-1
+1 MAX 1 MAX-1/1/MAX-1
+1 MAX -2 MAX-1/1/MAX-1
+1 MAX 2 MAX-1/1/MAX-1
+1 MAX -3 MAX-1/1/MAX-1
+1 MAX 3 MAX-1/1/MAX-1
+1 MAX 17 MAX-1/1/MAX-1
+1 MAX 127 MAX-1/1/MAX-1
+1 MAX MIN+1 MAX-1/1/MAX-1
+1 MAX MAX MAX-1/1/MAX-1
+1 MAX MIN MAX-1/1/MAX-1
+1 MIN 0 0
+1 MIN -1 0
+1 MIN 1 0
+1 MIN -2 0
+1 MIN 2 0
+1 MIN -3 0
+1 MIN 3 0
+1 MIN 17 0
+1 MIN 127 0
+1 MIN MIN+1 0
+1 MIN MAX 0
+1 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+3 0 0 0
+3 0 -1 0
+3 0 1 0
+3 0 -2 0
+3 0 2 0
+3 0 -3 0
+3 0 3 0
+3 0 17 0
+3 0 127 0
+3 0 MIN+1 0
+3 0 MAX 0
+3 0 MIN 0
+3 -1 0 0
+3 -1 -1 0
+3 -1 1 0
+3 -1 -2 0
+3 -1 2 0
+3 -1 -3 0
+3 -1 3 0
+3 -1 17 0
+3 -1 127 0
+3 -1 MIN+1 0
+3 -1 MAX 0
+3 -1 MIN 0
+3 1 0 0
+3 1 -1 0
+3 1 1 0
+3 1 -2 0
+3 1 2 0
+3 1 -3 0
+3 1 3 0
+3 1 17 0
+3 1 127 0
+3 1 MIN+1 0
+3 1 MAX 0
+3 1 MIN 0
+3 3 0 0
+3 3 -1 0
+3 3 1 0
+3 3 -2 0
+3 3 2 0
+3 3 -3 0
+3 3 3 0
+3 3 17 0
+3 3 127 0
+3 3 MIN+1 0
+3 3 MAX 0
+3 3 MIN 0
+3 MIN+1 0 0
+3 MIN+1 -1 0
+3 MIN+1 1 0
+3 MIN+1 -2 0
+3 MIN+1 2 0
+3 MIN+1 -3 0
+3 MIN+1 3 0
+3 MIN+1 17 0
+3 MIN+1 127 0
+3 MIN+1 MIN+1 0
+3 MIN+1 MAX 0
+3 MIN+1 MIN 0
+3 MAX 0 MAX-3/3/MAX-1
+3 MAX -1 MAX-3/3/MAX-1
+3 MAX 1 MAX-3/3/MAX-1
+3 MAX -2 MAX-3/3/MAX-1
+3 MAX 2 MAX-3/3/MAX-1
+3 MAX -3 MAX-3/3/MAX-1
+3 MAX 3 MAX-3/3/MAX-1
+3 MAX 17 MAX-3/3/MAX-1
+3 MAX 127 MAX-3/3/MAX-1
+3 MAX MIN+1 MAX-3/3/MAX-1
+3 MAX MAX MAX-3/3/MAX-1
+3 MAX MIN MAX-3/3/MAX-1
+3 MIN 0 0
+3 MIN -1 0
+3 MIN 1 0
+3 MIN -2 0
+3 MIN 2 0
+3 MIN -3 0
+3 MIN 3 0
+3 MIN 17 0
+3 MIN 127 0
+3 MIN MIN+1 0
+3 MIN MAX 0
+3 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+MIN+1 0 0 MAX/MIN+1/-1
+MIN+1 0 -1 MAX/MIN+1/-1
+MIN+1 0 1 MAX/MIN+1/-1
+MIN+1 0 -2 MAX/MIN+1/-1
+MIN+1 0 2 MAX/MIN+1/-1
+MIN+1 0 -3 MAX/MIN+1/-1
+MIN+1 0 3 MAX/MIN+1/-1
+MIN+1 0 17 MAX/MIN+1/-1
+MIN+1 0 127 MAX/MIN+1/-1
+MIN+1 0 MIN+1 MAX/MIN+1/-1
+MIN+1 0 MAX MAX/MIN+1/-1
+MIN+1 0 MIN MAX/MIN+1/-1
+MIN+1 -1 0 MAX-1/MIN+1/-2
+MIN+1 -1 -1 MAX-1/MIN+1/-2
+MIN+1 -1 1 MAX-1/MIN+1/-2
+MIN+1 -1 -2 MAX-1/MIN+1/-2
+MIN+1 -1 2 MAX-1/MIN+1/-2
+MIN+1 -1 -3 MAX-1/MIN+1/-2
+MIN+1 -1 3 MAX-1/MIN+1/-2
+MIN+1 -1 17 MAX-1/MIN+1/-2
+MIN+1 -1 127 MAX-1/MIN+1/-2
+MIN+1 -1 MIN+1 MAX-1/MIN+1/-2
+MIN+1 -1 MAX MAX-1/MIN+1/-2
+MIN+1 -1 MIN MAX-1/MIN+1/-2
+MIN+1 1 0 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -2 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 2 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -3 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 3 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 17 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 127 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 MAX ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 MIN ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 0 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -2 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 2 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -3 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 3 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 17 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 127 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 MAX ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 MIN ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MIN+1 0 0
+MIN+1 MIN+1 -1 0
+MIN+1 MIN+1 1 0
+MIN+1 MIN+1 -2 0
+MIN+1 MIN+1 2 0
+MIN+1 MIN+1 -3 0
+MIN+1 MIN+1 3 0
+MIN+1 MIN+1 17 0
+MIN+1 MIN+1 127 0
+MIN+1 MIN+1 MIN+1 0
+MIN+1 MIN+1 MAX 0
+MIN+1 MIN+1 MIN 0
+MIN+1 MAX 0 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -2 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -3 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 3 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 17 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX 127 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX MAX ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX MIN ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MIN 0 0
+MIN+1 MIN -1 0
+MIN+1 MIN 1 0
+MIN+1 MIN -2 0
+MIN+1 MIN 2 0
+MIN+1 MIN -3 0
+MIN+1 MIN 3 0
+MIN+1 MIN 17 0
+MIN+1 MIN 127 0
+MIN+1 MIN MIN+1 0
+MIN+1 MIN MAX 0
+MIN+1 MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+MAX 0 0 0
+MAX 0 -1 0
+MAX 0 1 0
+MAX 0 -2 0
+MAX 0 2 0
+MAX 0 -3 0
+MAX 0 3 0
+MAX 0 17 0
+MAX 0 127 0
+MAX 0 MIN+1 0
+MAX 0 MAX 0
+MAX 0 MIN 0
+MAX -1 0 0
+MAX -1 -1 0
+MAX -1 1 0
+MAX -1 -2 0
+MAX -1 2 0
+MAX -1 -3 0
+MAX -1 3 0
+MAX -1 17 0
+MAX -1 127 0
+MAX -1 MIN+1 0
+MAX -1 MAX 0
+MAX -1 MIN 0
+MAX 1 0 0
+MAX 1 -1 0
+MAX 1 1 0
+MAX 1 -2 0
+MAX 1 2 0
+MAX 1 -3 0
+MAX 1 3 0
+MAX 1 17 0
+MAX 1 127 0
+MAX 1 MIN+1 0
+MAX 1 MAX 0
+MAX 1 MIN 0
+MAX 3 0 0
+MAX 3 -1 0
+MAX 3 1 0
+MAX 3 -2 0
+MAX 3 2 0
+MAX 3 -3 0
+MAX 3 3 0
+MAX 3 17 0
+MAX 3 127 0
+MAX 3 MIN+1 0
+MAX 3 MAX 0
+MAX 3 MIN 0
+MAX MIN+1 0 0
+MAX MIN+1 -1 0
+MAX MIN+1 1 0
+MAX MIN+1 -2 0
+MAX MIN+1 2 0
+MAX MIN+1 -3 0
+MAX MIN+1 3 0
+MAX MIN+1 17 0
+MAX MIN+1 127 0
+MAX MIN+1 MIN+1 0
+MAX MIN+1 MAX 0
+MAX MIN+1 MIN 0
+MAX MAX 0 0
+MAX MAX -1 0
+MAX MAX 1 0
+MAX MAX -2 0
+MAX MAX 2 0
+MAX MAX -3 0
+MAX MAX 3 0
+MAX MAX 17 0
+MAX MAX 127 0
+MAX MAX MIN+1 0
+MAX MAX MAX 0
+MAX MAX MIN 0
+MAX MIN 0 0
+MAX MIN -1 0
+MAX MIN 1 0
+MAX MIN -2 0
+MAX MIN 2 0
+MAX MIN -3 0
+MAX MIN 3 0
+MAX MIN 17 0
+MAX MIN 127 0
+MAX MIN MIN+1 0
+MAX MIN MAX 0
+MAX MIN MIN 0
+
+start end step length/first/last
+-----------------------------------------
+MIN 0 0 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -3 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 3 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 17 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 127 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 MAX ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 MIN ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN -1 0 MAX/MIN/-2
+MIN -1 -1 MAX/MIN/-2
+MIN -1 1 MAX/MIN/-2
+MIN -1 -2 MAX/MIN/-2
+MIN -1 2 MAX/MIN/-2
+MIN -1 -3 MAX/MIN/-2
+MIN -1 3 MAX/MIN/-2
+MIN -1 17 MAX/MIN/-2
+MIN -1 127 MAX/MIN/-2
+MIN -1 MIN+1 MAX/MIN/-2
+MIN -1 MAX MAX/MIN/-2
+MIN -1 MIN MAX/MIN/-2
+MIN 1 0 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -3 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 3 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 17 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 127 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 MAX ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 MIN ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 0 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -3 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 3 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 17 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 127 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 MAX ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 MIN ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MIN+1 0 1/MIN/MIN
+MIN MIN+1 -1 1/MIN/MIN
+MIN MIN+1 1 1/MIN/MIN
+MIN MIN+1 -2 1/MIN/MIN
+MIN MIN+1 2 1/MIN/MIN
+MIN MIN+1 -3 1/MIN/MIN
+MIN MIN+1 3 1/MIN/MIN
+MIN MIN+1 17 1/MIN/MIN
+MIN MIN+1 127 1/MIN/MIN
+MIN MIN+1 MIN+1 1/MIN/MIN
+MIN MIN+1 MAX 1/MIN/MIN
+MIN MIN+1 MIN 1/MIN/MIN
+MIN MAX 0 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -3 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 3 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 17 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX 127 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX MIN+1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX MAX ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX MIN ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MIN 0 0
+MIN MIN -1 0
+MIN MIN 1 0
+MIN MIN -2 0
+MIN MIN 2 0
+MIN MIN -3 0
+MIN MIN 3 0
+MIN MIN 17 0
+MIN MIN 127 0
+MIN MIN MIN+1 0
+MIN MIN MAX 0
+MIN MIN MIN 0
+
+>>> start until end by step <<<
+
+start end step length/first/last
+-----------------------------------------
+0 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 0 -1 0
+0 0 1 0
+0 0 -2 0
+0 0 2 0
+0 0 -3 0
+0 0 3 0
+0 0 17 0
+0 0 127 0
+0 0 MIN+1 0
+0 0 MAX 0
+0 0 MIN 0
+0 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 -1 -1 1/0/0
+0 -1 1 0
+0 -1 -2 1/0/0
+0 -1 2 0
+0 -1 -3 1/0/0
+0 -1 3 0
+0 -1 17 0
+0 -1 127 0
+0 -1 MIN+1 1/0/0
+0 -1 MAX 0
+0 -1 MIN 1/0/0
+0 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 1 -1 0
+0 1 1 1/0/0
+0 1 -2 0
+0 1 2 1/0/0
+0 1 -3 0
+0 1 3 1/0/0
+0 1 17 1/0/0
+0 1 127 1/0/0
+0 1 MIN+1 0
+0 1 MAX 1/0/0
+0 1 MIN 0
+0 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 3 -1 0
+0 3 1 3/0/2
+0 3 -2 0
+0 3 2 2/0/2
+0 3 -3 0
+0 3 3 1/0/0
+0 3 17 1/0/0
+0 3 127 1/0/0
+0 3 MIN+1 0
+0 3 MAX 1/0/0
+0 3 MIN 0
+0 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MIN+1 -1 MAX/0/MIN+2
+0 MIN+1 1 0
+0 MIN+1 -2 1073741824/0/MIN+2
+0 MIN+1 2 0
+0 MIN+1 -3 715827883/0/MIN+2
+0 MIN+1 3 0
+0 MIN+1 17 0
+0 MIN+1 127 0
+0 MIN+1 MIN+1 1/0/0
+0 MIN+1 MAX 0
+0 MIN+1 MIN 1/0/0
+0 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MAX -1 0
+0 MAX 1 MAX/0/MAX-1
+0 MAX -2 0
+0 MAX 2 1073741824/0/MAX-1
+0 MAX -3 0
+0 MAX 3 715827883/0/MAX-1
+0 MAX 17 126322568/0/MAX-8
+0 MAX 127 16909321/0/MAX-7
+0 MAX MIN+1 0
+0 MAX MAX 1/0/0
+0 MAX MIN 0
+0 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+0 MIN -1 ---
+ java.lang.IllegalArgumentException: 0 until -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+0 MIN 1 0
+0 MIN -2 1073741824/0/MIN+2
+0 MIN 2 0
+0 MIN -3 715827883/0/MIN+2
+0 MIN 3 0
+0 MIN 17 0
+0 MIN 127 0
+0 MIN MIN+1 2/0/MIN+1
+0 MIN MAX 0
+0 MIN MIN 1/0/0
+
+start end step length/first/last
+-----------------------------------------
+-1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 0 -1 0
+-1 0 1 1/-1/-1
+-1 0 -2 0
+-1 0 2 1/-1/-1
+-1 0 -3 0
+-1 0 3 1/-1/-1
+-1 0 17 1/-1/-1
+-1 0 127 1/-1/-1
+-1 0 MIN+1 0
+-1 0 MAX 1/-1/-1
+-1 0 MIN 0
+-1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 -1 -1 0
+-1 -1 1 0
+-1 -1 -2 0
+-1 -1 2 0
+-1 -1 -3 0
+-1 -1 3 0
+-1 -1 17 0
+-1 -1 127 0
+-1 -1 MIN+1 0
+-1 -1 MAX 0
+-1 -1 MIN 0
+-1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 1 -1 0
+-1 1 1 2/-1/0
+-1 1 -2 0
+-1 1 2 1/-1/-1
+-1 1 -3 0
+-1 1 3 1/-1/-1
+-1 1 17 1/-1/-1
+-1 1 127 1/-1/-1
+-1 1 MIN+1 0
+-1 1 MAX 1/-1/-1
+-1 1 MIN 0
+-1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 3 -1 0
+-1 3 1 4/-1/2
+-1 3 -2 0
+-1 3 2 2/-1/1
+-1 3 -3 0
+-1 3 3 2/-1/2
+-1 3 17 1/-1/-1
+-1 3 127 1/-1/-1
+-1 3 MIN+1 0
+-1 3 MAX 1/-1/-1
+-1 3 MIN 0
+-1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MIN+1 -1 MAX-1/-1/MIN+2
+-1 MIN+1 1 0
+-1 MIN+1 -2 1073741823/-1/MIN+3
+-1 MIN+1 2 0
+-1 MIN+1 -3 715827882/-1/MIN+4
+-1 MIN+1 3 0
+-1 MIN+1 17 0
+-1 MIN+1 127 0
+-1 MIN+1 MIN+1 1/-1/-1
+-1 MIN+1 MAX 0
+-1 MIN+1 MIN 1/-1/-1
+-1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MAX -1 0
+-1 MAX 1 ---
+ java.lang.IllegalArgumentException: -1 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+-1 MAX -2 0
+-1 MAX 2 1073741824/-1/MAX-2
+-1 MAX -3 0
+-1 MAX 3 715827883/-1/MAX-2
+-1 MAX 17 126322568/-1/MAX-9
+-1 MAX 127 16909321/-1/MAX-8
+-1 MAX MIN+1 0
+-1 MAX MAX 2/-1/MAX-1
+-1 MAX MIN 0
+-1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+-1 MIN -1 MAX/-1/MIN+1
+-1 MIN 1 0
+-1 MIN -2 1073741824/-1/MIN+1
+-1 MIN 2 0
+-1 MIN -3 715827883/-1/MIN+1
+-1 MIN 3 0
+-1 MIN 17 0
+-1 MIN 127 0
+-1 MIN MIN+1 1/-1/-1
+-1 MIN MAX 0
+-1 MIN MIN 1/-1/-1
+
+start end step length/first/last
+-----------------------------------------
+1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 0 -1 1/1/1
+1 0 1 0
+1 0 -2 1/1/1
+1 0 2 0
+1 0 -3 1/1/1
+1 0 3 0
+1 0 17 0
+1 0 127 0
+1 0 MIN+1 1/1/1
+1 0 MAX 0
+1 0 MIN 1/1/1
+1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 -1 -1 2/1/0
+1 -1 1 0
+1 -1 -2 1/1/1
+1 -1 2 0
+1 -1 -3 1/1/1
+1 -1 3 0
+1 -1 17 0
+1 -1 127 0
+1 -1 MIN+1 1/1/1
+1 -1 MAX 0
+1 -1 MIN 1/1/1
+1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 1 -1 0
+1 1 1 0
+1 1 -2 0
+1 1 2 0
+1 1 -3 0
+1 1 3 0
+1 1 17 0
+1 1 127 0
+1 1 MIN+1 0
+1 1 MAX 0
+1 1 MIN 0
+1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 3 -1 0
+1 3 1 2/1/2
+1 3 -2 0
+1 3 2 1/1/1
+1 3 -3 0
+1 3 3 1/1/1
+1 3 17 1/1/1
+1 3 127 1/1/1
+1 3 MIN+1 0
+1 3 MAX 1/1/1
+1 3 MIN 0
+1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 1 until -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+1 MIN+1 1 0
+1 MIN+1 -2 1073741824/1/MIN+3
+1 MIN+1 2 0
+1 MIN+1 -3 715827883/1/MIN+3
+1 MIN+1 3 0
+1 MIN+1 17 0
+1 MIN+1 127 0
+1 MIN+1 MIN+1 2/1/MIN+2
+1 MIN+1 MAX 0
+1 MIN+1 MIN 1/1/1
+1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MAX -1 0
+1 MAX 1 MAX-1/1/MAX-1
+1 MAX -2 0
+1 MAX 2 1073741823/1/MAX-2
+1 MAX -3 0
+1 MAX 3 715827882/1/MAX-3
+1 MAX 17 126322568/1/MAX-7
+1 MAX 127 16909321/1/MAX-6
+1 MAX MIN+1 0
+1 MAX MAX 1/1/1
+1 MAX MIN 0
+1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+1 MIN -1 ---
+ java.lang.IllegalArgumentException: 1 until -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+1 MIN 1 0
+1 MIN -2 1073741825/1/MIN+1
+1 MIN 2 0
+1 MIN -3 715827883/1/MIN+3
+1 MIN 3 0
+1 MIN 17 0
+1 MIN 127 0
+1 MIN MIN+1 2/1/MIN+2
+1 MIN MAX 0
+1 MIN MIN 2/1/MIN+1
+
+start end step length/first/last
+-----------------------------------------
+3 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 0 -1 3/3/1
+3 0 1 0
+3 0 -2 2/3/1
+3 0 2 0
+3 0 -3 1/3/3
+3 0 3 0
+3 0 17 0
+3 0 127 0
+3 0 MIN+1 1/3/3
+3 0 MAX 0
+3 0 MIN 1/3/3
+3 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 -1 -1 4/3/0
+3 -1 1 0
+3 -1 -2 2/3/1
+3 -1 2 0
+3 -1 -3 2/3/0
+3 -1 3 0
+3 -1 17 0
+3 -1 127 0
+3 -1 MIN+1 1/3/3
+3 -1 MAX 0
+3 -1 MIN 1/3/3
+3 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 1 -1 2/3/2
+3 1 1 0
+3 1 -2 1/3/3
+3 1 2 0
+3 1 -3 1/3/3
+3 1 3 0
+3 1 17 0
+3 1 127 0
+3 1 MIN+1 1/3/3
+3 1 MAX 0
+3 1 MIN 1/3/3
+3 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 3 -1 0
+3 3 1 0
+3 3 -2 0
+3 3 2 0
+3 3 -3 0
+3 3 3 0
+3 3 17 0
+3 3 127 0
+3 3 MIN+1 0
+3 3 MAX 0
+3 3 MIN 0
+3 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 3 until -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+3 MIN+1 1 0
+3 MIN+1 -2 1073741825/3/MIN+3
+3 MIN+1 2 0
+3 MIN+1 -3 715827884/3/MIN+2
+3 MIN+1 3 0
+3 MIN+1 17 0
+3 MIN+1 127 0
+3 MIN+1 MIN+1 2/3/MIN+4
+3 MIN+1 MAX 0
+3 MIN+1 MIN 2/3/MIN+3
+3 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MAX -1 0
+3 MAX 1 MAX-3/3/MAX-1
+3 MAX -2 0
+3 MAX 2 1073741822/3/MAX-2
+3 MAX -3 0
+3 MAX 3 715827882/3/MAX-1
+3 MAX 17 126322568/3/MAX-5
+3 MAX 127 16909321/3/MAX-4
+3 MAX MIN+1 0
+3 MAX MAX 1/3/3
+3 MAX MIN 0
+3 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+3 MIN -1 ---
+ java.lang.IllegalArgumentException: 3 until -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+3 MIN 1 0
+3 MIN -2 1073741826/3/MIN+1
+3 MIN 2 0
+3 MIN -3 715827884/3/MIN+2
+3 MIN 3 0
+3 MIN 17 0
+3 MIN 127 0
+3 MIN MIN+1 2/3/MIN+4
+3 MIN MAX 0
+3 MIN MIN 2/3/MIN+3
+
+start end step length/first/last
+-----------------------------------------
+MIN+1 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 0 -1 0
+MIN+1 0 1 MAX/MIN+1/-1
+MIN+1 0 -2 0
+MIN+1 0 2 1073741824/MIN+1/-1
+MIN+1 0 -3 0
+MIN+1 0 3 715827883/MIN+1/-1
+MIN+1 0 17 126322568/MIN+1/-8
+MIN+1 0 127 16909321/MIN+1/-7
+MIN+1 0 MIN+1 0
+MIN+1 0 MAX 1/MIN+1/MIN+1
+MIN+1 0 MIN 0
+MIN+1 -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 -1 -1 0
+MIN+1 -1 1 MAX-1/MIN+1/-2
+MIN+1 -1 -2 0
+MIN+1 -1 2 1073741823/MIN+1/-3
+MIN+1 -1 -3 0
+MIN+1 -1 3 715827882/MIN+1/-4
+MIN+1 -1 17 126322568/MIN+1/-8
+MIN+1 -1 127 16909321/MIN+1/-7
+MIN+1 -1 MIN+1 0
+MIN+1 -1 MAX 1/MIN+1/MIN+1
+MIN+1 -1 MIN 0
+MIN+1 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 1 -1 0
+MIN+1 1 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 1 -2 0
+MIN+1 1 2 1073741824/MIN+1/-1
+MIN+1 1 -3 0
+MIN+1 1 3 715827883/MIN+1/-1
+MIN+1 1 17 126322568/MIN+1/-8
+MIN+1 1 127 16909321/MIN+1/-7
+MIN+1 1 MIN+1 0
+MIN+1 1 MAX 2/MIN+1/0
+MIN+1 1 MIN 0
+MIN+1 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 3 -1 0
+MIN+1 3 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 3 -2 0
+MIN+1 3 2 1073741825/MIN+1/1
+MIN+1 3 -3 0
+MIN+1 3 3 715827884/MIN+1/2
+MIN+1 3 17 126322568/MIN+1/-8
+MIN+1 3 127 16909321/MIN+1/-7
+MIN+1 3 MIN+1 0
+MIN+1 3 MAX 2/MIN+1/0
+MIN+1 3 MIN 0
+MIN+1 MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MIN+1 -1 0
+MIN+1 MIN+1 1 0
+MIN+1 MIN+1 -2 0
+MIN+1 MIN+1 2 0
+MIN+1 MIN+1 -3 0
+MIN+1 MIN+1 3 0
+MIN+1 MIN+1 17 0
+MIN+1 MIN+1 127 0
+MIN+1 MIN+1 MIN+1 0
+MIN+1 MIN+1 MAX 0
+MIN+1 MIN+1 MIN 0
+MIN+1 MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MAX -1 0
+MIN+1 MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483647 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN+1 MAX -2 0
+MIN+1 MAX 2 MAX/MIN+1/MAX-2
+MIN+1 MAX -3 0
+MIN+1 MAX 3 1431655765/MIN+1/MAX-2
+MIN+1 MAX 17 252645135/MIN+1/MAX-16
+MIN+1 MAX 127 33818641/MIN+1/MAX-14
+MIN+1 MAX MIN+1 0
+MIN+1 MAX MAX 2/MIN+1/0
+MIN+1 MAX MIN 0
+MIN+1 MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN+1 MIN -1 1/MIN+1/MIN+1
+MIN+1 MIN 1 0
+MIN+1 MIN -2 1/MIN+1/MIN+1
+MIN+1 MIN 2 0
+MIN+1 MIN -3 1/MIN+1/MIN+1
+MIN+1 MIN 3 0
+MIN+1 MIN 17 0
+MIN+1 MIN 127 0
+MIN+1 MIN MIN+1 1/MIN+1/MIN+1
+MIN+1 MIN MAX 0
+MIN+1 MIN MIN 1/MIN+1/MIN+1
+
+start end step length/first/last
+-----------------------------------------
+MAX 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 0 -1 MAX/MAX/1
+MAX 0 1 0
+MAX 0 -2 1073741824/MAX/1
+MAX 0 2 0
+MAX 0 -3 715827883/MAX/1
+MAX 0 3 0
+MAX 0 17 0
+MAX 0 127 0
+MAX 0 MIN+1 1/MAX/MAX
+MAX 0 MAX 0
+MAX 0 MIN 1/MAX/MAX
+MAX -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX -1 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 until -1 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX -1 1 0
+MAX -1 -2 1073741824/MAX/1
+MAX -1 2 0
+MAX -1 -3 715827883/MAX/1
+MAX -1 3 0
+MAX -1 17 0
+MAX -1 127 0
+MAX -1 MIN+1 2/MAX/0
+MAX -1 MAX 0
+MAX -1 MIN 1/MAX/MAX
+MAX 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 1 -1 MAX-1/MAX/2
+MAX 1 1 0
+MAX 1 -2 1073741823/MAX/3
+MAX 1 2 0
+MAX 1 -3 715827882/MAX/4
+MAX 1 3 0
+MAX 1 17 0
+MAX 1 127 0
+MAX 1 MIN+1 1/MAX/MAX
+MAX 1 MAX 0
+MAX 1 MIN 1/MAX/MAX
+MAX 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX 3 -1 MAX-3/MAX/4
+MAX 3 1 0
+MAX 3 -2 1073741822/MAX/5
+MAX 3 2 0
+MAX 3 -3 715827882/MAX/4
+MAX 3 3 0
+MAX 3 17 0
+MAX 3 127 0
+MAX 3 MIN+1 1/MAX/MAX
+MAX 3 MAX 0
+MAX 3 MIN 1/MAX/MAX
+MAX MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MIN+1 -1 ---
+ java.lang.IllegalArgumentException: 2147483647 until -2147483647 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN+1 1 0
+MAX MIN+1 -2 MAX/MAX/MIN+3
+MAX MIN+1 2 0
+MAX MIN+1 -3 1431655765/MAX/MIN+3
+MAX MIN+1 3 0
+MAX MIN+1 17 0
+MAX MIN+1 127 0
+MAX MIN+1 MIN+1 2/MAX/0
+MAX MIN+1 MAX 0
+MAX MIN+1 MIN 2/MAX/-1
+MAX MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MAX -1 0
+MAX MAX 1 0
+MAX MAX -2 0
+MAX MAX 2 0
+MAX MAX -3 0
+MAX MAX 3 0
+MAX MAX 17 0
+MAX MAX 127 0
+MAX MAX MIN+1 0
+MAX MAX MAX 0
+MAX MAX MIN 0
+MAX MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MAX MIN -1 ---
+ java.lang.IllegalArgumentException: 2147483647 until -2147483648 by -1: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN 1 0
+MAX MIN -2 ---
+ java.lang.IllegalArgumentException: 2147483647 until -2147483648 by -2: seqs cannot contain more than Int.MaxValue elements.
+MAX MIN 2 0
+MAX MIN -3 1431655765/MAX/MIN+3
+MAX MIN 3 0
+MAX MIN 17 0
+MAX MIN 127 0
+MAX MIN MIN+1 3/MAX/MIN+1
+MAX MIN MAX 0
+MAX MIN MIN 2/MAX/-1
+
+start end step length/first/last
+-----------------------------------------
+MIN 0 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 0 -1 0
+MIN 0 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 0 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 0 -2 0
+MIN 0 2 1073741824/MIN/-2
+MIN 0 -3 0
+MIN 0 3 715827883/MIN/-2
+MIN 0 17 126322568/MIN/-9
+MIN 0 127 16909321/MIN/-8
+MIN 0 MIN+1 0
+MIN 0 MAX 2/MIN/-1
+MIN 0 MIN 0
+MIN -1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN -1 -1 0
+MIN -1 1 MAX/MIN/-2
+MIN -1 -2 0
+MIN -1 2 1073741824/MIN/-2
+MIN -1 -3 0
+MIN -1 3 715827883/MIN/-2
+MIN -1 17 126322568/MIN/-9
+MIN -1 127 16909321/MIN/-8
+MIN -1 MIN+1 0
+MIN -1 MAX 1/MIN/MIN
+MIN -1 MIN 0
+MIN 1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 1 -1 0
+MIN 1 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 1 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 1 -2 0
+MIN 1 2 1073741825/MIN/0
+MIN 1 -3 0
+MIN 1 3 715827883/MIN/-2
+MIN 1 17 126322568/MIN/-9
+MIN 1 127 16909321/MIN/-8
+MIN 1 MIN+1 0
+MIN 1 MAX 2/MIN/-1
+MIN 1 MIN 0
+MIN 3 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN 3 -1 0
+MIN 3 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 3 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN 3 -2 0
+MIN 3 2 1073741826/MIN/2
+MIN 3 -3 0
+MIN 3 3 715827884/MIN/1
+MIN 3 17 126322568/MIN/-9
+MIN 3 127 16909321/MIN/-8
+MIN 3 MIN+1 0
+MIN 3 MAX 2/MIN/-1
+MIN 3 MIN 0
+MIN MIN+1 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MIN+1 -1 0
+MIN MIN+1 1 1/MIN/MIN
+MIN MIN+1 -2 0
+MIN MIN+1 2 1/MIN/MIN
+MIN MIN+1 -3 0
+MIN MIN+1 3 1/MIN/MIN
+MIN MIN+1 17 1/MIN/MIN
+MIN MIN+1 127 1/MIN/MIN
+MIN MIN+1 MIN+1 0
+MIN MIN+1 MAX 1/MIN/MIN
+MIN MIN+1 MIN 0
+MIN MAX 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MAX -1 0
+MIN MAX 1 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 1: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -2 0
+MIN MAX 2 ---
+ java.lang.IllegalArgumentException: -2147483648 until 2147483647 by 2: seqs cannot contain more than Int.MaxValue elements.
+MIN MAX -3 0
+MIN MAX 3 1431655765/MIN/MAX-3
+MIN MAX 17 252645135/MIN/MAX-17
+MIN MAX 127 33818641/MIN/MAX-15
+MIN MAX MIN+1 0
+MIN MAX MAX 3/MIN/MAX-1
+MIN MAX MIN 0
+MIN MIN 0 ---
+ java.lang.IllegalArgumentException: step cannot be 0.
+MIN MIN -1 0
+MIN MIN 1 0
+MIN MIN -2 0
+MIN MIN 2 0
+MIN MIN -3 0
+MIN MIN 3 0
+MIN MIN 17 0
+MIN MIN 127 0
+MIN MIN MIN+1 0
+MIN MIN MAX 0
+MIN MIN MIN 0
+
diff --git a/test/files/run/range-unit.scala b/test/files/run/range-unit.scala
new file mode 100644
index 0000000000..ece0d9806c
--- /dev/null
+++ b/test/files/run/range-unit.scala
@@ -0,0 +1,55 @@
+import scala.collection.immutable.Range
+
+object Test {
+ // ha ha, I always forget math.abs(Int.MinValue) == Int.MinValue
+ val numbers = (
+ ( (-3 to 3) ++ List(17, 127, Int.MaxValue, Int.MinValue + 1)
+ ).distinct.sortBy(n => (math.abs(n), n))
+ ) :+ Int.MinValue
+
+ // reducing output a little
+ val endpoints = numbers filterNot Set(-3, -2, 2, 17, 127)
+
+ def num(n: Int) = {
+ val frommax = Int.MaxValue - n
+ val frommin = Int.MinValue - n
+
+ if (n > 0) {
+ if (frommax == 0) "MAX"
+ else if (frommax < 1000) "MAX-" + frommax
+ else "" + n
+ }
+ else {
+ if (frommin == 0) "MIN"
+ else if (frommin > -1000) "MIN+" + (-frommin)
+ else "" + n
+ }
+ }
+
+ def run[T](body: => Range): List[Any] = {
+ try { val r = body ; if (r.isEmpty) List(r.length) else List(num(r.length), num(r.head), num(r.last)) }
+ catch { case e: IllegalArgumentException => List("---\n " + e) }
+ }
+
+ def runGroup(label: String, f: (Int, Int, Int) => Range) {
+ println(">>> " + label + " <<<\n")
+ for (start <- endpoints) {
+ val s = "%-7s %-7s %-7s %s".format("start", "end", "step", "length/first/last")
+ println(s + "\n" + ("-" * s.length))
+ for (end <- endpoints ; step <- numbers) {
+ print("%-7s %-7s %-7s ".format(num(start), num(end), num(step)))
+ println(run(f(start, end, step)).mkString("/"))
+ }
+ println("")
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ runGroup("Range.inclusive", Range.inclusive(_, _, _))
+ runGroup("Range.apply", Range.apply(_, _, _))
+ runGroup("start to end", (x, y, _) => x to y)
+ runGroup("start to end by step", _ to _ by _)
+ runGroup("start until end", (x, y, _) => x until y)
+ runGroup("start until end by step", _ until _ by _)
+ }
+}
diff --git a/test/files/run/si4147.scala b/test/files/run/si4147.scala
new file mode 100644
index 0000000000..c1e2d746a9
--- /dev/null
+++ b/test/files/run/si4147.scala
@@ -0,0 +1,36 @@
+
+
+
+import scala.collection._
+
+
+
+object Test {
+
+ def main(args: Array[String]) {
+ checkElementsAreSorted()
+ checkRangedImpl()
+ }
+
+ def checkElementsAreSorted() {
+ val tree = mutable.SortedSet[Int]()
+ tree ++= List(4, 3, 1, 6, 7, 5, 2)
+ assert(tree == immutable.SortedSet(1, 2, 3, 4, 5, 6, 7))
+ assert(tree.size == 7)
+ }
+
+ def checkRangedImpl() {
+ val tree = mutable.SortedSet[Int](3, 1, 6, 7, 5, 2)
+ val projection = tree.rangeImpl(Some(3), Some(6))
+ assert(projection == immutable.SortedSet(3, 5))
+ assert(projection.size == 2)
+
+ // Let's check that modification are taken into account
+ tree add 4
+ assert(tree == immutable.SortedSet(1, 2, 3, 4, 5, 6, 7))
+ assert(projection == immutable.SortedSet(3, 4, 5))
+ assert(tree.size == 7)
+ assert(projection.size == 3)
+ }
+
+}
diff --git a/test/files/run/si5262.check b/test/files/run/si5262.check
new file mode 100644
index 0000000000..4c7a875de5
--- /dev/null
+++ b/test/files/run/si5262.check
@@ -0,0 +1,2 @@
+List(1, 2, 3, 4)
+List(1, 2, null, 4) \ No newline at end of file
diff --git a/test/files/run/si5262.scala b/test/files/run/si5262.scala
new file mode 100644
index 0000000000..fc4e57aa96
--- /dev/null
+++ b/test/files/run/si5262.scala
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+object Test {
+
+ def serializationDeserialization(obj : Any) {
+ val bos = new java.io.ByteArrayOutputStream()
+ val out = new java.io.ObjectOutputStream(bos)
+ out.writeObject(obj)
+
+ val arr = bos.toByteArray()
+ val in = new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(arr))
+ val o = in.readObject()
+ println(o)
+ }
+
+ def main(args : Array[String]) {
+ serializationDeserialization(List(1,2,3,4))
+ serializationDeserialization(List(1,2,null,4))
+ }
+
+}
diff --git a/test/files/run/si5374.check b/test/files/run/si5374.check
new file mode 100644
index 0000000000..cdf0bc7e5b
--- /dev/null
+++ b/test/files/run/si5374.check
@@ -0,0 +1,3 @@
+ListBuffer(1, 2, 3, 1)
+ListBuffer(1, 2, 3, 1)
+ListBuffer() \ No newline at end of file
diff --git a/test/files/run/si5374.scala b/test/files/run/si5374.scala
new file mode 100644
index 0000000000..a5678c3a81
--- /dev/null
+++ b/test/files/run/si5374.scala
@@ -0,0 +1,42 @@
+
+
+
+import collection.mutable.ListBuffer
+import java.io._
+
+
+
+object Test {
+
+ def main(args: Array[String]) {
+ ticketExample()
+ emptyListBuffer()
+ }
+
+ def ticketExample() {
+ val baos = new ByteArrayOutputStream
+ val oos = new ObjectOutputStream(baos)
+ oos.writeObject( ListBuffer(1,2,3) )
+ val bais = new ByteArrayInputStream( baos.toByteArray )
+ val ois = new ObjectInputStream(bais)
+ val lb = ois.readObject.asInstanceOf[ListBuffer[Int]]
+ val lb2 = ListBuffer[Int]() ++= lb
+
+ lb2 ++= List(1)
+ lb ++= List(1)
+ println(lb)
+ println(lb2)
+ }
+
+ def emptyListBuffer() {
+ val baos = new ByteArrayOutputStream
+ val oos = new ObjectOutputStream(baos)
+ oos.writeObject( ListBuffer() )
+ val bais = new ByteArrayInputStream( baos.toByteArray )
+ val ois = new ObjectInputStream(bais)
+ val lb = ois.readObject.asInstanceOf[ListBuffer[Int]]
+
+ println(lb)
+ }
+
+}
diff --git a/test/files/run/stringInterpolation.check b/test/files/run/stringInterpolation.check
deleted file mode 100644
index b5b63343a8..0000000000
--- a/test/files/run/stringInterpolation.check
+++ /dev/null
@@ -1,2 +0,0 @@
-1 plus 1 is 2
-We have a 1.10% chance of success
diff --git a/test/files/run/stringInterpolation.scala b/test/files/run/stringInterpolation.scala
deleted file mode 100644
index d88f5f6889..0000000000
--- a/test/files/run/stringInterpolation.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-object Test {
- def main(args : Array[String]) : Unit = {
- println("\{1} plus \{1} is \{1 + 1}")
- val x = 1.1
- println("We have a \{ x ;2.2f}% chance of success")
- }
-}
diff --git a/test/files/run/t1987.check b/test/files/run/t1987.check
new file mode 100644
index 0000000000..d2102a4a18
--- /dev/null
+++ b/test/files/run/t1987.check
@@ -0,0 +1,16 @@
+long
+long
+double
+double
+long
+long
+double
+double
+long
+long
+double
+double
+long
+long
+double
+double
diff --git a/test/files/run/t1987.flags b/test/files/run/t1987.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/run/t1987.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/run/t1987.scala b/test/files/run/t1987.scala
new file mode 100644
index 0000000000..4c278ec6a0
--- /dev/null
+++ b/test/files/run/t1987.scala
@@ -0,0 +1,62 @@
+// a.scala
+// Fri Jan 13 11:31:47 PST 2012
+
+package foo {
+ package object bar {
+ def duh(n: Long) = println("long")
+ def duh(n: Double) = println("double")
+
+ def duh2(n: Double) = println("double")
+ def duh2(n: Long) = println("long")
+ }
+ package bar {
+ object Main {
+ def main(args:Array[String]) {
+ duh(33L)
+ bip.bar.duh(33L)
+ duh(33d)
+ bip.bar.duh(33d)
+
+ duh2(33L)
+ bip.bar.duh2(33L)
+ duh2(33d)
+ bip.bar.duh2(33d)
+ }
+ }
+ }
+}
+
+package bip {
+ trait Duh {
+ def duh(n: Long) = println("long")
+ def duh(n: Double) = println("double")
+ }
+ trait Duh2 {
+ def duh2(n: Double) = println("double")
+ def duh2(n: Long) = println("long")
+ }
+
+ package object bar extends Duh with Duh2 { }
+ package bar {
+ object Main {
+ def main(args:Array[String]) {
+ duh(33L)
+ bip.bar.duh(33L)
+ duh(33d)
+ bip.bar.duh(33d)
+
+ duh2(33L)
+ bip.bar.duh2(33L)
+ duh2(33d)
+ bip.bar.duh2(33d)
+ }
+ }
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ foo.bar.Main.main(null)
+ bip.bar.Main.main(null)
+ }
+}
diff --git a/test/files/run/t4835.check b/test/files/run/t4835.check
new file mode 100644
index 0000000000..531c3d7bb6
--- /dev/null
+++ b/test/files/run/t4835.check
@@ -0,0 +1,7 @@
+-1 0 1 2 3 4 5 6 7 8 9
+-1 1 3 5 7 9 11 13 15 17 19
+1 1
+2 1 2
+2 1 A 2
+3 1 2 3
+3 1 A 2 B 3
diff --git a/test/files/run/t4835.scala b/test/files/run/t4835.scala
new file mode 100644
index 0000000000..50d161be40
--- /dev/null
+++ b/test/files/run/t4835.scala
@@ -0,0 +1,38 @@
+/*
+ * Test case for SI-4835. This tests confirm that the fix
+ * doesn't break laziness. To test memory consumption,
+ * I need to confirm that OutOfMemoryError doesn't occur.
+ * I could create such tests. However, such tests consume
+ * too much time and memory.
+ */
+object Test {
+ private final val INFINITE = -1
+ def testStreamIterator(num: Int, stream: Stream[Int]): Unit = {
+ val iter = stream.iterator
+ print(num)
+ // if num == -1, then steram is infinite sequence
+ if (num == INFINITE) {
+ for(i <- 0 until 10) {
+ print(" " + iter.next())
+ }
+ } else {
+ while(iter.hasNext) {
+ print(" " + iter.next())
+ }
+ }
+ println()
+ }
+
+ def main(args: Array[String]): Unit = {
+ import Stream.{from, cons, empty}
+ testStreamIterator(INFINITE, from(0))
+ testStreamIterator(INFINITE, from(0).filter(_ % 2 == 1))
+ testStreamIterator(1, Stream(1))
+ testStreamIterator(2, Stream(1, 2))
+ //Stream with side effect
+ testStreamIterator(2, cons(1, cons({ print(" A"); 2}, empty)))
+ testStreamIterator(3, Stream(1, 2, 3))
+ //Stream with side effect
+ testStreamIterator(3, cons(1, cons({ print(" A"); 2}, cons({ print(" B"); 3}, Stream.empty))))
+ }
+}
diff --git a/test/files/run/t5072.check b/test/files/run/t5072.check
new file mode 100644
index 0000000000..8fe75f55d6
--- /dev/null
+++ b/test/files/run/t5072.check
@@ -0,0 +1,14 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> class C
+defined class C
+
+scala> Thread.currentThread.getContextClassLoader.loadClass(classOf[C].getName)
+res0: Class[_] = class C
+
+scala>
+
+scala>
diff --git a/test/files/run/t5072.scala b/test/files/run/t5072.scala
new file mode 100644
index 0000000000..eef8604ef1
--- /dev/null
+++ b/test/files/run/t5072.scala
@@ -0,0 +1,8 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+class C
+Thread.currentThread.getContextClassLoader.loadClass(classOf[C].getName)
+ """
+}
diff --git a/test/files/run/t5377.check b/test/files/run/t5377.check
new file mode 100644
index 0000000000..7bd0e297bf
--- /dev/null
+++ b/test/files/run/t5377.check
@@ -0,0 +1,18 @@
+1 List(1)
+1 List(1)
+2 List(1, 2) List(2, 1)
+2 List(1, 2) List(2, 1)
+2 List(2, 1) List(1, 2)
+2 List(2, 1) List(1, 2)
+3 List(1, 2, 3) List(1, 3, 2) List(2, 1, 3) List(2, 3, 1) List(3, 1, 2) List(3, 2, 1)
+3 List(1, 2, 3) List(1, 3, 2) List(2, 1, 3) List(2, 3, 1) List(3, 1, 2) List(3, 2, 1)
+3 List(1, 3, 2) List(1, 2, 3) List(3, 1, 2) List(3, 2, 1) List(2, 1, 3) List(2, 3, 1)
+3 List(1, 3, 2) List(1, 2, 3) List(3, 1, 2) List(3, 2, 1) List(2, 1, 3) List(2, 3, 1)
+3 List(2, 1, 3) List(2, 3, 1) List(1, 2, 3) List(1, 3, 2) List(3, 2, 1) List(3, 1, 2)
+3 List(2, 1, 3) List(2, 3, 1) List(1, 2, 3) List(1, 3, 2) List(3, 2, 1) List(3, 1, 2)
+3 List(2, 3, 1) List(2, 1, 3) List(3, 2, 1) List(3, 1, 2) List(1, 2, 3) List(1, 3, 2)
+3 List(2, 3, 1) List(2, 1, 3) List(3, 2, 1) List(3, 1, 2) List(1, 2, 3) List(1, 3, 2)
+3 List(3, 1, 2) List(3, 2, 1) List(1, 3, 2) List(1, 2, 3) List(2, 3, 1) List(2, 1, 3)
+3 List(3, 1, 2) List(3, 2, 1) List(1, 3, 2) List(1, 2, 3) List(2, 3, 1) List(2, 1, 3)
+3 List(3, 2, 1) List(3, 1, 2) List(2, 3, 1) List(2, 1, 3) List(1, 3, 2) List(1, 2, 3)
+3 List(3, 2, 1) List(3, 1, 2) List(2, 3, 1) List(2, 1, 3) List(1, 3, 2) List(1, 2, 3)
diff --git a/test/files/run/t5377.scala b/test/files/run/t5377.scala
new file mode 100644
index 0000000000..2e8fb1a6af
--- /dev/null
+++ b/test/files/run/t5377.scala
@@ -0,0 +1,47 @@
+object Test {
+ def testPermutations1(num: Int, stream: Stream[Int]): Unit = {
+ val perm = stream.permutations
+ print(num)
+ while(perm.hasNext) {
+ print(" " + perm.next().toList)
+ }
+ println()
+ }
+ def testPermutations2(num: Int, stream: List[Int]): Unit = {
+ val perm = stream.permutations
+ print(num)
+ while(perm.hasNext) {
+ print(" " + perm.next().toList)
+ }
+ println()
+ }
+
+ def main(args: Array[String]): Unit = {
+ testPermutations1(1, Stream(1))
+ testPermutations2(1, List(1))
+
+ testPermutations1(2, Stream(1, 2))
+ testPermutations2(2, List(1, 2))
+
+ testPermutations1(2, Stream(2, 1))
+ testPermutations2(2, List(2, 1))
+
+ testPermutations1(3, Stream(1, 2, 3))
+ testPermutations2(3, List(1, 2, 3))
+
+ testPermutations1(3, Stream(1, 3, 2))
+ testPermutations2(3, List(1, 3, 2))
+
+ testPermutations1(3, Stream(2, 1, 3))
+ testPermutations2(3, List(2, 1, 3))
+
+ testPermutations1(3, Stream(2, 3, 1))
+ testPermutations2(3, List(2, 3, 1))
+
+ testPermutations1(3, Stream(3, 1, 2))
+ testPermutations2(3, List(3, 1, 2))
+
+ testPermutations1(3, Stream(3, 2, 1))
+ testPermutations2(3, List(3, 2, 1))
+ }
+}
diff --git a/test/files/run/t5387.scala b/test/files/run/t5387.scala
new file mode 100644
index 0000000000..5d62a005a9
--- /dev/null
+++ b/test/files/run/t5387.scala
@@ -0,0 +1,15 @@
+/*
+ * This tests that the predicate of dropWhile is only evaluated as often as needed, see https://issues.scala-lang.org/browse/SI-5387
+ */
+import scala.collection.immutable.ListMap
+object Test extends App{
+ val subject = ListMap(1->1,2->2,3->3,4->4,5->5)
+ val result = ListMap(3->3,4->4,5->5)
+ assert( result == subject.dropWhile{
+ case (key, value) => {
+ assert( key <= 3, "predicate evaluated more often than needed, key "+key )
+ key < 3
+ }
+ }
+ )
+}
diff --git a/test/files/run/trait-renaming.check b/test/files/run/trait-renaming.check
new file mode 100644
index 0000000000..b2e5affde5
--- /dev/null
+++ b/test/files/run/trait-renaming.check
@@ -0,0 +1,2 @@
+public static int bippy.A$B$1$class.f(bippy.A$B$1)
+public static void bippy.A$B$1$class.$init$(bippy.A$B$1)
diff --git a/test/files/run/trait-renaming/A_1.scala b/test/files/run/trait-renaming/A_1.scala
new file mode 100644
index 0000000000..2c3d4f566f
--- /dev/null
+++ b/test/files/run/trait-renaming/A_1.scala
@@ -0,0 +1,15 @@
+package bippy {
+ class A {
+ def f = {
+ trait B {
+ def f = 5
+ }
+ trait C {
+ def g = 10
+ }
+ new B with C { }
+ }
+
+ def g = Class.forName("bippy.A$B$1$class")
+ }
+}
diff --git a/test/files/run/trait-renaming/B_2.scala b/test/files/run/trait-renaming/B_2.scala
new file mode 100644
index 0000000000..174e929fe2
--- /dev/null
+++ b/test/files/run/trait-renaming/B_2.scala
@@ -0,0 +1,5 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ (new bippy.A).g.getDeclaredMethods.map(_.toString).sorted foreach println
+ }
+}
diff --git a/test/files/run/xml-attribute.check b/test/files/run/xml-attribute.check
new file mode 100644
index 0000000000..3ae2034684
--- /dev/null
+++ b/test/files/run/xml-attribute.check
@@ -0,0 +1,12 @@
+<t></t>
+<t></t>
+<t></t>
+<t></t>
+<t></t>
+<t b="1" d="2"></t>
+<t b="1" d="2"></t>
+<t b="1" d="2"></t>
+<t a="1" d="2"></t>
+<t b="1" d="2"></t>
+<t a="1" b="2" c="3"></t>
+<t g="1" e="2" p:a="3" f:e="4" mgruhu:ji="5"></t> \ No newline at end of file
diff --git a/test/files/run/xml-attribute.scala b/test/files/run/xml-attribute.scala
index 8b261acc94..eb3956c41b 100644
--- a/test/files/run/xml-attribute.scala
+++ b/test/files/run/xml-attribute.scala
@@ -12,12 +12,11 @@ object Test {
assert(noAttr == preAttrNull)
assert(noAttr == preAttrNone)
- val noAttrStr = "<t></t>"
- assert(noAttr.toString() == noAttrStr)
- assert(attrNull.toString() == noAttrStr)
- assert(attrNone.toString() == noAttrStr)
- assert(preAttrNull.toString() == noAttrStr)
- assert(preAttrNone.toString() == noAttrStr)
+ println(noAttr)
+ println(attrNull)
+ println(attrNone)
+ println(preAttrNull)
+ println(preAttrNone)
val xml1 = <t b="1" d="2"/>
val xml2 = <t a={ null: String } p:a={ null: String } b="1" c={ null: String } d="2"/>
@@ -25,9 +24,14 @@ object Test {
assert(xml1 == xml2)
assert(xml1 == xml3)
- val xml1Str = "<t d=\"2\" b=\"1\"></t>"
- assert(xml1.toString() == xml1Str)
- assert(xml2.toString() == xml1Str)
- assert(xml3.toString() == xml1Str)
+ println(xml1)
+ println(xml2)
+ println(xml3)
+
+ // Check if attribute order is retained
+ println(<t a="1" d="2"/>)
+ println(<t b="1" d="2"/>)
+ println(<t a="1" b="2" c="3"/>)
+ println(<t g="1" e="2" p:a="3" f:e="4" mgruhu:ji="5"/>)
}
}
diff --git a/test/files/scalacheck/si4147.scala b/test/files/scalacheck/si4147.scala
new file mode 100644
index 0000000000..1453440ef1
--- /dev/null
+++ b/test/files/scalacheck/si4147.scala
@@ -0,0 +1,67 @@
+import org.scalacheck.Prop.forAll
+import org.scalacheck.Properties
+import org.scalacheck.ConsoleReporter.testStatsEx
+import org.scalacheck.Gen
+import org.scalacheck.ConsoleReporter
+
+
+import collection.mutable
+
+
+object Test extends Properties("Mutable TreeSet") {
+
+ val generator = Gen.listOfN(1000, Gen.chooseNum(0, 1000))
+
+ val denseGenerator = Gen.listOfN(1000, Gen.chooseNum(0, 200))
+
+ property("Insertion doesn't allow duplicates values.") = forAll(generator) { (s: List[Int]) =>
+ {
+ val t = mutable.TreeSet[Int](s: _*)
+ t == s.toSet
+ }
+ }
+
+ property("Verification of size method validity") = forAll(generator) { (s: List[Int]) =>
+ {
+ val t = mutable.TreeSet[Int](s: _*)
+ for (a <- s) {
+ t -= a
+ }
+ t.size == 0
+ }
+ }
+
+ property("All inserted elements are removed") = forAll(generator) { (s: List[Int]) =>
+ {
+ val t = mutable.TreeSet[Int](s: _*)
+ for (a <- s) {
+ t -= a
+ }
+ t == Set()
+ }
+ }
+
+ property("Elements are sorted.") = forAll(generator) { (s: List[Int]) =>
+ {
+ val t = mutable.TreeSet[Int](s: _*)
+ t.toList == s.distinct.sorted
+ }
+ }
+
+ property("Implicit CanBuildFrom resolution succeeds as well as the \"same-result-type\" principle.") =
+ forAll(generator) { (s: List[Int]) =>
+ {
+ val t = mutable.TreeSet[Int](s: _*)
+ val t2 = t.map(_ * 2)
+ t2.isInstanceOf[collection.mutable.TreeSet[Int]]
+ }
+ }
+
+ property("A view doesn't expose off bounds elements") = forAll(denseGenerator) { (s: List[Int]) =>
+ {
+ val t = mutable.TreeSet[Int](s: _*)
+ val view = t.rangeImpl(Some(50), Some(150))
+ view.filter(_ < 50) == Set[Int]() && view.filter(_ >= 150) == Set[Int]()
+ }
+ }
+}
diff --git a/test/files/specialized/spec-hlists.check b/test/files/specialized/spec-hlists.check
new file mode 100644
index 0000000000..0ab3339bbc
--- /dev/null
+++ b/test/files/specialized/spec-hlists.check
@@ -0,0 +1,2 @@
+class HCons$mcI$sp
+class HCons$mcI$sp
diff --git a/test/files/specialized/spec-hlists.scala b/test/files/specialized/spec-hlists.scala
new file mode 100644
index 0000000000..8c4ac8f610
--- /dev/null
+++ b/test/files/specialized/spec-hlists.scala
@@ -0,0 +1,29 @@
+/** Test contributed by Stefan Zeiger showing that HLists can be
+ * specialized.
+ */
+
+sealed trait HList {
+ type Self <: HList
+
+ type |: [E] = HCons[E, Self]
+
+ final def |: [@specialized E](elem: E): |: [E] = new HCons[E, Self](elem, this.asInstanceOf[Self])
+
+ def m[@specialized E, T <: AnyRef](x: E): T = null.asInstanceOf[T]
+}
+
+final class HCons[@specialized H, T <: HList](val head: H, val tail: T) extends HList {
+ type Self = HCons[H, T]
+}
+
+final object HNil extends HList {
+ type Self = HNil.type
+}
+
+object Test extends App {
+ val l1 = new HCons(42, "foo" |: HNil)
+ println(l1.getClass)
+
+ val l2 = 42 |: "abc" |: HNil
+ println(l2.getClass)
+}
diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.scala b/test/scaladoc/scala/html/HtmlFactoryTest.scala
index 5b17affbf0..e2687dd510 100644
--- a/test/scaladoc/scala/html/HtmlFactoryTest.scala
+++ b/test/scaladoc/scala/html/HtmlFactoryTest.scala
@@ -190,9 +190,9 @@ object Test extends Properties("HtmlFactory") {
createTemplate("Trac4372.scala") match {
case node: scala.xml.Node => {
val html = node.toString
- html.contains("<span class=\"name\" title=\"gt4s: $plus$colon\">+:</span>") &&
- html.contains("<span class=\"name\" title=\"gt4s: $minus$colon\">-:</span>") &&
- html.contains("""<span class="params">(<span name="n">n: <span name="scala.Int" class="extype">Int</span></span>)</span><span class="result">: <span name="scala.Int" class="extype">Int</span></span>""")
+ html.contains("<span title=\"gt4s: $plus$colon\" class=\"name\">+:</span>") &&
+ html.contains("<span title=\"gt4s: $minus$colon\" class=\"name\">-:</span>") &&
+ html.contains("""<span class="params">(<span name="n">n: <span class="extype" name="scala.Int">Int</span></span>)</span><span class="result">: <span class="extype" name="scala.Int">Int</span></span>""")
}
case _ => false
}
diff --git a/tools/binary-repo-lib.sh b/tools/binary-repo-lib.sh
index 79a37dd7df..4221e3205c 100755
--- a/tools/binary-repo-lib.sh
+++ b/tools/binary-repo-lib.sh
@@ -77,7 +77,7 @@ pushJarFile() {
local remote_uri=${version}${jar#$basedir}
echo " Pushing to ${remote_urlbase}/${remote_uri} ..."
echo " $curl"
- local curl=$(curlUpload $remote_uri $jar_name $user $pw)
+ curlUpload $remote_uri $jar_name $user $pw
echo " Making new sha1 file ...."
echo "$jar_sha1" > "${jar_name}${desired_ext}"
popd >/dev/null
@@ -112,14 +112,20 @@ pushJarFiles() {
local password=$3
# TODO - ignore target/ and build/
local jarFiles="$(find ${basedir}/lib -name "*.jar") $(find ${basedir}/test/files -name "*.jar")"
+ local changed="no"
for jar in $jarFiles; do
local valid=$(isJarFileValid $jar)
if [[ "$valid" != "OK" ]]; then
echo "$jar has changed, pushing changes...."
+ changed="yes"
pushJarFile $jar $basedir $user $password
fi
done
- echo "Binary changes have been pushed. You may now submit the new *${desired_ext} files to git."
+ if test "$changed" == "no"; then
+ echo "No jars have been changed."
+ else
+ echo "Binary changes have been pushed. You may now submit the new *${desired_ext} files to git."
+ fi
}
# Pulls a single binary artifact from a remote repository.
@@ -141,7 +147,7 @@ pullJarFile() {
# Argument 1 - The directory to search for *.desired.sha1 files that need to be retrieved.
pullJarFiles() {
local basedir=$1
- local desiredFiles="$(find ${basedir}/lib -name *${desired_ext}) $(find ${basedir}/test/files -name *${desired_ext})"
+ local desiredFiles="$(find ${basedir}/lib -name *${desired_ext}) $(find ${basedir}/test/files -name *${desired_ext}) $(find ${basedir}/tools -name *${desired_ext})"
for sha in $desiredFiles; do
jar=${sha%$desired_ext}
local valid=$(isJarFileValid $jar)
diff --git a/tools/epfl-publish b/tools/epfl-publish
index e9cd97b3d2..4982f930bb 100755
--- a/tools/epfl-publish
+++ b/tools/epfl-publish
@@ -1,7 +1,6 @@
#!/usr/bin/env bash
#
# publishes nightly build if $publish_to is set in environment.
-# alternate maven settings.xml file given in $maven_settings.
#
[[ $# -eq 1 ]] || {
@@ -20,21 +19,6 @@ version="$1"
exit 1
}
-# should not be hardcoded
-# adds -Dsettings.file= if fixed path is present
-mavenSettingsOption () {
- hardcoded_path="/home/linuxsoft/apps/hudson-maven-settings/settings.xml"
-
- # environment variable
- if [[ -n $maven_settings ]]; then
- echo -Dsettings.file="$maven_settings"
- elif [[ -f $hardcoded_path ]]; then
- echo -Dsettings.file="$hardcoded_path"
- fi
-}
-
-mavenSettings=${maven_settings:-findMavenSettings}
-
if [[ -z $publish_to ]]; then
echo "Nothing to publish."
else
@@ -45,6 +29,4 @@ else
[[ $version == "2.8.x" ]] || rsync -az build/scaladoc/ "$publish_to/docs"
# sbaz
[[ -d dists/sbaz ]] && rsync -az dists/sbaz/ "$publish_to/sbaz"
- # Deploy the maven artifacts on scala-tools.org
- ( cd dists/maven/latest && ant deploy.snapshot $(mavenSettingsOption) )
fi