summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.mailmap25
-rw-r--r--build.xml36
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTrees.scala131
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenUtils.scala3
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala20
-rw-r--r--src/compiler/scala/tools/nsc/Driver.scala6
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala73
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala39
-rw-r--r--src/compiler/scala/tools/nsc/ast/Positions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala29
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala66
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala22
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala5
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala87
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala79
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala97
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocFactory.scala2
-rwxr-xr-x[-rw-r--r--]src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala (renamed from src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala)232
-rwxr-xr-xsrc/compiler/scala/tools/nsc/doc/base/LinkTo.scala15
-rwxr-xr-xsrc/compiler/scala/tools/nsc/doc/base/MemberLookupBase.scala230
-rwxr-xr-x[-rw-r--r--]src/compiler/scala/tools/nsc/doc/base/comment/Body.scala (renamed from src/compiler/scala/tools/nsc/doc/model/comment/Body.scala)2
-rw-r--r--src/compiler/scala/tools/nsc/doc/base/comment/Comment.scala (renamed from src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala)3
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala9
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Source.scala1
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Template.scala3
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/CommentFactory.scala114
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/Entity.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/LinkTo.scala24
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala225
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala44
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala4
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala3
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala3
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/Doc.scala50
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala3
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala5
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala30
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala34
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala24
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala544
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala2
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala1
-rw-r--r--src/eclipse/continuations-library/.classpath8
-rw-r--r--src/eclipse/continuations-library/.project30
-rw-r--r--src/eclipse/continuations-library/.settings/org.scala-ide.sdt.core.prefs2
-rw-r--r--src/eclipse/partest/.classpath1
-rw-r--r--src/eclipse/reflect/.classpath1
-rw-r--r--src/eclipse/scala-compiler/.classpath1
-rw-r--r--src/eclipse/scalap/.classpath1
-rw-r--r--src/library/scala/StringContext.scala13
-rw-r--r--src/library/scala/collection/SeqLike.scala2
-rw-r--r--src/library/scala/collection/convert/WrapAsJava.scala3
-rw-r--r--src/library/scala/collection/convert/WrapAsScala.scala5
-rw-r--r--src/library/scala/collection/immutable/Range.scala1
-rw-r--r--src/library/scala/collection/mutable/MutableList.scala10
-rw-r--r--src/library/scala/collection/mutable/Queue.scala28
-rw-r--r--src/library/scala/util/Random.scala2
-rw-r--r--src/partest/scala/tools/partest/DirectTest.scala4
-rw-r--r--src/partest/scala/tools/partest/ScaladocModelTest.scala2
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala2
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala103
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala5
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala2
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala6
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala1
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala2
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala179
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala32
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala8
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala2
-rw-r--r--src/reflect/scala/reflect/internal/transform/UnCurry.scala3
-rw-r--r--src/reflect/scala/reflect/internal/util/Position.scala3
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala2
-rw-r--r--test/files/jvm/serialization.scala15
-rw-r--r--test/files/neg/anyval-anyref-parent.check2
-rw-r--r--test/files/neg/case-collision.check10
-rw-r--r--test/files/neg/case-collision.flags1
-rw-r--r--test/files/neg/case-collision.scala11
-rw-r--r--test/files/neg/cyclics-import.check11
-rw-r--r--test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala4
-rw-r--r--test/files/neg/names-defaults-neg.check2
-rw-r--r--test/files/neg/protected-constructors.check5
-rw-r--r--test/files/neg/t1672b.check16
-rw-r--r--test/files/neg/t1672b.scala52
-rw-r--r--test/files/neg/t2148.check2
-rw-r--r--test/files/neg/t3222.check14
-rw-r--r--test/files/neg/t3614.check4
-rw-r--r--test/files/neg/t4044.check7
-rw-r--r--test/files/neg/t409.check4
-rw-r--r--test/files/neg/t5361.check4
-rw-r--r--test/files/neg/t5361.scala3
-rw-r--r--test/files/neg/t5529.check5
-rw-r--r--test/files/neg/t5696.check2
-rw-r--r--test/files/neg/t6260.check4
-rw-r--r--test/files/neg/t6535.check6
-rw-r--r--test/files/neg/t6535.scala15
-rw-r--r--test/files/neg/t6558.check10
-rw-r--r--test/files/neg/t6558.scala12
-rw-r--r--test/files/neg/t6558b.check7
-rw-r--r--test/files/neg/t6558b.scala15
-rw-r--r--test/files/neg/t6667.check13
-rw-r--r--test/files/neg/t6667.scala10
-rw-r--r--test/files/neg/t6667b.check13
-rw-r--r--test/files/neg/t6667b.scala25
-rw-r--r--test/files/neg/t667.check4
-rw-r--r--test/files/neg/t6758.check28
-rw-r--r--test/files/neg/t6758.scala43
-rw-r--r--test/files/neg/t877.check4
-rw-r--r--test/files/pos/attachments-typed-ident.check0
-rw-r--r--test/files/pos/attachments-typed-ident.flags1
-rw-r--r--test/files/pos/attachments-typed-ident/Impls_1.scala17
-rw-r--r--test/files/pos/attachments-typed-ident/Macros_Test_2.scala4
-rw-r--r--test/files/pos/strip-tvars-for-lubbasetypes.scala25
-rw-r--r--test/files/pos/t1672.scala10
-rw-r--r--test/files/pos/t5726.scala17
-rw-r--r--test/files/pos/t5877.scala14
-rw-r--r--test/files/pos/t5877b.scala13
-rw-r--r--test/files/pos/t6547.flags1
-rw-r--r--test/files/pos/t6547.scala6
-rw-r--r--test/files/pos/t6551.scala2
-rw-r--r--test/files/pos/t6712.scala5
-rw-r--r--test/files/pos/t6722.scala11
-rwxr-xr-xtest/files/presentation/doc.check48
-rwxr-xr-xtest/files/presentation/doc.scala71
-rwxr-xr-xtest/files/presentation/doc/src/Test.scala1
-rw-r--r--test/files/presentation/memory-leaks/MemoryLeaksTest.scala5
-rw-r--r--test/files/run/idempotency-case-classes.check52
-rw-r--r--test/files/run/idempotency-case-classes.scala22
-rw-r--r--test/files/run/idempotency-extractors.check5
-rw-r--r--test/files/run/idempotency-extractors.scala22
-rw-r--r--test/files/run/idempotency-labels.check15
-rw-r--r--test/files/run/idempotency-labels.scala22
-rw-r--r--test/files/run/idempotency-lazy-vals.check23
-rw-r--r--test/files/run/idempotency-lazy-vals.scala27
-rw-r--r--test/files/run/idempotency-partial-functions.check2
-rw-r--r--test/files/run/idempotency-partial-functions.scala25
-rw-r--r--test/files/run/idempotency-this.check4
-rw-r--r--test/files/run/idempotency-this.scala22
-rw-r--r--test/files/run/inline-ex-handlers.check21
-rw-r--r--test/files/run/macro-abort-fresh/Test_2.scala2
-rw-r--r--test/files/run/macro-declared-in-class-class/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-class-object/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-class/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala2
-rw-r--r--test/files/run/macro-declared-in-method/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-object-class/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-object-object/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-object/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-package-object/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-refinement/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-trait/Impls_1.scala2
-rw-r--r--test/files/run/macro-def-infer-return-type-b/Test_2.scala2
-rw-r--r--test/files/run/macro-expand-implicit-argument/Macros_1.scala8
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala2
-rw-r--r--test/files/run/macro-impl-default-params/Impls_Macros_1.scala4
-rw-r--r--test/files/run/macro-impl-rename-context/Impls_Macros_1.scala4
-rw-r--r--test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala2
-rw-r--r--test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala2
-rw-r--r--test/files/run/macro-invalidret-nontypeable/Test_2.scala4
-rw-r--r--test/files/run/macro-invalidusage-badret/Test_2.scala2
-rw-r--r--test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala2
-rw-r--r--test/files/run/macro-invalidusage-partialapplication/Test_2.scala2
-rw-r--r--test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala2
-rw-r--r--test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala6
-rw-r--r--test/files/run/macro-reify-freevars/Test_2.scala4
-rw-r--r--test/files/run/macro-reify-splice-outside-reify/Test_2.scala2
-rw-r--r--test/files/run/macro-reify-tagless-a/Test_2.scala4
-rw-r--r--test/files/run/reify_renamed_term_basic.check1
-rw-r--r--test/files/run/reify_renamed_term_basic.scala20
-rw-r--r--test/files/run/reify_renamed_term_local_to_reifee.check1
-rw-r--r--test/files/run/reify_renamed_term_local_to_reifee.scala20
-rw-r--r--test/files/run/reify_renamed_term_overloaded_method.check1
-rw-r--r--test/files/run/reify_renamed_term_overloaded_method.scala17
-rw-r--r--test/files/run/reify_renamed_term_si5841.check1
-rw-r--r--test/files/run/reify_renamed_term_si5841.scala7
-rw-r--r--test/files/run/reify_renamed_type_basic.check1
-rw-r--r--test/files/run/reify_renamed_type_basic.scala16
-rw-r--r--test/files/run/reify_renamed_type_local_to_reifee.check1
-rw-r--r--test/files/run/reify_renamed_type_local_to_reifee.scala24
-rw-r--r--test/files/run/reify_renamed_type_spliceable.check1
-rw-r--r--test/files/run/reify_renamed_type_spliceable.scala21
-rw-r--r--test/files/run/t1672.scala28
-rw-r--r--test/files/run/t5064.check6
-rw-r--r--test/files/run/t5603.check4
-rw-r--r--test/files/run/t5733.check2
-rw-r--r--test/files/run/t5733.scala53
-rw-r--r--test/files/run/t5789.check14
-rw-r--r--test/files/run/t5789.scala14
-rw-r--r--test/files/run/t5894.scala17
-rw-r--r--test/files/run/t6288.check85
-rw-r--r--test/files/run/t6288.scala41
-rw-r--r--test/files/run/t6288b-jump-position.check80
-rw-r--r--test/files/run/t6288b-jump-position.scala22
-rw-r--r--test/files/run/t6320.check17
-rw-r--r--test/files/run/t6320.scala9
-rw-r--r--test/files/run/t6549.check32
-rw-r--r--test/files/run/t6549.scala22
-rw-r--r--test/files/run/t6555.check22
-rw-r--r--test/files/run/t6555.scala15
-rw-r--r--test/files/run/t6614.check11
-rw-r--r--test/files/run/t6614.scala8
-rw-r--r--test/files/run/t6631.scala18
-rw-r--r--test/files/run/t6690.scala62
-rw-r--r--test/files/run/t6731.check40
-rw-r--r--test/files/run/t6731.scala143
-rw-r--r--test/files/run/toolbox_typecheck_implicitsdisabled.scala8
-rw-r--r--test/pending/run/macro-reify-tagless-b/Test_2.scala2
-rwxr-xr-xtest/scaladoc/run/SI-191-deprecated.scala3
-rwxr-xr-xtest/scaladoc/run/SI-191.scala3
-rw-r--r--test/scaladoc/run/SI-3314.scala3
-rw-r--r--test/scaladoc/run/SI-5235.scala3
-rw-r--r--test/scaladoc/run/links.scala7
-rw-r--r--test/scaladoc/run/t4922.check1
-rw-r--r--test/scaladoc/run/t4922.scala32
-rw-r--r--test/scaladoc/scalacheck/CommentFactoryTest.scala3
240 files changed, 3557 insertions, 1309 deletions
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000000..49d5dc6629
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,25 @@
+Aleksandar Prokopec <aleksandar@aleksandar-Latitude-E6500.(none)>
+Aleksandar Prokopec <aleksandar@htpc.(none)>
+Aleksandar Prokopec <aleksandar@htpc-axel22.(none)>
+Aleksandar Prokopec <aleksandar@lampmac14.epfl.ch>
+Aleksandar Prokopec <aleksandar.prokopec@epfl.ch>
+Antonio Cunei <antonio.cunei@typesafe.com>
+Caoyuan Deng <dcaoyuan@epfl.ch>
+Chris Hodapp <clhodapp1@gmail.com>
+Chris James <chrisJames@epfl.ch>
+Christopher Vogt <vogt@epfl.ch>
+Damien Obristi <damien.obrist@gmail.com>
+Daniel C. Sobral <dcs@dcs-132-CK-NF79.(none)>
+Ilya Sergei <ilyas@epfl.ch>
+Ingo Maier <ingoem@gmail.com>
+Kenji Yoshida <6b656e6a69@gmail.com>
+Luc Bourlier <skyluc@epfl.ch>
+Martin Odersky <odersky@gamil.com>
+Nada Amin <amin@epfl.ch>
+Nada Amin <nada.amin@epfl.ch>
+Natallie Baikevich <lu-a-jalla@ya.ru>
+Pavel Pavlov <pavel.e.pavlov@gmail.com>
+Philipp Haller <philipp.haller@typesafe.com>
+Roland Kuhn <rk@rkuhn.info>
+Rüdiger Klaehn <rklaehn@gmail.com>
+Stéphane Micheloud <michelou@epfl.ch>
diff --git a/build.xml b/build.xml
index 3cfbd454e2..95e324250a 100644
--- a/build.xml
+++ b/build.xml
@@ -22,7 +22,7 @@ END-USER TARGETS
<target name="clean" depends="quick.clean"
description="Removes binaries of compiler and library. Distributions are untouched."/>
- <target name="test" depends="test.done, osgi.test"
+ <target name="test" depends="test.done, osgi.test, bc.run"
description="Runs test suite and bootstrapping test on Scala compiler and library."/>
<target name="test-opt"
@@ -2644,6 +2644,40 @@ BOOTRAPING TEST AND TEST SUITE
<target name="test.done" depends="test.suite, test.continuations.suite, test.scaladoc, test.stability, test.sbt"/>
+
+<!-- ===========================================================================
+Binary compatibility testing
+============================================================================ -->
+
+ <target name="bc.init" depends="init">
+ <property name="bc-build.dir" value="${build.dir}/bc"/>
+ <!-- Obtain mima -->
+ <mkdir dir="${bc-build.dir}"/>
+ <!-- Pull down MIMA -->
+ <artifact:dependencies pathId="mima.classpath">
+ <dependency groupId="com.typesafe" artifactId="mima-reporter_2.9.2" version="0.1.4"/>
+ </artifact:dependencies>
+ <artifact:dependencies pathId="old.bc.classpath">
+ <dependency groupId="org.scala-lang" artifactId="scala-library" version="2.10.0-RC2"/>
+ </artifact:dependencies>
+ </target>
+
+ <target name="bc.run" depends="bc.init, pack.lib">
+ <java
+ fork="true"
+ failonerror="true"
+ classname="com.typesafe.tools.mima.cli.Main">
+ <arg value="--prev"/>
+ <arg value="${org.scala-lang:scala-library:jar}"/>
+ <arg value="--curr"/>
+ <arg value="${build-pack.dir}/lib/scala-library.jar"/>
+ <classpath>
+ <path refid="mima.classpath"/>
+ </classpath>
+ </java>
+ </target>
+
+
<!-- ===========================================================================
DISTRIBUTION
============================================================================ -->
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
index bdcc7383b0..31974b5b76 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
@@ -45,7 +45,9 @@ trait GenTrees {
case global.EmptyTree =>
reifyMirrorObject(EmptyTree)
case global.emptyValDef =>
- mirrorBuildSelect(nme.emptyValDef)
+ mirrorSelect(nme.emptyValDef)
+ case global.pendingSuperCall =>
+ mirrorSelect(nme.pendingSuperCall)
case FreeDef(_, _, _, _, _) =>
reifyNestedFreeDef(tree)
case FreeRef(_, _) =>
@@ -101,7 +103,8 @@ trait GenTrees {
case ReifiedTree(_, _, inlinedSymtab, rtree, _, _, _) =>
if (reifyDebug) println("inlining the splicee")
// all free vars local to the enclosing reifee should've already been inlined by ``Metalevels''
- inlinedSymtab.syms foreach (sym => if (sym.isLocalToReifee) assert(false, inlinedSymtab.symDef(sym)))
+ for (sym <- inlinedSymtab.syms if sym.isLocalToReifee)
+ abort("local free var, should have already been inlined by Metalevels: " + inlinedSymtab.symDef(sym))
state.symtab ++= inlinedSymtab
rtree
case tree =>
@@ -117,88 +120,102 @@ trait GenTrees {
// unlike in `reifyBoundType` we can skip checking for `tpe` being local or not local w.r.t the reifee
// a single check for a symbol of the bound term should be enough
// that's because only Idents and Thises can be bound terms, and they cannot host complex types
- private def reifyBoundTerm(tree: Tree): Tree = tree match {
- case tree @ This(_) if tree.symbol == NoSymbol =>
- throw new Error("unexpected: bound term that doesn't have a symbol: " + showRaw(tree))
- case tree @ This(_) if tree.symbol.isClass && !tree.symbol.isModuleClass && !tree.symbol.isLocalToReifee =>
- val sym = tree.symbol
- if (reifyDebug) println("This for %s, reified as freeVar".format(sym))
- if (reifyDebug) println("Free: " + sym)
- mirrorBuildCall(nme.Ident, reifyFreeTerm(This(sym)))
- case tree @ This(_) if !tree.symbol.isLocalToReifee =>
- if (reifyDebug) println("This for %s, reified as This".format(tree.symbol))
- mirrorBuildCall(nme.This, reify(tree.symbol))
- case tree @ This(_) if tree.symbol.isLocalToReifee =>
- mirrorCall(nme.This, reify(tree.qual))
- case tree @ Ident(_) if tree.symbol == NoSymbol =>
- // this sometimes happens, e.g. for binds that don't have a body
- // or for untyped code generated during previous phases
- // (see a comment in Reifiers about the latter, starting with "why do we resetAllAttrs?")
- mirrorCall(nme.Ident, reify(tree.name))
- case tree @ Ident(_) if !tree.symbol.isLocalToReifee =>
- if (tree.symbol.isVariable && tree.symbol.owner.isTerm) {
- captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reification here.
- mirrorCall(nme.Select, mirrorBuildCall(nme.Ident, reify(tree.symbol)), reify(nme.elem))
- } else {
- mirrorBuildCall(nme.Ident, reify(tree.symbol))
- }
- case tree @ Ident(_) if tree.symbol.isLocalToReifee =>
- mirrorCall(nme.Ident, reify(tree.name))
- case _ =>
- throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ private def reifyBoundTerm(tree: Tree): Tree = {
+ val sym = tree.symbol
+
+ tree match {
+ case This(qual) =>
+ assert(sym != NoSymbol, "unexpected: bound term that doesn't have a symbol: " + showRaw(tree))
+ if (sym.isLocalToReifee)
+ mirrorCall(nme.This, reify(qual))
+ else if (sym.isClass && !sym.isModuleClass) {
+ if (reifyDebug) println("This for %s, reified as freeVar".format(sym))
+ if (reifyDebug) println("Free: " + sym)
+ mirrorBuildCall(nme.Ident, reifyFreeTerm(This(sym)))
+ }
+ else {
+ if (reifyDebug) println("This for %s, reified as This".format(sym))
+ mirrorBuildCall(nme.This, reify(sym))
+ }
+
+ case Ident(name) =>
+ if (sym == NoSymbol) {
+ // this sometimes happens, e.g. for binds that don't have a body
+ // or for untyped code generated during previous phases
+ // (see a comment in Reifiers about the latter, starting with "why do we resetAllAttrs?")
+ mirrorCall(nme.Ident, reify(name))
+ }
+ else if (!sym.isLocalToReifee) {
+ if (sym.isVariable && sym.owner.isTerm) {
+ captureVariable(sym) // Note order dependency: captureVariable needs to come before reification here.
+ mirrorCall(nme.Select, mirrorBuildCall(nme.Ident, reify(sym)), reify(nme.elem))
+ }
+ else mirrorBuildCall(nme.Ident, reify(sym))
+ }
+ else mirrorCall(nme.Ident, reify(name))
+
+ case Select(qual, name) =>
+ if (sym == NoSymbol || sym.name == name)
+ reifyProduct(tree)
+ else
+ reifyProduct(Select(qual, sym.name))
+
+ case _ =>
+ throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ }
}
private def reifyBoundType(tree: Tree): Tree = {
+ val sym = tree.symbol
+ val tpe = tree.tpe
+
def reifyBoundType(tree: Tree): Tree = {
- if (tree.tpe == null)
- throw new Error("unexpected: bound type that doesn't have a tpe: " + showRaw(tree))
+ assert(tpe != null, "unexpected: bound type that doesn't have a tpe: " + showRaw(tree))
// if a symbol or a type of the scrutinee are local to reifee
// (e.g. point to a locally declared class or to a path-dependent thingie that depends on a local variable)
// then we can reify the scrutinee as a symless AST and that will definitely be hygienic
// why? because then typechecking of a scrutinee doesn't depend on the environment external to the quasiquote
// otherwise we need to reify the corresponding type
- if (tree.symbol.isLocalToReifee || tree.tpe.isLocalToReifee)
+ if (sym.isLocalToReifee || tpe.isLocalToReifee)
reifyProduct(tree)
else {
- val sym = tree.symbol
- val tpe = tree.tpe
if (reifyDebug) println("reifying bound type %s (underlying type is %s)".format(sym, tpe))
if (tpe.isSpliceable) {
val spliced = spliceType(tpe)
+
if (spliced == EmptyTree) {
if (reifyDebug) println("splicing failed: reify as is")
mirrorBuildCall(nme.TypeTree, reify(tpe))
- } else {
- spliced match {
- case TypeRefToFreeType(freeType) =>
- if (reifyDebug) println("splicing returned a free type: " + freeType)
- Ident(freeType)
- case _ =>
- if (reifyDebug) println("splicing succeeded: " + spliced)
- mirrorBuildCall(nme.TypeTree, spliced)
- }
}
- } else {
- if (sym.isLocatable) {
- if (reifyDebug) println("tpe is locatable: reify as Ident(%s)".format(sym))
- mirrorBuildCall(nme.Ident, reify(sym))
- } else {
- if (reifyDebug) println("tpe is not locatable: reify as TypeTree(%s)".format(tpe))
- mirrorBuildCall(nme.TypeTree, reify(tpe))
+ else spliced match {
+ case TypeRefToFreeType(freeType) =>
+ if (reifyDebug) println("splicing returned a free type: " + freeType)
+ Ident(freeType)
+ case _ =>
+ if (reifyDebug) println("splicing succeeded: " + spliced)
+ mirrorBuildCall(nme.TypeTree, spliced)
}
}
+ else if (sym.isLocatable) {
+ if (reifyDebug) println("tpe is locatable: reify as Ident(%s)".format(sym))
+ mirrorBuildCall(nme.Ident, reify(sym))
+ }
+ else {
+ if (reifyDebug) println("tpe is not locatable: reify as TypeTree(%s)".format(tpe))
+ mirrorBuildCall(nme.TypeTree, reify(tpe))
+ }
}
}
tree match {
- case Select(_, _) =>
- reifyBoundType(tree)
- case SelectFromTypeTree(_, _) =>
- reifyBoundType(tree)
- case Ident(_) =>
+ case Select(qual, name) if name != sym.name =>
+ reifyBoundType(Select(qual, sym.name))
+
+ case Select(_, _) | SelectFromTypeTree(_, _) | Ident(_) =>
reifyBoundType(tree)
+
case _ =>
throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
index 49877b4286..21db93d8f5 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
@@ -34,9 +34,6 @@ trait GenUtils {
def mirrorSelect(name: String): Tree =
termPath(nme.UNIVERSE_PREFIX + name)
- def mirrorBuildSelect(name: String): Tree =
- termPath(nme.UNIVERSE_BUILD_PREFIX + name)
-
def mirrorMirrorSelect(name: String): Tree =
termPath(nme.MIRROR_PREFIX + name)
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index b60d15c1d4..ebbcb95481 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -251,6 +251,8 @@ trait Extractors {
object BoundTerm {
def unapply(tree: Tree): Option[Tree] = tree match {
+ case Select(_, name) if name.isTermName =>
+ Some(tree)
case Ident(name) if name.isTermName =>
Some(tree)
case This(_) =>
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 4e7ba60d5e..355a1fd262 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -23,7 +23,7 @@ trait CompilationUnits { self: Global =>
/** One unit of compilation that has been submitted to the compiler.
* It typically corresponds to a single file of source code. It includes
* error-reporting hooks. */
- class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi {
+ class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi { self =>
/** the fresh name creator */
var fresh: FreshNameCreator = new FreshNameCreator.Default
@@ -57,7 +57,23 @@ trait CompilationUnits { self: Global =>
/** Synthetic definitions generated by namer, eliminated by typer.
*/
- val synthetics = mutable.HashMap[Symbol, Tree]()
+ object synthetics {
+ private val map = mutable.HashMap[Symbol, Tree]()
+ def update(sym: Symbol, tree: Tree) {
+ debuglog(s"adding synthetic ($sym, $tree) to $self")
+ map.update(sym, tree)
+ }
+ def -=(sym: Symbol) {
+ debuglog(s"removing synthetic $sym from $self")
+ map -= sym
+ }
+ def get(sym: Symbol): Option[Tree] = logResultIf[Option[Tree]](s"found synthetic for $sym in $self", _.isDefined) {
+ map get sym
+ }
+ def keys: Iterable[Symbol] = map.keys
+ def clear(): Unit = map.clear()
+ override def toString = map.toString
+ }
/** things to check at end of compilation unit */
val toCheck = new ListBuffer[() => Unit]
diff --git a/src/compiler/scala/tools/nsc/Driver.scala b/src/compiler/scala/tools/nsc/Driver.scala
index 1775602122..814bd58a66 100644
--- a/src/compiler/scala/tools/nsc/Driver.scala
+++ b/src/compiler/scala/tools/nsc/Driver.scala
@@ -54,10 +54,10 @@ abstract class Driver {
doCompile(compiler)
} catch {
case ex: Throwable =>
- compiler.logThrowable(ex)
+ compiler.reportThrowable(ex)
ex match {
- case FatalError(msg) => reporter.error(null, "fatal error: " + msg)
- case _ => throw ex
+ case FatalError(msg) => // signals that we should fail compilation.
+ case _ => throw ex // unexpected error, tell the outside world.
}
}
}
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index b0288c0149..8883920325 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -292,7 +292,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
log(msg)
}
- def logThrowable(t: Throwable): Unit = globalError(throwableAsString(t))
+ @deprecated("Renamed to reportThrowable", "2.10.1")
+ def logThrowable(t: Throwable): Unit = reportThrowable(t)
+ def reportThrowable(t: Throwable): Unit = globalError(throwableAsString(t))
override def throwableAsString(t: Throwable) = util.stackTraceString(t)
// ------------ File interface -----------------------------------------
@@ -1144,37 +1146,41 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Don't want to introduce new errors trying to report errors,
* so swallow exceptions.
*/
- override def supplementErrorMessage(errorMessage: String): String = try {
- val tree = analyzer.lastTreeToTyper
- val sym = tree.symbol
- val tpe = tree.tpe
- val enclosing = lastSeenContext.enclClassOrMethod.tree
-
- val info1 = formatExplain(
- "while compiling" -> currentSource.path,
- "during phase" -> ( if (globalPhase eq phase) phase else "global=%s, atPhase=%s".format(globalPhase, phase) ),
- "library version" -> scala.util.Properties.versionString,
- "compiler version" -> Properties.versionString,
- "reconstructed args" -> settings.recreateArgs.mkString(" ")
- )
- val info2 = formatExplain(
- "last tree to typer" -> tree.summaryString,
- "symbol" -> Option(sym).fold("null")(_.debugLocationString),
- "symbol definition" -> Option(sym).fold("null")(_.defString),
- "tpe" -> tpe,
- "symbol owners" -> ownerChainString(sym),
- "context owners" -> ownerChainString(lastSeenContext.owner)
- )
- val info3: List[String] = (
- ( List("== Enclosing template or block ==", nodePrinters.nodeToString(enclosing).trim) )
- ++ ( if (tpe eq null) Nil else List("== Expanded type of tree ==", typeDeconstruct.show(tpe)) )
- ++ ( if (!opt.debug) Nil else List("== Current unit body ==", nodePrinters.nodeToString(currentUnit.body)) )
- ++ ( List(errorMessage) )
- )
-
- ("\n" + info1) :: info2 :: info3 mkString "\n\n"
- }
- catch { case x: Exception => errorMessage }
+ override def supplementErrorMessage(errorMessage: String): String =
+ if (currentRun.supplementedError) errorMessage
+ else try {
+ val tree = analyzer.lastTreeToTyper
+ val sym = tree.symbol
+ val tpe = tree.tpe
+ val enclosing = lastSeenContext.enclClassOrMethod.tree
+
+ val info1 = formatExplain(
+ "while compiling" -> currentSource.path,
+ "during phase" -> ( if (globalPhase eq phase) phase else "global=%s, atPhase=%s".format(globalPhase, phase) ),
+ "library version" -> scala.util.Properties.versionString,
+ "compiler version" -> Properties.versionString,
+ "reconstructed args" -> settings.recreateArgs.mkString(" ")
+ )
+ val info2 = formatExplain(
+ "last tree to typer" -> tree.summaryString,
+ "symbol" -> Option(sym).fold("null")(_.debugLocationString),
+ "symbol definition" -> Option(sym).fold("null")(_.defString),
+ "tpe" -> tpe,
+ "symbol owners" -> ownerChainString(sym),
+ "context owners" -> ownerChainString(lastSeenContext.owner)
+ )
+ val info3: List[String] = (
+ ( List("== Enclosing template or block ==", nodePrinters.nodeToString(enclosing).trim) )
+ ++ ( if (tpe eq null) Nil else List("== Expanded type of tree ==", typeDeconstruct.show(tpe)) )
+ ++ ( if (!opt.debug) Nil else List("== Current unit body ==", nodePrinters.nodeToString(currentUnit.body)) )
+ ++ ( List(errorMessage) )
+ )
+
+ currentRun.supplementedError = true
+
+ ("\n" + info1) :: info2 :: info3 mkString "\n\n"
+ }
+ catch { case x: Exception => errorMessage }
/** The id of the currently active run
*/
@@ -1230,6 +1236,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Has any macro expansion used a fallback during this run? */
var seenMacroExpansionsFallingBack = false
+ /** Have we already supplemented the error message of a compiler crash? */
+ private[nsc] final var supplementedError = false
+
/** To be initialized from firstPhase. */
private var terminalPhase: Phase = NoPhase
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index 5a4be5125d..e635c5e87d 100755
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
@@ -19,11 +19,17 @@ import scala.collection.mutable
*/
trait DocComments { self: Global =>
- var cookedDocComments = Map[Symbol, String]()
+ val cookedDocComments = mutable.HashMap[Symbol, String]()
/** The raw doc comment map */
val docComments = mutable.HashMap[Symbol, DocComment]()
+ def clearDocComments() {
+ cookedDocComments.clear()
+ docComments.clear()
+ defs.clear()
+ }
+
/** Associate comment with symbol `sym` at position `pos`. */
def docComment(sym: Symbol, docStr: String, pos: Position = NoPosition) =
if ((sym ne null) && (sym ne NoSymbol))
@@ -55,25 +61,20 @@ trait DocComments { self: Global =>
* If a symbol does not have a doc comment but some overridden version of it does,
* the doc comment of the overridden version is copied instead.
*/
- def cookedDocComment(sym: Symbol, docStr: String = ""): String = cookedDocComments.get(sym) match {
- case Some(comment) =>
- comment
- case None =>
- val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse ""
+ def cookedDocComment(sym: Symbol, docStr: String = ""): String = cookedDocComments.getOrElseUpdate(sym, {
+ val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse ""
else DocComment(docStr).template
- val comment = superComment(sym) match {
- case None =>
- if (ownComment.indexOf("@inheritdoc") != -1)
- reporter.warning(sym.pos, "The comment for " + sym +
- " contains @inheritdoc, but no parent comment is available to inherit from.")
- ownComment.replaceAllLiterally("@inheritdoc", "<invalid inheritdoc annotation>")
- case Some(sc) =>
- if (ownComment == "") sc
- else expandInheritdoc(sc, merge(sc, ownComment, sym), sym)
- }
- cookedDocComments += (sym -> comment)
- comment
- }
+ superComment(sym) match {
+ case None =>
+ if (ownComment.indexOf("@inheritdoc") != -1)
+ reporter.warning(sym.pos, "The comment for " + sym +
+ " contains @inheritdoc, but no parent comment is available to inherit from.")
+ ownComment.replaceAllLiterally("@inheritdoc", "<invalid inheritdoc annotation>")
+ case Some(sc) =>
+ if (ownComment == "") sc
+ else expandInheritdoc(sc, merge(sc, ownComment, sym), sym)
+ }
+ })
/** The cooked doc comment of symbol `sym` after variable expansion, or "" if missing.
*
diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala
index d8fb632f73..49569f5e05 100644
--- a/src/compiler/scala/tools/nsc/ast/Positions.scala
+++ b/src/compiler/scala/tools/nsc/ast/Positions.scala
@@ -20,7 +20,7 @@ trait Positions extends scala.reflect.internal.Positions {
// When we prune due to encountering a position, traverse the
// pruned children so we can warn about those lacking positions.
t.children foreach { c =>
- if ((c eq EmptyTree) || (c eq emptyValDef)) ()
+ if (!c.canHaveAttrs) ()
else if (c.pos == NoPosition) {
reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase)
inform("parent: " + treeSymStatus(t))
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 53d35791b6..5cb43575b8 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -58,7 +58,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
def mkUnchecked(expr: Tree): Tree = atPos(expr.pos) {
// This can't be "Annotated(New(UncheckedClass), expr)" because annotations
// are very picky about things and it crashes the compiler with "unexpected new".
- Annotated(New(scalaDot(UncheckedClass.name), ListOfNil), expr)
+ Annotated(New(scalaDot(UncheckedClass.name), Nil), expr)
}
// if it's a Match, mark the selector unchecked; otherwise nothing.
def mkUncheckedMatch(tree: Tree) = tree match {
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 296d55fec5..54402f0903 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -65,6 +65,13 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
// --- factory methods ----------------------------------------------------------
+ /** Factory method for a primary constructor super call `super.<init>(args_1)...(args_n)`
+ */
+ def PrimarySuperCall(argss: List[List[Tree]]): Tree = argss match {
+ case Nil => Apply(gen.mkSuperSelect, Nil)
+ case xs :: rest => rest.foldLeft(Apply(gen.mkSuperSelect, xs): Tree)(Apply.apply)
+ }
+
/** Generates a template with constructor corresponding to
*
* constrmods (vparams1_) ... (vparams_n) preSuper { presupers }
@@ -82,7 +89,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* body
* }
*/
- def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): Template = {
+ def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): Template = {
/* Add constructor to template */
// create parameters for <init> as synthetic trees.
@@ -117,9 +124,16 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
val superRef: Tree = atPos(superPos)(gen.mkSuperSelect)
- val superCall = (superRef /: argss) (Apply.apply)
+ val superCall = pendingSuperCall // we can't know in advance which of the parents will end up as a superclass
+ // this requires knowing which of the parents is a type macro and which is not
+ // and that's something that cannot be found out before typer
+ // (the type macros aren't in the trunk yet, but there is a plan for them to land there soon)
+ // this means that we don't know what will be the arguments of the super call
+ // therefore here we emit a dummy which gets populated when the template is named and typechecked
List(
- atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
+ // TODO: previously this was `wrappingPos(superPos, lvdefs ::: argss.flatten)`
+ // is it going to be a problem that we can no longer include the `argss`?
+ atPos(wrappingPos(superPos, lvdefs)) (
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
}
}
@@ -137,11 +151,10 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* @param constrMods the modifiers for the class constructor, i.e. as in `class C private (...)`
* @param vparamss the value parameters -- if they have symbols they
* should be owned by `sym`
- * @param argss the supercall arguments
* @param body the template statements without primary constructor
* and value parameter fields.
*/
- def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = {
+ def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): ClassDef = {
// "if they have symbols they should be owned by `sym`"
assert(
mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)),
@@ -151,7 +164,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
ClassDef(sym,
Template(sym.info.parents map TypeTree,
if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
- constrMods, vparamss, argss, body, superPos))
+ constrMods, vparamss, body, superPos))
}
// --- subcomponents --------------------------------------------------
@@ -324,6 +337,8 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
else
super.transform {
tree match {
+ case tree if !tree.canHaveAttrs =>
+ tree
case tpt: TypeTree =>
if (tpt.original != null)
transform(tpt.original)
@@ -337,8 +352,6 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
transform(fn)
case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
tree
- case EmptyTree =>
- tree
case _ =>
val dupl = tree.duplicate
if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)) && !(keepLabels && tree.symbol.isLabel))
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 074fcabec8..33db4ee2d5 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1562,9 +1562,9 @@ self =>
val nstart = in.skipToken()
val npos = r2p(nstart, nstart, in.lastOffset)
val tstart = in.offset
- val (parents, argss, self, stats) = template(isTrait = false)
+ val (parents, self, stats) = template()
val cpos = r2p(tstart, tstart, in.lastOffset max tstart)
- makeNew(parents, self, stats, argss, npos, cpos)
+ makeNew(parents, self, stats, npos, cpos)
case _ =>
syntaxErrorOrIncomplete("illegal start of simple expression", true)
errorTermTree
@@ -2106,7 +2106,7 @@ self =>
def annotationExpr(): Tree = atPos(in.offset) {
val t = exprSimpleType()
if (in.token == LPAREN) New(t, multipleArgumentExprs())
- else New(t, ListOfNil)
+ else New(t, Nil)
}
/* -------- PARAMETERS ------------------------------------------- */
@@ -2742,20 +2742,17 @@ self =>
* TraitParents ::= AnnotType {with AnnotType}
* }}}
*/
- def templateParents(isTrait: Boolean): (List[Tree], List[List[Tree]]) = {
- val parents = new ListBuffer[Tree] += startAnnotType()
- val argss = (
- // TODO: the insertion of ListOfNil here is where "new Foo" becomes
- // indistinguishable from "new Foo()".
- if (in.token == LPAREN && !isTrait) multipleArgumentExprs()
- else ListOfNil
- )
-
- while (in.token == WITH) {
- in.nextToken()
- parents += startAnnotType()
+ def templateParents(): List[Tree] = {
+ val parents = new ListBuffer[Tree]
+ def readAppliedParent() = {
+ val start = in.offset
+ val parent = startAnnotType()
+ val argss = if (in.token == LPAREN) multipleArgumentExprs() else Nil
+ parents += atPos(start)((parent /: argss)(Apply.apply))
}
- (parents.toList, argss)
+ readAppliedParent()
+ while (in.token == WITH) { in.nextToken(); readAppliedParent() }
+ parents.toList
}
/** {{{
@@ -2765,12 +2762,12 @@ self =>
* EarlyDef ::= Annotations Modifiers PatDef
* }}}
*/
- def template(isTrait: Boolean): (List[Tree], List[List[Tree]], ValDef, List[Tree]) = {
+ def template(): (List[Tree], ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) {
// @S: pre template body cannot stub like post body can!
val (self, body) = templateBody(isPre = true)
- if (in.token == WITH && self.isEmpty) {
+ if (in.token == WITH && (self eq emptyValDef)) {
val earlyDefs: List[Tree] = body flatMap {
case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred =>
List(copyValDef(vdef)(mods = mods | Flags.PRESUPER))
@@ -2782,16 +2779,16 @@ self =>
case _ => List()
}
in.nextToken()
- val (parents, argss) = templateParents(isTrait = isTrait)
- val (self1, body1) = templateBodyOpt(traitParentSeen = isTrait)
- (parents, argss, self1, earlyDefs ::: body1)
+ val parents = templateParents()
+ val (self1, body1) = templateBodyOpt(parenMeansSyntaxError = false)
+ (parents, self1, earlyDefs ::: body1)
} else {
- (List(), ListOfNil, self, body)
+ (List(), self, body)
}
} else {
- val (parents, argss) = templateParents(isTrait = isTrait)
- val (self, body) = templateBodyOpt(traitParentSeen = isTrait)
- (parents, argss, self, body)
+ val parents = templateParents()
+ val (self, body) = templateBodyOpt(parenMeansSyntaxError = false)
+ (parents, self, body)
}
}
@@ -2805,15 +2802,15 @@ self =>
* }}}
*/
def templateOpt(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]], tstart: Int): Template = {
- val (parents0, argss, self, body) = (
+ val (parents0, self, body) = (
if (in.token == EXTENDS || in.token == SUBTYPE && mods.isTrait) {
in.nextToken()
- template(isTrait = mods.isTrait)
+ template()
}
else {
newLineOptWhenFollowedBy(LBRACE)
- val (self, body) = templateBodyOpt(traitParentSeen = false)
- (List(), ListOfNil, self, body)
+ val (self, body) = templateBodyOpt(parenMeansSyntaxError = mods.isTrait || name.isTermName)
+ (List(), self, body)
}
)
def anyrefParents() = {
@@ -2835,7 +2832,7 @@ self =>
if (inScalaRootPackage && ScalaValueClassNames.contains(name))
Template(parents0, self, anyvalConstructor :: body)
else
- Template(anyrefParents, self, constrMods, vparamss, argss, body, o2p(tstart))
+ Template(anyrefParents, self, constrMods, vparamss, body, o2p(tstart))
}
}
@@ -2850,14 +2847,15 @@ self =>
case (self, Nil) => (self, EmptyTree.asList)
case result => result
}
- def templateBodyOpt(traitParentSeen: Boolean): (ValDef, List[Tree]) = {
+ def templateBodyOpt(parenMeansSyntaxError: Boolean): (ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) {
templateBody(isPre = false)
} else {
- if (in.token == LPAREN)
- syntaxError((if (traitParentSeen) "parents of traits" else "traits or objects")+
- " may not have parameters", true)
+ if (in.token == LPAREN) {
+ if (parenMeansSyntaxError) syntaxError(s"traits or objects may not have parameters", true)
+ else abort("unexpected opening parenthesis")
+ }
(emptyValDef, List())
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 0ac46a18bc..f94055f666 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -205,20 +205,26 @@ abstract class TreeBuilder {
*/
def makeAnonymousNew(stats: List[Tree]): Tree = {
val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats
- makeNew(Nil, emptyValDef, stats1, ListOfNil, NoPosition, NoPosition)
+ makeNew(Nil, emptyValDef, stats1, NoPosition, NoPosition)
}
/** Create positioned tree representing an object creation <new parents { stats }
* @param npos the position of the new
* @param cpos the position of the anonymous class starting with parents
*/
- def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree], argss: List[List[Tree]],
+ def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree],
npos: Position, cpos: Position): Tree =
if (parents.isEmpty)
- makeNew(List(scalaAnyRefConstr), self, stats, argss, npos, cpos)
- else if (parents.tail.isEmpty && stats.isEmpty)
- atPos(npos union cpos) { New(parents.head, argss) }
- else {
+ makeNew(List(scalaAnyRefConstr), self, stats, npos, cpos)
+ else if (parents.tail.isEmpty && stats.isEmpty) {
+ // `Parsers.template` no longer differentiates tpts and their argss
+ // e.g. `C()` will be represented as a single tree Apply(Ident(C), Nil)
+ // instead of parents = Ident(C), argss = Nil as before
+ // this change works great for things that are actually templates
+ // but in this degenerate case we need to perform postprocessing
+ val app = treeInfo.dissectApplied(parents.head)
+ atPos(npos union cpos) { New(app.callee, app.argss) }
+ } else {
val x = tpnme.ANON_CLASS_NAME
atPos(npos union cpos) {
Block(
@@ -226,12 +232,12 @@ abstract class TreeBuilder {
atPos(cpos) {
ClassDef(
Modifiers(FINAL), x, Nil,
- Template(parents, self, NoMods, ListOfNil, argss, stats, cpos.focus))
+ Template(parents, self, NoMods, ListOfNil, stats, cpos.focus))
}),
atPos(npos) {
New(
Ident(x) setPos npos.focus,
- ListOfNil)
+ Nil)
}
)
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index 068836fe4f..d50d4cd125 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
@@ -320,7 +320,12 @@ trait BasicBlocks {
else
instrs.zipWithIndex collect {
case (oldInstr, i) if map contains oldInstr =>
- code.touched |= replaceInstruction(i, map(oldInstr))
+ // SI-6288 clone important here because `replaceInstruction` assigns
+ // a position to `newInstr`. Without this, a single instruction can
+ // be added twice, and the position last position assigned clobbers
+ // all previous positions in other usages.
+ val newInstr = map(oldInstr).clone()
+ code.touched |= replaceInstruction(i, newInstr)
}
////////////////////// Emit //////////////////////
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index ea4e8475f9..fd2b11898c 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -753,7 +753,8 @@ abstract class GenICode extends SubComponent {
} else
ctx1.bb.emit(CONSTANT(Constant(false)))
} else if (r.isValueType && cast) {
- assert(false, tree) /* Erasure should have added an unboxing operation to prevent that. */
+ /* Erasure should have added an unboxing operation to prevent that. */
+ abort("should have been unboxed by erasure: " + tree)
} else if (r.isValueType) {
ctx.bb.emit(IS_INSTANCE(REFERENCE(definitions.boxedClass(r.toType.typeSymbol))))
} else {
@@ -1257,7 +1258,7 @@ abstract class GenICode extends SubComponent {
val sym = (
if (!tree.symbol.isPackageClass) tree.symbol
else tree.symbol.info.member(nme.PACKAGE) match {
- case NoSymbol => assert(false, "Cannot use package as value: " + tree) ; NoSymbol
+ case NoSymbol => abort("Cannot use package as value: " + tree)
case s => debugwarn("Bug: found package class where package object expected. Converting.") ; s.moduleClass
}
)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 6eb05c4402..d185ed0c34 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -21,7 +21,7 @@ import asm.Label
*
* Documentation at http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/2012Q2/GenASM.pdf
*/
-abstract class GenASM extends SubComponent with BytecodeWriters {
+abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
import global._
import icodes._
import icodes.opcodes._
@@ -32,20 +32,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
/** Create a new phase */
override def newPhase(p: Phase): Phase = new AsmPhase(p)
- private def outputDirectory(sym: Symbol): AbstractFile =
- settings.outputDirs outputDirFor beforeFlatten(sym.sourceFile)
-
- private def getFile(base: AbstractFile, clsName: String, suffix: String): AbstractFile = {
- var dir = base
- val pathParts = clsName.split("[./]").toList
- for (part <- pathParts.init) {
- dir = dir.subdirectoryNamed(part)
- }
- dir.fileNamed(pathParts.last + suffix)
- }
- private def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile =
- getFile(outputDirectory(sym), clsName, suffix)
-
/** JVM code generation phase
*/
class AsmPhase(prev: Phase) extends ICodePhase(prev) {
@@ -55,62 +41,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
val BeanInfoAttr = rootMirror.getRequiredClass("scala.beans.BeanInfo")
- def isJavaEntryPoint(icls: IClass) = {
- val sym = icls.symbol
- def fail(msg: String, pos: Position = sym.pos) = {
- icls.cunit.warning(sym.pos,
- 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
- // + " You can still run the program by calling it as " + sym.javaSimpleName + " instead."
- )
- false
- }
- 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.
- beforeErasure {
- 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)
- }
- }
- }
- }
- }
-
private def initBytecodeWriter(entryPoints: List[IClass]): BytecodeWriter = {
settings.outputDirs.getSingleOutput match {
case Some(f) if f hasExtension "jar" =>
@@ -160,7 +90,14 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
}
// For predictably ordered error messages.
- var sortedClasses = classes.values.toList sortBy ("" + _.symbol.fullName)
+ var sortedClasses = classes.values.toList sortBy (_.symbol.fullName)
+
+ // Warn when classes will overwrite one another on case-insensitive systems.
+ for ((_, v1 :: v2 :: _) <- sortedClasses groupBy (_.symbol.javaClassName.toString.toLowerCase)) {
+ v1.cunit.warning(v1.symbol.pos,
+ s"Class ${v1.symbol.javaClassName} differs only in case from ${v2.symbol.javaClassName}. " +
+ "Such classes will overwrite one another on case-insensitive filesystems.")
+ }
debuglog("Created new bytecode generator for " + classes.size + " classes.")
val bytecodeWriter = initBytecodeWriter(sortedClasses filter isJavaEntryPoint)
@@ -1090,12 +1027,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
// a plain class lacking companion module, for details see `isCandidateForForwarders`).
// -----------------------------------------------------------------------------------------
- val ExcludedForwarderFlags = {
- import Flags._
- // Should include DEFERRED but this breaks findMember.
- ( CASE | SPECIALIZED | LIFTED | PROTECTED | STATIC | EXPANDEDNAME | BridgeAndPrivateFlags )
- }
-
/** Add a forwarder for method m. Used only from addForwarders(). */
private def addForwarder(isRemoteClass: Boolean, jclass: asm.ClassVisitor, module: Symbol, m: Symbol) {
val moduleName = javaName(module)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 3d29b2590e..fe0020e074 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -26,7 +26,7 @@ import scala.language.postfixOps
* @version 1.0
*
*/
-abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with BytecodeWriters {
+abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with BytecodeWriters with GenJVMASM {
import global._
import icodes._
import icodes.opcodes._
@@ -37,20 +37,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
/** Create a new phase */
override def newPhase(p: Phase): Phase = new JvmPhase(p)
- private def outputDirectory(sym: Symbol): AbstractFile =
- settings.outputDirs outputDirFor beforeFlatten(sym.sourceFile)
-
- private def getFile(base: AbstractFile, clsName: String, suffix: String): AbstractFile = {
- var dir = base
- val pathParts = clsName.split("[./]").toList
- for (part <- pathParts.init) {
- dir = dir.subdirectoryNamed(part)
- }
- dir.fileNamed(pathParts.last + suffix)
- }
- private def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile =
- getFile(outputDirectory(sym), clsName, suffix)
-
/** JVM code generation phase
*/
class JvmPhase(prev: Phase) extends ICodePhase(prev) {
@@ -58,63 +44,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
override def erasedTypes = true
def apply(cls: IClass) = sys.error("no implementation")
- def isJavaEntryPoint(clasz: IClass) = {
- val sym = clasz.symbol
- def fail(msg: String, pos: Position = sym.pos) = {
- clasz.cunit.warning(sym.pos,
- 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
- // + " You can still run the program by calling it as " + sym.javaSimpleName + " instead."
- )
- false
- }
- 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.
- beforeErasure {
- 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)
- }
- }
- }
- }
- }
-
override def run() {
// we reinstantiate the bytecode generator at each run, to allow the GC
// to collect everything
@@ -210,12 +139,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val BeanDisplayNameAttr = rootMirror.getRequiredClass("scala.beans.BeanDisplayName")
val BeanDescriptionAttr = rootMirror.getRequiredClass("scala.beans.BeanDescription")
- final val ExcludedForwarderFlags = {
- import Flags._
- // Should include DEFERRED but this breaks findMember.
- ( CASE | SPECIALIZED | LIFTED | PROTECTED | STATIC | EXPANDEDNAME | BridgeAndPrivateFlags )
- }
-
// Additional interface parents based on annotations and other cues
def newParentForAttr(attr: Symbol): Option[Symbol] = attr match {
case SerializableAttr => Some(SerializableClass)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala
new file mode 100644
index 0000000000..49c0fa2757
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala
@@ -0,0 +1,97 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2013 LAMP/EPFL
+ * @author Jason Zaugg
+ */
+
+package scala.tools.nsc
+package backend.jvm
+import scala.tools.nsc.io.AbstractFile
+import scala.tools.nsc.symtab._
+
+/** Code shared between the legagy backend [[scala.tools.nsc.backend.jvm.GenJVM]]
+ * and the new backend [[scala.tools.nsc.backend.jvm.GenASM]]. There should be
+ * more here, but for now I'm starting with the refactorings that are either
+ * straightforward to review or necessary for maintenance.
+ */
+trait GenJVMASM {
+ val global: Global
+ import global._
+ import icodes._
+ import definitions._
+
+ protected def outputDirectory(sym: Symbol): AbstractFile =
+ settings.outputDirs outputDirFor beforeFlatten(sym.sourceFile)
+
+ protected def getFile(base: AbstractFile, clsName: String, suffix: String): AbstractFile = {
+ var dir = base
+ val pathParts = clsName.split("[./]").toList
+ for (part <- pathParts.init) {
+ dir = dir.subdirectoryNamed(part)
+ }
+ dir.fileNamed(pathParts.last + suffix)
+ }
+ protected def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile =
+ getFile(outputDirectory(sym), clsName, suffix)
+
+ protected val ExcludedForwarderFlags = {
+ import Flags._
+ // Should include DEFERRED but this breaks findMember.
+ ( CASE | SPECIALIZED | LIFTED | PROTECTED | STATIC | EXPANDEDNAME | BridgeAndPrivateFlags | MACRO )
+ }
+
+ protected def isJavaEntryPoint(icls: IClass) = {
+ val sym = icls.symbol
+ def fail(msg: String, pos: Position = sym.pos) = {
+ icls.cunit.warning(sym.pos,
+ 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
+ // + " You can still run the program by calling it as " + sym.javaSimpleName + " instead."
+ )
+ false
+ }
+ 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.
+ beforeErasure {
+ 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)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
index bb14c3dce0..23f932b5b4 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
@@ -147,18 +147,18 @@ abstract class ClosureElimination extends SubComponent {
case _ =>
}
- case UNBOX(_) =>
+ case UNBOX(boxType) =>
info.stack match {
case Deref(LocalVar(loc1)) :: _ if info.bindings isDefinedAt LocalVar(loc1) =>
val value = info.getBinding(loc1)
value match {
- case Boxed(LocalVar(loc2)) =>
+ case Boxed(LocalVar(loc2)) if loc2.kind == boxType =>
bb.replaceInstruction(i, DROP(icodes.ObjectReference) :: valueToInstruction(info.getBinding(loc2)) :: Nil)
debuglog("replaced " + i + " with " + info.getBinding(loc2))
case _ =>
()
}
- case Boxed(LocalVar(loc1)) :: _ =>
+ case Boxed(LocalVar(loc1)) :: _ if loc1.kind == boxType =>
val loc2 = info.getAlias(loc1)
bb.replaceInstruction(i, DROP(icodes.ObjectReference) :: valueToInstruction(Deref(LocalVar(loc2))) :: Nil)
debuglog("replaced " + i + " with " + LocalVar(loc2))
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
index 642e330a57..a091b04993 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -80,7 +80,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
with model.ModelFactoryImplicitSupport
with model.ModelFactoryTypeSupport
with model.diagram.DiagramFactory
- with model.comment.CommentFactory
+ with model.CommentFactory
with model.TreeFactory
with model.MemberLookup {
override def templateShouldDocument(sym: compiler.Symbol, inTpl: DocTemplateImpl) =
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala
index 40057bbb52..f60d56d9bb 100644..100755
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala
@@ -1,13 +1,13 @@
/* NSC -- new Scala compiler
- * Copyright 2007-2013 LAMP/EPFL
+ * Copyright 2007-2012 LAMP/EPFL
* @author Manohar Jonnalagedda
*/
package scala.tools.nsc
package doc
-package model
-package comment
+package base
+import base.comment._
import reporters.Reporter
import scala.collection._
import scala.util.matching.Regex
@@ -23,78 +23,10 @@ import scala.language.postfixOps
*
* @author Manohar Jonnalagedda
* @author Gilles Dubochet */
-trait CommentFactory { thisFactory: ModelFactory with CommentFactory with MemberLookup=>
+trait CommentFactoryBase { this: MemberLookupBase =>
val global: Global
- import global.{ reporter, definitions }
-
- protected val commentCache = mutable.HashMap.empty[(global.Symbol, TemplateImpl), Comment]
-
- def addCommentBody(sym: global.Symbol, inTpl: TemplateImpl, docStr: String, docPos: global.Position): global.Symbol = {
- commentCache += (sym, inTpl) -> parse(docStr, docStr, docPos, None)
- sym
- }
-
- def comment(sym: global.Symbol, currentTpl: Option[DocTemplateImpl], inTpl: DocTemplateImpl): Option[Comment] = {
- val key = (sym, inTpl)
- if (commentCache isDefinedAt key)
- Some(commentCache(key))
- else {
- val c = defineComment(sym, currentTpl, inTpl)
- if (c isDefined) commentCache += (sym, inTpl) -> c.get
- c
- }
- }
-
- /** A comment is usualy created by the parser, however for some special
- * cases we have to give some `inTpl` comments (parent class for example)
- * to the comment of the symbol.
- * This function manages some of those cases : Param accessor and Primary constructor */
- def defineComment(sym: global.Symbol, currentTpl: Option[DocTemplateImpl], inTpl: DocTemplateImpl):Option[Comment] = {
-
- //param accessor case
- // We just need the @param argument, we put it into the body
- if( sym.isParamAccessor &&
- inTpl.comment.isDefined &&
- inTpl.comment.get.valueParams.isDefinedAt(sym.encodedName)) {
- val comContent = Some(inTpl.comment.get.valueParams(sym.encodedName))
- Some(createComment(body0 = comContent))
- }
-
- // Primary constructor case
- // We need some content of the class definition : @constructor for the body,
- // @param and @deprecated, we can add some more if necessary
- else if (sym.isPrimaryConstructor && inTpl.comment.isDefined ) {
- val tplComment = inTpl.comment.get
- // If there is nothing to put into the comment there is no need to create it
- if(tplComment.constructor.isDefined ||
- tplComment.throws != Map.empty ||
- tplComment.valueParams != Map.empty ||
- tplComment.typeParams != Map.empty ||
- tplComment.deprecated.isDefined
- )
- Some(createComment( body0 = tplComment.constructor,
- throws0 = tplComment.throws,
- valueParams0 = tplComment.valueParams,
- typeParams0 = tplComment.typeParams,
- deprecated0 = tplComment.deprecated
- ))
- else None
- }
-
- //other comment cases
- // parse function will make the comment
- else {
- val rawComment = global.expandedDocComment(sym, inTpl.sym).trim
- if (rawComment != "") {
- val tplOpt = if (currentTpl.isDefined) currentTpl else Some(inTpl)
- val c = parse(rawComment, global.rawDocComment(sym), global.docCommentPos(sym), tplOpt)
- Some(c)
- }
- else None
- }
-
- }
+ import global.{ reporter, definitions, Symbol }
/* Creates comments with necessary arguments */
def createComment (
@@ -259,9 +191,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
* @param comment The expanded comment string (including start and end markers) to be parsed.
* @param src The raw comment source string.
* @param pos The position of the comment in source. */
- protected def parse(comment: String, src: String, pos: Position, inTplOpt: Option[DocTemplateImpl] = None): Comment = {
- assert(!inTplOpt.isDefined || inTplOpt.get != null)
-
+ protected def parseAtSymbol(comment: String, src: String, pos: Position, siteOpt: Option[Symbol] = None): Comment = {
/** The cleaned raw comment as a list of lines. Cleaning removes comment
* start and end markers, line start markers and unnecessary whitespace. */
def clean(comment: String): List[String] = {
@@ -387,7 +317,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
val tagsWithoutDiagram = tags.filterNot(pair => stripTags.contains(pair._1))
val bodyTags: mutable.Map[TagKey, List[Body]] =
- mutable.Map(tagsWithoutDiagram mapValues {tag => tag map (parseWiki(_, pos, inTplOpt))} toSeq: _*)
+ mutable.Map(tagsWithoutDiagram mapValues {tag => tag map (parseWikiAtSymbol(_, pos, siteOpt))} toSeq: _*)
def oneTag(key: SimpleTagKey): Option[Body] =
((bodyTags remove key): @unchecked) match {
@@ -420,7 +350,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
}
val com = createComment (
- body0 = Some(parseWiki(docBody.toString, pos, inTplOpt)),
+ body0 = Some(parseWikiAtSymbol(docBody.toString, pos, siteOpt)),
authors0 = allTags(SimpleTagKey("author")),
see0 = allTags(SimpleTagKey("see")),
result0 = oneTag(SimpleTagKey("return")),
@@ -460,24 +390,17 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
* - Removed start-of-line star and one whitespace afterwards (if present).
* - Removed all end-of-line whitespace.
* - Only `endOfLine` is used to mark line endings. */
- def parseWiki(string: String, pos: Position, inTplOpt: Option[DocTemplateImpl]): Body = {
- assert(!inTplOpt.isDefined || inTplOpt.get != null)
-
- new WikiParser(string, pos, inTplOpt).document()
- }
+ def parseWikiAtSymbol(string: String, pos: Position, siteOpt: Option[Symbol]): Body = new WikiParser(string, pos, siteOpt).document()
/** TODO
*
* @author Ingo Maier
* @author Manohar Jonnalagedda
* @author Gilles Dubochet */
- protected final class WikiParser(val buffer: String, pos: Position, inTplOpt: Option[DocTemplateImpl]) extends CharReader(buffer) { wiki =>
- assert(!inTplOpt.isDefined || inTplOpt.get != null)
-
+ protected final class WikiParser(val buffer: String, pos: Position, siteOpt: Option[Symbol]) extends CharReader(buffer) { wiki =>
var summaryParsed = false
def document(): Body = {
- nextChar()
val blocks = new mutable.ListBuffer[Block]
while (char != endOfText)
blocks += block()
@@ -559,21 +482,21 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
def code(): Block = {
jumpWhitespace()
jump("{{{")
- readUntil("}}}")
+ val str = readUntil("}}}")
if (char == endOfText)
reportError(pos, "unclosed code block")
else
jump("}}}")
blockEnded("code block")
- Code(normalizeIndentation(getRead))
+ Code(normalizeIndentation(str))
}
/** {{{ title ::= ('=' inline '=' | "==" inline "==" | ...) '\n' }}} */
def title(): Block = {
jumpWhitespace()
- val inLevel = repeatJump("=")
+ val inLevel = repeatJump('=')
val text = inline(check("=" * inLevel))
- val outLevel = repeatJump("=", inLevel)
+ val outLevel = repeatJump('=', inLevel)
if (inLevel != outLevel)
reportError(pos, "unbalanced or unclosed heading")
blockEnded("heading")
@@ -583,7 +506,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
/** {{{ hrule ::= "----" { '-' } '\n' }}} */
def hrule(): Block = {
jumpWhitespace()
- repeatJump("-")
+ repeatJump('-')
blockEnded("horizontal rule")
HorizontalRule()
}
@@ -621,8 +544,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
}
do {
- readUntil { char == safeTagMarker || char == endOfText }
- val str = getRead()
+ val str = readUntil { char == safeTagMarker || char == endOfText }
nextChar()
list += str
@@ -660,8 +582,8 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
else if (check(",,")) subscript()
else if (check("[[")) link()
else {
- readUntil { char == safeTagMarker || check("''") || char == '`' || check("__") || char == '^' || check(",,") || check("[[") || isInlineEnd || checkParaEnded || char == endOfLine }
- Text(getRead())
+ val str = readUntil { char == safeTagMarker || check("''") || char == '`' || check("__") || char == '^' || check(",,") || check("[[") || isInlineEnd || checkParaEnded || char == endOfLine }
+ Text(str)
}
}
@@ -698,9 +620,8 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
def htmlTag(): HtmlTag = {
jump(safeTagMarker)
- readUntil(safeTagMarker)
+ val read = readUntil(safeTagMarker)
if (char != endOfText) jump(safeTagMarker)
- var read = getRead
HtmlTag(read)
}
@@ -762,14 +683,11 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
def link(): Inline = {
val SchemeUri = """([a-z]+:.*)""".r
jump("[[")
- var parens = 1
- readUntil { parens += 1; !check("[") }
- getRead // clear the buffer
+ var parens = 2 + repeatJump('[')
val start = "[" * parens
val stop = "]" * parens
//println("link with " + parens + " matching parens")
- readUntil { check(stop) || check(" ") }
- val target = getRead()
+ val target = readUntil { check(stop) || check(" ") }
val title =
if (!check(stop)) Some({
jump(" ")
@@ -782,7 +700,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
case (SchemeUri(uri), optTitle) =>
Link(uri, optTitle getOrElse Text(uri))
case (qualName, optTitle) =>
- makeEntityLink(optTitle getOrElse Text(target), pos, target, inTplOpt)
+ makeEntityLink(optTitle getOrElse Text(target), pos, target, siteOpt)
}
}
@@ -860,7 +778,6 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
(char == endOfText) ||
((char == endOfLine) && {
val poff = offset
- val pc = char
nextChar() // read EOL
val ok = {
checkSkipInitWhitespace(endOfLine) ||
@@ -870,7 +787,6 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
checkSkipInitWhitespace('\u003D')
}
offset = poff
- char = pc
ok
})
}
@@ -882,40 +798,31 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
protected sealed class CharReader(buffer: String) { reader =>
- var char: Char = _
var offset: Int = 0
+ def char: Char =
+ if (offset >= buffer.length) endOfText else buffer charAt offset
final def nextChar() {
- if (offset >= buffer.length)
- char = endOfText
- else {
- char = buffer charAt offset
- offset += 1
- }
+ offset += 1
}
final def check(chars: String): Boolean = {
val poff = offset
- val pc = char
val ok = jump(chars)
offset = poff
- char = pc
ok
}
def checkSkipInitWhitespace(c: Char): Boolean = {
val poff = offset
- val pc = char
jumpWhitespace()
val ok = jump(c)
offset = poff
- char = pc
ok
}
def checkSkipInitWhitespace(chars: String): Boolean = {
val poff = offset
- val pc = char
jumpWhitespace()
val (ok0, chars0) =
if (chars.charAt(0) == ' ')
@@ -924,20 +831,17 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
(true, chars)
val ok = ok0 && jump(chars0)
offset = poff
- char = pc
ok
}
def countWhitespace: Int = {
var count = 0
val poff = offset
- val pc = char
while (isWhitespace(char) && char != endOfText) {
nextChar()
count += 1
}
offset = poff
- char = pc
count
}
@@ -964,38 +868,10 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
index == chars.length
}
- final def checkedJump(chars: String): Boolean = {
- val poff = offset
- val pc = char
- val ok = jump(chars)
- if (!ok) {
- offset = poff
- char = pc
- }
- ok
- }
-
- final def repeatJump(chars: String, max: Int): Int = {
- var count = 0
- var more = true
- while (more && count < max) {
- if (!checkedJump(chars))
- more = false
- else
- count += 1
- }
- count
- }
-
- final def repeatJump(chars: String): Int = {
+ final def repeatJump(c: Char, max: Int = Int.MaxValue): Int = {
var count = 0
- var more = true
- while (more) {
- if (!checkedJump(chars))
- more = false
- else
- count += 1
- }
+ while (jump(c) && count < max)
+ count += 1
count
}
@@ -1035,47 +911,41 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
/* READERS */
- private val readBuilder = new mutable.StringBuilder
-
- final def getRead(): String = {
- val bld = readBuilder.toString
- readBuilder.clear()
- if (bld.length < 6) bld.intern else bld
- }
-
- final def readUntil(ch: Char): Int = {
- var count = 0
- while (char != ch && char != endOfText) {
- readBuilder += char
- nextChar()
+ final def readUntil(c: Char): String = {
+ withRead {
+ while (char != c && char != endOfText) {
+ nextChar()
+ }
}
- count
}
- final def readUntil(chars: String): Int = {
+ final def readUntil(chars: String): String = {
assert(chars.length > 0)
- var count = 0
- val c = chars.charAt(0)
- while (!check(chars) && char != endOfText) {
- readBuilder += char
- nextChar()
- while (char != c && char != endOfText) {
- readBuilder += char
+ withRead {
+ val c = chars.charAt(0)
+ while (!check(chars) && char != endOfText) {
nextChar()
+ while (char != c && char != endOfText)
+ nextChar()
}
}
- count
}
- final def readUntil(pred: => Boolean): Int = {
- var count = 0
- while (!pred && char != endOfText) {
- readBuilder += char
- nextChar()
+ final def readUntil(pred: => Boolean): String = {
+ withRead {
+ while (char != endOfText && !pred) {
+ nextChar()
+ }
}
- count
}
+ private def withRead(read: => Unit): String = {
+ val start = offset
+ read
+ buffer.substring(start, offset)
+ }
+
+
/* CHARS CLASSES */
def isWhitespace(c: Char) = c == ' ' || c == '\t'
diff --git a/src/compiler/scala/tools/nsc/doc/base/LinkTo.scala b/src/compiler/scala/tools/nsc/doc/base/LinkTo.scala
new file mode 100755
index 0000000000..c11179800c
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/base/LinkTo.scala
@@ -0,0 +1,15 @@
+/* NSC -- new Scala compiler
+ * Copyright 2007-2013 LAMP/EPFL
+ */
+
+package scala.tools.nsc
+package doc
+package base
+
+import scala.collection._
+
+sealed trait LinkTo
+final case class LinkToMember[Mbr, Tpl](mbr: Mbr, tpl: Tpl) extends LinkTo
+final case class LinkToTpl[Tpl](tpl: Tpl) extends LinkTo
+final case class LinkToExternal(name: String, url: String) extends LinkTo
+final case class Tooltip(name: String) extends LinkTo
diff --git a/src/compiler/scala/tools/nsc/doc/base/MemberLookupBase.scala b/src/compiler/scala/tools/nsc/doc/base/MemberLookupBase.scala
new file mode 100755
index 0000000000..f3a5660dc4
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/base/MemberLookupBase.scala
@@ -0,0 +1,230 @@
+package scala.tools.nsc
+package doc
+package base
+
+import comment._
+
+/** This trait extracts all required information for documentation from compilation units.
+ * The base trait has been extracted to allow getting light-weight documentation
+ * for a particular symbol in the IDE.*/
+trait MemberLookupBase {
+
+ val global: Global
+ val settings: doc.Settings
+
+ import global._
+ def internalLink(sym: Symbol, site: Symbol): Option[LinkTo]
+ def chooseLink(links: List[LinkTo]): LinkTo
+
+ import global._
+ import definitions.{ NothingClass, AnyClass, AnyValClass, AnyRefClass, ListClass }
+ import rootMirror.{RootPackage, EmptyPackage}
+
+ private def isRoot(s: Symbol) = s.isRootSymbol || s.isEmptyPackage || s.isEmptyPackageClass
+
+ def makeEntityLink(title: Inline, pos: Position, query: String, siteOpt: Option[Symbol]) =
+ new EntityLink(title) { lazy val link = memberLookup(pos, query, siteOpt) }
+
+ def memberLookup(pos: Position, query: String, siteOpt: Option[Symbol]): LinkTo = {
+ var members = breakMembers(query)
+
+ // (1) First look in the root package, as most of the links are qualified
+ val fromRoot = lookupInRootPackage(pos, members)
+
+ // (2) Or recursively go into each containing template.
+ val fromParents = siteOpt.fold(Stream.empty[Symbol]) { s =>
+ Stream.iterate(s)(_.owner)
+ }.takeWhile (!isRoot(_)).map {
+ lookupInTemplate(pos, members, _)
+ }
+
+ val syms = (fromRoot +: fromParents) find (!_.isEmpty) getOrElse Nil
+
+ val links = syms flatMap { case (sym, site) => internalLink(sym, site) } match {
+ case Nil =>
+ // (3) Look at external links
+ syms.flatMap { case (sym, owner) =>
+ // reconstruct the original link
+ def linkName(sym: Symbol) = {
+ def nameString(s: Symbol) = s.nameString + (if ((s.isModule || s.isModuleClass) && !s.isPackage) "$" else "")
+ val packageSuffix = if (sym.isPackage) ".package" else ""
+
+ sym.ownerChain.reverse.filterNot(isRoot(_)).map(nameString(_)).mkString(".") + packageSuffix
+ }
+
+ if (sym.isClass || sym.isModule || sym.isTrait || sym.isPackage)
+ findExternalLink(sym, linkName(sym))
+ else if (owner.isClass || owner.isModule || owner.isTrait || owner.isPackage)
+ findExternalLink(sym, linkName(owner) + "@" + externalSignature(sym))
+ else
+ None
+ }
+ case links => links
+ }
+ links match {
+ case Nil =>
+ if (!settings.docNoLinkWarnings.value)
+ reporter.warning(pos, "Could not find any member to link for \"" + query + "\".")
+ // (4) if we still haven't found anything, create a tooltip
+ Tooltip(query)
+ case List(l) => l
+ case links =>
+ val chosen = chooseLink(links)
+ def linkToString(link: LinkTo) = {
+ val chosenInfo =
+ if (link == chosen) " [chosen]" else ""
+ link.toString + chosenInfo + "\n"
+ }
+ if (!settings.docNoLinkWarnings.value)
+ reporter.warning(pos,
+ "The link target \"" + query + "\" is ambiguous. Several (possibly overloaded) members fit the target:\n" +
+ links.map(linkToString).mkString +
+ (if (MemberLookup.showExplanation)
+ "\n\n" +
+ "Quick crash course on using Scaladoc links\n" +
+ "==========================================\n" +
+ "Disambiguating terms and types: Prefix terms with '$' and types with '!' in case both names are in use:\n" +
+ " - [[scala.collection.immutable.List!.apply class List's apply method]] and\n" +
+ " - [[scala.collection.immutable.List$.apply object List's apply method]]\n" +
+ "Disambiguating overloaded members: If a term is overloaded, you can indicate the first part of its signature followed by *:\n" +
+ " - [[[scala.collection.immutable.List$.fill[A](Int)(⇒A):List[A]* Fill with a single parameter]]]\n" +
+ " - [[[scala.collection.immutable.List$.fill[A](Int,Int)(⇒A):List[List[A]]* Fill with a two parameters]]]\n" +
+ "Notes: \n" +
+ " - you can use any number of matching square brackets to avoid interference with the signature\n" +
+ " - you can use \\. to escape dots in prefixes (don't forget to use * at the end to match the signature!)\n" +
+ " - you can use \\# to escape hashes, otherwise they will be considered as delimiters, like dots.\n"
+ else "")
+ )
+ chosen
+ }
+ }
+
+ private abstract class SearchStrategy
+ private object BothTypeAndTerm extends SearchStrategy
+ private object OnlyType extends SearchStrategy
+ private object OnlyTerm extends SearchStrategy
+
+ private def lookupInRootPackage(pos: Position, members: List[String]) =
+ lookupInTemplate(pos, members, EmptyPackage) ::: lookupInTemplate(pos, members, RootPackage)
+
+ private def lookupInTemplate(pos: Position, members: List[String], container: Symbol): List[(Symbol, Symbol)] = {
+ // Maintaining compatibility with previous links is a bit tricky here:
+ // we have a preference for term names for all terms except for the last, where we prefer a class:
+ // How to do this:
+ // - at each step we do a DFS search with the prefered strategy
+ // - if the search doesn't return any members, we backtrack on the last decision
+ // * we look for terms with the last member's name
+ // * we look for types with the same name, all the way up
+ val result = members match {
+ case Nil => Nil
+ case mbrName::Nil =>
+ var syms = lookupInTemplate(pos, mbrName, container, OnlyType) map ((_, container))
+ if (syms.isEmpty)
+ syms = lookupInTemplate(pos, mbrName, container, OnlyTerm) map ((_, container))
+ syms
+
+ case tplName::rest =>
+ def completeSearch(syms: List[Symbol]) =
+ syms flatMap (lookupInTemplate(pos, rest, _))
+
+ completeSearch(lookupInTemplate(pos, tplName, container, OnlyTerm)) match {
+ case Nil => completeSearch(lookupInTemplate(pos, tplName, container, OnlyType))
+ case syms => syms
+ }
+ }
+ //println("lookupInTemplate(" + members + ", " + container + ") => " + result)
+ result
+ }
+
+ private def lookupInTemplate(pos: Position, member: String, container: Symbol, strategy: SearchStrategy): List[Symbol] = {
+ val name = member.stripSuffix("$").stripSuffix("!").stripSuffix("*")
+ def signatureMatch(sym: Symbol): Boolean = externalSignature(sym).startsWith(name)
+
+ // We need to cleanup the bogus classes created by the .class file parser. For example, [[scala.Predef]] resolves
+ // to (bogus) class scala.Predef loaded by the class loader -- which we need to eliminate by looking at the info
+ // and removing NoType classes
+ def cleanupBogusClasses(syms: List[Symbol]) = { syms.filter(_.info != NoType) }
+
+ def syms(name: Name) = container.info.nonPrivateMember(name.encodedName).alternatives
+ def termSyms = cleanupBogusClasses(syms(newTermName(name)))
+ def typeSyms = cleanupBogusClasses(syms(newTypeName(name)))
+
+ val result = if (member.endsWith("$"))
+ termSyms
+ else if (member.endsWith("!"))
+ typeSyms
+ else if (member.endsWith("*"))
+ cleanupBogusClasses(container.info.nonPrivateDecls) filter signatureMatch
+ else
+ if (strategy == BothTypeAndTerm)
+ termSyms ::: typeSyms
+ else if (strategy == OnlyType)
+ typeSyms
+ else if (strategy == OnlyTerm)
+ termSyms
+ else
+ Nil
+
+ //println("lookupInTemplate(" + member + ", " + container + ") => " + result)
+ result
+ }
+
+ private def breakMembers(query: String): List[String] = {
+ // Okay, how does this work? Well: you split on . but you don't want to split on \. => thus the ugly regex
+ // query.split((?<=[^\\\\])\\.).map(_.replaceAll("\\."))
+ // The same code, just faster:
+ var members = List[String]()
+ var index = 0
+ var last_index = 0
+ val length = query.length
+ while (index < length) {
+ if ((query.charAt(index) == '.' || query.charAt(index) == '#') &&
+ ((index == 0) || (query.charAt(index-1) != '\\'))) {
+
+ val member = query.substring(last_index, index).replaceAll("\\\\([#\\.])", "$1")
+ // we want to allow javadoc-style links [[#member]] -- which requires us to remove empty members from the first
+ // elemnt in the list
+ if ((member != "") || (!members.isEmpty))
+ members ::= member
+ last_index = index + 1
+ }
+ index += 1
+ }
+ if (last_index < length)
+ members ::= query.substring(last_index, length).replaceAll("\\\\\\.", ".")
+ members.reverse
+ }
+
+
+ def findExternalLink(sym: Symbol, name: String): Option[LinkToExternal] = {
+ val sym1 =
+ if (sym == AnyClass || sym == AnyRefClass || sym == AnyValClass || sym == NothingClass) ListClass
+ else if (sym.isPackage)
+ /* Get package object which has associatedFile ne null */
+ sym.info.member(newTermName("package"))
+ else sym
+ Option(sym1.associatedFile) flatMap (_.underlyingSource) flatMap { src =>
+ val path = src.path
+ settings.extUrlMapping get path map { url =>
+ LinkToExternal(name, url + "#" + name)
+ }
+ } orElse {
+ // Deprecated option.
+ settings.extUrlPackageMapping find {
+ case (pkg, _) => name startsWith pkg
+ } map {
+ case (_, url) => LinkToExternal(name, url + "#" + name)
+ }
+ }
+ }
+
+ def externalSignature(sym: Symbol) = {
+ sym.info // force it, otherwise we see lazy types
+ (sym.nameString + sym.signatureString).replaceAll("\\s", "")
+ }
+}
+
+object MemberLookup {
+ private[this] var _showExplanation = true
+ def showExplanation: Boolean = if (_showExplanation) { _showExplanation = false; true } else false
+}
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala b/src/compiler/scala/tools/nsc/doc/base/comment/Body.scala
index 3e5e634e18..02e662da85 100644..100755
--- a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
+++ b/src/compiler/scala/tools/nsc/doc/base/comment/Body.scala
@@ -5,7 +5,7 @@
package scala.tools.nsc
package doc
-package model
+package base
package comment
import scala.collection._
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala b/src/compiler/scala/tools/nsc/doc/base/comment/Comment.scala
index 3e172544dd..2b28164ca4 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala
+++ b/src/compiler/scala/tools/nsc/doc/base/comment/Comment.scala
@@ -5,7 +5,7 @@
package scala.tools.nsc
package doc
-package model
+package base
package comment
import scala.collection._
@@ -131,5 +131,4 @@ abstract class Comment {
(authors map ("@author " + _.toString)).mkString("\n") +
(result map ("@return " + _.toString)).mkString("\n") +
(version map ("@version " + _.toString)).mkString
-
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index e8131e242b..69da322418 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -7,8 +7,9 @@ package scala.tools.nsc
package doc
package html
+import base._
+import base.comment._
import model._
-import comment._
import scala.xml.{XML, NodeSeq}
import scala.xml.dtd.{DocType, PublicID}
@@ -126,12 +127,12 @@ abstract class HtmlPage extends Page { thisPage =>
}
def linkToHtml(text: Inline, link: LinkTo, hasLinks: Boolean) = link match {
- case LinkToTpl(dtpl) =>
+ case LinkToTpl(dtpl: TemplateEntity) =>
if (hasLinks)
<a href={ relativeLinkTo(dtpl) } class="extype" name={ dtpl.qualifiedName }>{ inlineToHtml(text) }</a>
else
<span class="extype" name={ dtpl.qualifiedName }>{ inlineToHtml(text) }</span>
- case LinkToMember(mbr, inTpl) =>
+ case LinkToMember(mbr: MemberEntity, inTpl: TemplateEntity) =>
if (hasLinks)
<a href={ relativeLinkTo(inTpl) + "#" + mbr.signature } class="extmbr" name={ mbr.qualifiedName }>{ inlineToHtml(text) }</a>
else
@@ -140,7 +141,7 @@ abstract class HtmlPage extends Page { thisPage =>
<span class="extype" name={ tooltip }>{ inlineToHtml(text) }</span>
case LinkToExternal(name, url) =>
<a href={ url } class="extype" target="_top">{ inlineToHtml(text) }</a>
- case NoLink =>
+ case _ =>
inlineToHtml(text)
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Source.scala b/src/compiler/scala/tools/nsc/doc/html/page/Source.scala
index 807a1bc11a..68289b7474 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Source.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Source.scala
@@ -9,7 +9,6 @@ package html
package page
import model._
-import comment._
import scala.xml.{NodeSeq, Unparsed}
import java.io.File
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index 008999e09f..e885e9c56e 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -8,6 +8,9 @@ package doc
package html
package page
+import base._
+import base.comment._
+
import model._
import model.diagram._
import diagram._
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
index 304c534bdc..847367838c 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
@@ -74,7 +74,7 @@ class DotDiagramGenerator(settings: doc.Settings) extends DiagramGenerator {
def textTypeEntity(text: String) =
new TypeEntity {
val name = text
- def refEntity: SortedMap[Int, (LinkTo, Int)] = SortedMap()
+ def refEntity: SortedMap[Int, (base.LinkTo, Int)] = SortedMap()
}
// it seems dot chokes on node names over 8000 chars, so let's limit the size of the string
diff --git a/src/compiler/scala/tools/nsc/doc/model/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/CommentFactory.scala
new file mode 100644
index 0000000000..9ba89146c0
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/model/CommentFactory.scala
@@ -0,0 +1,114 @@
+/* NSC -- new Scala compiler
+ * Copyright 2007-2013 LAMP/EPFL
+ * @author Manohar Jonnalagedda
+ */
+
+package scala.tools.nsc
+package doc
+package model
+
+import base.comment._
+
+import reporters.Reporter
+import scala.collection._
+import scala.reflect.internal.util.{NoPosition, Position}
+import scala.language.postfixOps
+
+/** The comment parser transforms raw comment strings into `Comment` objects.
+ * Call `parse` to run the parser. Note that the parser is stateless and
+ * should only be built once for a given Scaladoc run.
+ *
+ * @param reporter The reporter on which user messages (error, warnings) should be printed.
+ *
+ * @author Manohar Jonnalagedda
+ * @author Gilles Dubochet */
+trait CommentFactory extends base.CommentFactoryBase {
+ thisFactory: ModelFactory with CommentFactory with MemberLookup =>
+
+ val global: Global
+ import global.{ reporter, definitions, Symbol }
+
+ protected val commentCache = mutable.HashMap.empty[(Symbol, TemplateImpl), Comment]
+
+ def addCommentBody(sym: Symbol, inTpl: TemplateImpl, docStr: String, docPos: global.Position): Symbol = {
+ commentCache += (sym, inTpl) -> parse(docStr, docStr, docPos, None)
+ sym
+ }
+
+ def comment(sym: Symbol, currentTpl: Option[DocTemplateImpl], inTpl: DocTemplateImpl): Option[Comment] = {
+ val key = (sym, inTpl)
+ if (commentCache isDefinedAt key)
+ Some(commentCache(key))
+ else {
+ val c = defineComment(sym, currentTpl, inTpl)
+ if (c isDefined) commentCache += (sym, inTpl) -> c.get
+ c
+ }
+ }
+
+ /** A comment is usualy created by the parser, however for some special
+ * cases we have to give some `inTpl` comments (parent class for example)
+ * to the comment of the symbol.
+ * This function manages some of those cases : Param accessor and Primary constructor */
+ def defineComment(sym: Symbol, currentTpl: Option[DocTemplateImpl], inTpl: DocTemplateImpl):Option[Comment] = {
+
+ //param accessor case
+ // We just need the @param argument, we put it into the body
+ if( sym.isParamAccessor &&
+ inTpl.comment.isDefined &&
+ inTpl.comment.get.valueParams.isDefinedAt(sym.encodedName)) {
+ val comContent = Some(inTpl.comment.get.valueParams(sym.encodedName))
+ Some(createComment(body0 = comContent))
+ }
+
+ // Primary constructor case
+ // We need some content of the class definition : @constructor for the body,
+ // @param and @deprecated, we can add some more if necessary
+ else if (sym.isPrimaryConstructor && inTpl.comment.isDefined ) {
+ val tplComment = inTpl.comment.get
+ // If there is nothing to put into the comment there is no need to create it
+ if(tplComment.constructor.isDefined ||
+ tplComment.throws != Map.empty ||
+ tplComment.valueParams != Map.empty ||
+ tplComment.typeParams != Map.empty ||
+ tplComment.deprecated.isDefined
+ )
+ Some(createComment( body0 = tplComment.constructor,
+ throws0 = tplComment.throws,
+ valueParams0 = tplComment.valueParams,
+ typeParams0 = tplComment.typeParams,
+ deprecated0 = tplComment.deprecated
+ ))
+ else None
+ }
+
+ //other comment cases
+ // parse function will make the comment
+ else {
+ val rawComment = global.expandedDocComment(sym, inTpl.sym).trim
+ if (rawComment != "") {
+ val tplOpt = if (currentTpl.isDefined) currentTpl else Some(inTpl)
+ val c = parse(rawComment, global.rawDocComment(sym), global.docCommentPos(sym), tplOpt)
+ Some(c)
+ }
+ else None
+ }
+
+ }
+
+ protected def parse(comment: String, src: String, pos: Position, inTplOpt: Option[DocTemplateImpl] = None): Comment = {
+ assert(!inTplOpt.isDefined || inTplOpt.get != null)
+ parseAtSymbol(comment, src, pos, inTplOpt map (_.sym))
+ }
+
+ /** Parses a string containing wiki syntax into a `Comment` object.
+ * Note that the string is assumed to be clean:
+ * - Removed Scaladoc start and end markers.
+ * - Removed start-of-line star and one whitespace afterwards (if present).
+ * - Removed all end-of-line whitespace.
+ * - Only `endOfLine` is used to mark line endings. */
+ def parseWiki(string: String, pos: Position, inTplOpt: Option[DocTemplateImpl]): Body = {
+ assert(!inTplOpt.isDefined || inTplOpt.get != null)
+ parseWikiAtSymbol(string,pos, inTplOpt map (_.sym))
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
index c3f9101f17..cbc1a23d44 100644
--- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
@@ -9,7 +9,7 @@ package doc
package model
import scala.collection._
-import comment._
+import base.comment._
import diagram._
/** An entity in a Scaladoc universe. Entities are declarations in the program and correspond to symbols in the
diff --git a/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala b/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala
deleted file mode 100644
index 6c13d5a6d3..0000000000
--- a/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2007-2013 LAMP/EPFL
- */
-
-package scala.tools.nsc
-package doc
-package model
-
-import scala.collection._
-
-abstract sealed class LinkTo
-final case class LinkToTpl(tpl: DocTemplateEntity) extends LinkTo
-final case class LinkToMember(mbr: MemberEntity, inTpl: DocTemplateEntity) extends LinkTo
-final case class Tooltip(name: String) extends LinkTo { def this(tpl: TemplateEntity) = this(tpl.qualifiedName) }
-final case class LinkToExternal(name: String, url: String) extends LinkTo
-case object NoLink extends LinkTo // you should use Tooltip if you have a name from the user, this is only in case all fails
-
-object LinkToTpl {
- // this makes it easier to create links
- def apply(tpl: TemplateEntity) = tpl match {
- case dtpl: DocTemplateEntity => new LinkToTpl(dtpl)
- case ntpl: TemplateEntity => new Tooltip(ntpl.qualifiedName)
- }
-}
diff --git a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala b/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
index 5257db1610..b1105196b7 100644
--- a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
@@ -2,227 +2,30 @@ package scala.tools.nsc
package doc
package model
-import comment._
-
-import scala.reflect.internal.util.FakePos //Position
+import base._
/** This trait extracts all required information for documentation from compilation units */
-trait MemberLookup {
+trait MemberLookup extends base.MemberLookupBase {
thisFactory: ModelFactory =>
import global._
- import rootMirror.RootPackage, rootMirror.EmptyPackage
-
- def makeEntityLink(title: Inline, pos: Position, query: String, inTplOpt: Option[DocTemplateImpl]) =
- new EntityLink(title) { lazy val link = memberLookup(pos, query, inTplOpt) }
-
- def memberLookup(pos: Position, query: String, inTplOpt: Option[DocTemplateImpl]): LinkTo = {
- assert(modelFinished)
-
- var members = breakMembers(query)
- //println(query + " => " + members)
-
- // (1) First look in the root package, as most of the links are qualified
- val fromRoot = lookupInRootPackage(pos, members)
-
- // (2) Or recursively go into each containing template.
- val fromParents = inTplOpt.fold(Stream.empty[DocTemplateImpl]) { tpl =>
- Stream.iterate(tpl)(_.inTemplate)
- }.takeWhile (tpl => tpl != null && !tpl.isRootPackage).map { tpl =>
- lookupInTemplate(pos, members, tpl.asInstanceOf[EntityImpl].sym)
- }
-
- val syms = (fromRoot +: fromParents) find (!_.isEmpty) getOrElse Nil
- val linkTo = createLinks(syms) match {
- case Nil if !syms.isEmpty =>
- // (3) Look at external links
- syms.flatMap { case (sym, owner) =>
-
- // reconstruct the original link
- def linkName(sym: Symbol) = {
- def isRoot(s: Symbol) = s.isRootSymbol || s.isEmptyPackage || s.isEmptyPackageClass
- def nameString(s: Symbol) = s.nameString + (if ((s.isModule || s.isModuleClass) && !s.isPackage) "$" else "")
- val packageSuffix = if (sym.isPackage) ".package" else ""
- sym.ownerChain.reverse.filterNot(isRoot(_)).map(nameString(_)).mkString(".") + packageSuffix
- }
-
- if (sym.isClass || sym.isModule || sym.isTrait || sym.isPackage)
- findExternalLink(sym, linkName(sym))
- else if (owner.isClass || owner.isModule || owner.isTrait || owner.isPackage)
- findExternalLink(sym, linkName(owner) + "@" + externalSignature(sym))
- else
- None
+ override def internalLink(sym: Symbol, site: Symbol): Option[LinkTo] =
+ findTemplateMaybe(sym) match {
+ case Some(tpl) => Some(LinkToTpl(tpl))
+ case None =>
+ findTemplateMaybe(site) flatMap { inTpl =>
+ inTpl.members find (_.asInstanceOf[EntityImpl].sym == sym) map (LinkToMember(_, inTpl))
}
- case links => links
}
- //println(createLinks(syms))
- //println(linkTo)
-
- // (4) if we still haven't found anything, create a tooltip, if we found too many, report
- if (linkTo.isEmpty){
- if (!settings.docNoLinkWarnings.value)
- reporter.warning(pos, "Could not find any member to link for \"" + query + "\".")
- Tooltip(query)
- } else {
- if (linkTo.length > 1) {
-
- val chosen =
- if (linkTo.exists(_.isInstanceOf[LinkToMember]))
- linkTo.collect({case lm: LinkToMember => lm}).min(Ordering[MemberEntity].on[LinkToMember](_.mbr))
- else
- linkTo.head
-
- def linkToString(link: LinkTo) = {
- val description =
- link match {
- case lm@LinkToMember(mbr, inTpl) => " * " + mbr.kind + " \"" + mbr.signature + "\" in " + inTpl.kind + " " + inTpl.qualifiedName
- case lt@LinkToTpl(tpl) => " * " + tpl.kind + " \"" + tpl.qualifiedName + "\""
- case other => " * " + other.toString
- }
- val chosenInfo =
- if (link == chosen)
- " [chosen]"
- else
- ""
- description + chosenInfo + "\n"
- }
- if (!settings.docNoLinkWarnings.value)
- reporter.warning(pos,
- "The link target \"" + query + "\" is ambiguous. Several (possibly overloaded) members fit the target:\n" +
- linkTo.map(link => linkToString(link)).mkString +
- (if (MemberLookup.showExplanation)
- "\n\n" +
- "Quick crash course on using Scaladoc links\n" +
- "==========================================\n" +
- "Disambiguating terms and types: Prefix terms with '$' and types with '!' in case both names are in use:\n" +
- " - [[scala.collection.immutable.List!.apply class List's apply method]] and\n" +
- " - [[scala.collection.immutable.List$.apply object List's apply method]]\n" +
- "Disambiguating overloaded members: If a term is overloaded, you can indicate the first part of its signature followed by *:\n" +
- " - [[[scala.collection.immutable.List$.fill[A](Int)(⇒A):List[A]* Fill with a single parameter]]]\n" +
- " - [[[scala.collection.immutable.List$.fill[A](Int,Int)(⇒A):List[List[A]]* Fill with a two parameters]]]\n" +
- "Notes: \n" +
- " - you can use any number of matching square brackets to avoid interference with the signature\n" +
- " - you can use \\. to escape dots in prefixes (don't forget to use * at the end to match the signature!)\n" +
- " - you can use \\# to escape hashes, otherwise they will be considered as delimiters, like dots.\n"
- else "")
- )
- chosen
- } else
- linkTo.head
+ override def chooseLink(links: List[LinkTo]): LinkTo = {
+ val mbrs = links.collect {
+ case lm@LinkToMember(mbr: MemberEntity, _) => (mbr, lm)
}
- }
-
- private abstract class SearchStrategy
- private object BothTypeAndTerm extends SearchStrategy
- private object OnlyType extends SearchStrategy
- private object OnlyTerm extends SearchStrategy
-
- private def lookupInRootPackage(pos: Position, members: List[String]) =
- lookupInTemplate(pos, members, EmptyPackage) ::: lookupInTemplate(pos, members, RootPackage)
-
- private def createLinks(syms: List[(Symbol, Symbol)]): List[LinkTo] =
- syms.flatMap { case (sym, owner) =>
- findTemplateMaybe(sym) match {
- case Some(tpl) => LinkToTpl(tpl) :: Nil
- case None =>
- findTemplateMaybe(owner) flatMap { inTpl =>
- inTpl.members find (_.asInstanceOf[EntityImpl].sym == sym) map (LinkToMember(_, inTpl))
- }
- }
- }
-
- private def lookupInTemplate(pos: Position, members: List[String], container: Symbol): List[(Symbol, Symbol)] = {
- // Maintaining compatibility with previous links is a bit tricky here:
- // we have a preference for term names for all terms except for the last, where we prefer a class:
- // How to do this:
- // - at each step we do a DFS search with the prefered strategy
- // - if the search doesn't return any members, we backtrack on the last decision
- // * we look for terms with the last member's name
- // * we look for types with the same name, all the way up
- val result = members match {
- case Nil => Nil
- case mbrName::Nil =>
- var syms = lookupInTemplate(pos, mbrName, container, OnlyType) map ((_, container))
- if (syms.isEmpty)
- syms = lookupInTemplate(pos, mbrName, container, OnlyTerm) map ((_, container))
- syms
-
- case tplName::rest =>
- def completeSearch(syms: List[Symbol]) =
- syms flatMap (lookupInTemplate(pos, rest, _))
-
- completeSearch(lookupInTemplate(pos, tplName, container, OnlyTerm)) match {
- case Nil => completeSearch(lookupInTemplate(pos, tplName, container, OnlyType))
- case syms => syms
- }
- }
- //println("lookupInTemplate(" + members + ", " + container + ") => " + result)
- result
- }
-
- private def lookupInTemplate(pos: Position, member: String, container: Symbol, strategy: SearchStrategy): List[Symbol] = {
- val name = member.stripSuffix("$").stripSuffix("!").stripSuffix("*")
- def signatureMatch(sym: Symbol): Boolean = externalSignature(sym).startsWith(name)
-
- // We need to cleanup the bogus classes created by the .class file parser. For example, [[scala.Predef]] resolves
- // to (bogus) class scala.Predef loaded by the class loader -- which we need to eliminate by looking at the info
- // and removing NoType classes
- def cleanupBogusClasses(syms: List[Symbol]) = { syms.filter(_.info != NoType) }
-
- def syms(name: Name) = container.info.nonPrivateMember(name.encodedName).alternatives
- def termSyms = cleanupBogusClasses(syms(newTermName(name)))
- def typeSyms = cleanupBogusClasses(syms(newTypeName(name)))
-
- val result = if (member.endsWith("$"))
- termSyms
- else if (member.endsWith("!"))
- typeSyms
- else if (member.endsWith("*"))
- cleanupBogusClasses(container.info.nonPrivateDecls) filter signatureMatch
+ if (mbrs.isEmpty)
+ links.head
else
- if (strategy == BothTypeAndTerm)
- termSyms ::: typeSyms
- else if (strategy == OnlyType)
- typeSyms
- else if (strategy == OnlyTerm)
- termSyms
- else
- Nil
-
- //println("lookupInTemplate(" + member + ", " + container + ") => " + result)
- result
- }
-
- private def breakMembers(query: String): List[String] = {
- // Okay, how does this work? Well: you split on . but you don't want to split on \. => thus the ugly regex
- // query.split((?<=[^\\\\])\\.).map(_.replaceAll("\\."))
- // The same code, just faster:
- var members = List[String]()
- var index = 0
- var last_index = 0
- val length = query.length
- while (index < length) {
- if ((query.charAt(index) == '.' || query.charAt(index) == '#') &&
- ((index == 0) || (query.charAt(index-1) != '\\'))) {
-
- val member = query.substring(last_index, index).replaceAll("\\\\([#\\.])", "$1")
- // we want to allow javadoc-style links [[#member]] -- which requires us to remove empty members from the first
- // elemnt in the list
- if ((member != "") || (!members.isEmpty))
- members ::= member
- last_index = index + 1
- }
- index += 1
- }
- if (last_index < length)
- members ::= query.substring(last_index, length).replaceAll("\\\\\\.", ".")
- members.reverse
+ mbrs.min(Ordering[MemberEntity].on[(MemberEntity, LinkTo)](_._1))._2
}
}
-
-object MemberLookup {
- private[this] var _showExplanation = true
- def showExplanation: Boolean = if (_showExplanation) { _showExplanation = false; true } else false
-}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 3ae1210ebf..ea074873e8 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -4,8 +4,8 @@ package scala.tools.nsc
package doc
package model
-import comment._
-
+import base._
+import base.comment._
import diagram._
import scala.collection._
@@ -950,7 +950,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
// units.filter should return only one element
(currentRun.units filter (_.source.file == aSym.sourceFile)).toList match {
case List(unit) =>
- (unit.body find (_.symbol == aSym)) match {
+ // SI-4922 `sym == aSym` is insufficent if `aSym` is a clone of symbol
+ // of the parameter in the tree, as can happen with type parametric methods.
+ def isCorrespondingParam(sym: Symbol) = (
+ sym != null &&
+ sym != NoSymbol &&
+ sym.owner == aSym.owner &&
+ sym.name == aSym.name &&
+ sym.isParamWithDefault
+ )
+ (unit.body find (t => isCorrespondingParam(t.symbol))) match {
case Some(ValDef(_,_,_,rhs)) => makeTree(rhs)
case _ => None
}
@@ -1085,31 +1094,12 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
{ val rawComment = global.expandedDocComment(bSym, inTpl.sym)
rawComment.contains("@template") || rawComment.contains("@documentable") }
- def findExternalLink(sym: Symbol, name: String): Option[LinkTo] = {
- val sym1 =
- if (sym == AnyClass || sym == AnyRefClass || sym == AnyValClass || sym == NothingClass) ListClass
- else if (sym.isPackage)
- /* Get package object which has associatedFile ne null */
- sym.info.member(newTermName("package"))
- else sym
- Option(sym1.associatedFile) flatMap (_.underlyingSource) flatMap { src =>
- val path = src.path
- settings.extUrlMapping get path map { url =>
- LinkToExternal(name, url + "#" + name)
- }
- } orElse {
- // Deprecated option.
- settings.extUrlPackageMapping find {
- case (pkg, _) => name startsWith pkg
- } map {
- case (_, url) => LinkToExternal(name, url + "#" + name)
- }
+ object LinkToTpl {
+ // this makes it easier to create links
+ def apply(tpl: TemplateEntity): LinkTo = tpl match {
+ case dtpl: DocTemplateEntity => new LinkToTpl(dtpl)
+ case _ => new Tooltip(tpl.qualifiedName)
}
}
-
- def externalSignature(sym: Symbol) = {
- sym.info // force it, otherwise we see lazy types
- (sym.nameString + sym.signatureString).replaceAll("\\s", "")
- }
}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
index 5334de3797..f88251b22e 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
@@ -10,8 +10,6 @@ package scala.tools.nsc
package doc
package model
-import comment._
-
import scala.collection._
import scala.util.matching.Regex
@@ -608,4 +606,4 @@ trait ModelFactoryImplicitSupport {
false
} else true // the member structure is different foo(3, 5) vs foo(3)(5)
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
index 942ccaf1ba..87dc615c8e 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
@@ -4,8 +4,7 @@ package scala.tools.nsc
package doc
package model
-import comment._
-
+import base._
import diagram._
import scala.collection._
@@ -24,7 +23,8 @@ trait ModelFactoryTypeSupport {
with ModelFactoryTypeSupport
with DiagramFactory
with CommentFactory
- with TreeFactory =>
+ with TreeFactory
+ with MemberLookup =>
import global._
import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass }
diff --git a/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala b/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala
index e4a053e115..cf5c1fb3fb 100644
--- a/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala
@@ -20,7 +20,7 @@ abstract class TypeEntity {
/** Maps which parts of this type's name reference entities. The map is indexed by the position of the first
* character that reference some entity, and contains the entity and the position of the last referenced
* character. The referenced character ranges do not to overlap or nest. The map is sorted by position. */
- def refEntity: SortedMap[Int, (LinkTo, Int)]
+ def refEntity: SortedMap[Int, (base.LinkTo, Int)]
/** The human-readable representation of this type. */
override def toString = name
diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala
index 49cfaffc2e..cd60865ce7 100644
--- a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala
@@ -3,7 +3,6 @@ package model
package diagram
import model._
-import comment.CommentFactory
import java.util.regex.{Pattern, Matcher}
import scala.util.matching.Regex
@@ -259,4 +258,4 @@ trait DiagramDirectiveParser {
result
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala
index db2d0c0175..175b4a6472 100644
--- a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala
@@ -3,7 +3,6 @@ package model
package diagram
import model._
-import comment.CommentFactory
import scala.collection.mutable
// statistics
@@ -25,7 +24,7 @@ trait DiagramFactory extends DiagramDirectiveParser {
// the following can used for hardcoding different relations into the diagram, for bootstrapping purposes
def aggregationNode(text: String) =
- NormalNode(new TypeEntity { val name = text; val refEntity = SortedMap[Int, (LinkTo, Int)]() }, None)()
+ NormalNode(new TypeEntity { val name = text; val refEntity = SortedMap[Int, (base.LinkTo, Int)]() }, None)()
/** Create the inheritance diagram for this template */
def makeInheritanceDiagram(tpl: DocTemplateImpl): Option[Diagram] = {
diff --git a/src/compiler/scala/tools/nsc/interactive/Doc.scala b/src/compiler/scala/tools/nsc/interactive/Doc.scala
new file mode 100755
index 0000000000..4d02de6198
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/interactive/Doc.scala
@@ -0,0 +1,50 @@
+/* NSC -- new Scala compiler
+ * Copyright 2007-2012 LAMP/EPFL
+ * @author Eugene Vigdorchik
+ */
+
+package scala.tools.nsc
+package interactive
+
+import doc.base._
+import comment._
+import scala.xml.NodeSeq
+
+sealed trait DocResult
+final case class UrlResult(url: String) extends DocResult
+final case class HtmlResult(comment: Comment) extends DocResult
+
+abstract class Doc(val settings: doc.Settings) extends MemberLookupBase with CommentFactoryBase {
+
+ override val global: interactive.Global
+ import global._
+
+ def chooseLink(links: List[LinkTo]): LinkTo
+
+ override def internalLink(sym: Symbol, site: Symbol): Option[LinkTo] =
+ ask { () =>
+ if (sym.isClass || sym.isModule)
+ Some(LinkToTpl(sym))
+ else
+ if ((site.isClass || site.isModule) && site.info.members.toList.contains(sym))
+ Some(LinkToMember(sym, site))
+ else
+ None
+ }
+
+ def retrieve(sym: Symbol, site: Symbol): Option[DocResult] = {
+ val sig = ask { () => externalSignature(sym) }
+ findExternalLink(sym, sig) map { link => UrlResult(link.url) } orElse {
+ val resp = new Response[Tree]
+ // Ensure docComment tree is type-checked.
+ val pos = ask { () => docCommentPos(sym) }
+ askTypeAt(pos, resp)
+ resp.get.left.toOption flatMap { _ =>
+ ask { () =>
+ val comment = parseAtSymbol(expandedDocComment(sym), rawDocComment(sym), pos, Some(site))
+ Some(HtmlResult(comment))
+ }
+ }
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 2ab389445f..0fc4fcaaf7 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -74,6 +74,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
if (verboseIDE) println("[%s][%s]".format(projectName, msg))
override def forInteractive = true
+ override def forScaladoc = settings.isScaladoc
/** A map of all loaded files to the rich compilation units that correspond to them.
*/
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index b95f1fa7ca..64117bd8ee 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -144,7 +144,7 @@ self: scala.tools.nsc.Global =>
*/
private def setChildrenPos(pos: Position, trees: List[Tree]): Unit = try {
for (tree <- trees) {
- if (!tree.isEmpty && tree.pos == NoPosition) {
+ if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) {
val children = tree.children
if (children.isEmpty) {
tree setPos pos.focus
@@ -165,7 +165,7 @@ self: scala.tools.nsc.Global =>
*/
override def atPos[T <: Tree](pos: Position)(tree: T): T = {
if (pos.isOpaqueRange) {
- if (!tree.isEmpty && tree.pos == NoPosition) {
+ if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) {
tree.setPos(pos)
val children = tree.children
if (children.nonEmpty) {
@@ -203,7 +203,7 @@ self: scala.tools.nsc.Global =>
def validate(tree: Tree, encltree: Tree): Unit = {
- if (!tree.isEmpty) {
+ if (!tree.isEmpty && tree.canHaveAttrs) {
if (settings.Yposdebug.value && (settings.verbose.value || settings.Yrangepos.value))
println("[%10s] %s".format("validate", treeStatus(tree, encltree)))
diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala
index 5c1837b3bf..ea2333a65b 100644
--- a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala
+++ b/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala
@@ -8,6 +8,7 @@ import scala.reflect.internal.util.Position
/** Trait encapsulating the creation of a presentation compiler's instance.*/
private[tests] trait PresentationCompilerInstance extends TestSettings {
protected val settings = new Settings
+ protected def docSettings: doc.Settings = new doc.Settings(_ => ())
protected val compilerReporter: CompilerReporter = new InteractiveReporter {
override def compiler = PresentationCompilerInstance.this.compiler
}
@@ -28,4 +29,4 @@ private[tests] trait PresentationCompilerInstance extends TestSettings {
reporter.println("\tbootClassPath: %s".format(settings.bootclasspath.value))
reporter.println("\tverbose: %b".format(settings.verbose.value))
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
index 12fb8f1507..67519cf90c 100644
--- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -120,7 +120,7 @@ trait MemberHandlers {
if (replProps.vids) """" + " @ " + "%%8x".format(System.identityHashCode(%s)) + " """.trim.format(req fullPath name)
else ""
- """ + "%s%s: %s = " + %s""".format(prettyName, vidString, string2code(req typeOf name), resultString)
+ """ + "%s%s: %s = " + %s""".format(string2code(prettyName), vidString, string2code(req typeOf name), resultString)
}
}
}
@@ -147,8 +147,7 @@ trait MemberHandlers {
override def resultExtractionCode(req: Request) = {
val lhsType = string2code(req lookupTypeOf name)
val res = string2code(req fullPath name)
-
- """ + "%s: %s = " + %s + "\n" """.format(lhs, lhsType, res) + "\n"
+ """ + "%s: %s = " + %s + "\n" """.format(string2code(lhs.toString), lhsType, res) + "\n"
}
}
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 43a8402fc7..050f7a8f95 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -551,7 +551,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
if (parentToken == AT && in.token == DEFAULT) {
val annot =
atPos(pos) {
- New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), ListOfNil)
+ New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), Nil)
}
mods1 = mods1 withAnnotations List(annot)
skipTo(SEMI)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index b9eb1ba0cd..25b7813646 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -198,7 +198,7 @@ abstract class Pickler extends SubComponent {
case RefinedType(parents, decls) =>
val rclazz = tp.typeSymbol
for (m <- decls.iterator)
- if (m.owner != rclazz) assert(false, "bad refinement member "+m+" of "+tp+", owner = "+m.owner)
+ if (m.owner != rclazz) abort("bad refinement member "+m+" of "+tp+", owner = "+m.owner)
putSymbol(rclazz); putTypes(parents); putSymbols(decls.toList)
case ClassInfoType(parents, decls, clazz) =>
putSymbol(clazz); putTypes(parents); putSymbols(decls.toList)
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 4092d1262a..ec0797acb5 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -68,7 +68,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
def matchesName(param: Symbol) = param.name == name || param.name.startsWith(name + nme.NAME_JOIN_STRING)
(constrParams filter matchesName) match {
- case Nil => assert(false, name + " not in " + constrParams) ; null
+ case Nil => abort(name + " not in " + constrParams)
case p :: _ => p
}
}
@@ -511,7 +511,6 @@ abstract class Constructors extends Transform with ast.TreeDSL {
sym = closureClass,
constrMods = Modifiers(0),
vparamss = List(List(outerFieldDef)),
- argss = ListOfNil,
body = List(applyMethodDef),
superPos = impl.pos)
}
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 64bb98e2c5..57bdaea17a 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -269,7 +269,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** Mix in members of implementation class mixinClass into class clazz */
def mixinImplClassMembers(mixinClass: Symbol, mixinInterface: Symbol) {
- assert(mixinClass.isImplClass, "Not an impl class:" +
+ if (!mixinClass.isImplClass) debugwarn ("Impl class flag is not set " +
((mixinClass.debugLocationString, mixinInterface.debugLocationString)))
for (member <- mixinClass.info.decls ; if isForwarded(member)) {
@@ -360,7 +360,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// first complete the superclass with mixed in members
addMixedinMembers(clazz.superClass, unit)
- //Console.println("adding members of " + clazz.info.baseClasses.tail.takeWhile(superclazz !=) + " to " + clazz);//DEBUG
for (mc <- clazz.mixinClasses ; if mc hasFlag lateINTERFACE) {
// @SEAN: adding trait tracking so we don't have to recompile transitive closures
unit.depends += mc
@@ -871,8 +870,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
val cond = Apply(Select(moduleVarRef, nme.eq), List(NULL))
mkFastPathBody(clazz, moduleSym, cond, List(assign), List(NULL), returnTree, attrThis, args)
case _ =>
- assert(false, "Invalid getter " + rhs + " for module in class " + clazz)
- EmptyTree
+ abort("Invalid getter " + rhs + " for module in class " + clazz)
}
def mkCheckedAccessor(clazz: Symbol, retVal: Tree, offset: Int, pos: Position, fieldSym: Symbol): Tree = {
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 2f79472cfb..bbab545d9e 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -965,6 +965,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case (NoSymbol, _) => None
case (overridden, env) =>
val om = specializedOverload(clazz, overridden, env)
+ foreachWithIndex(om.paramss) { (params, i) =>
+ foreachWithIndex(params) { (param, j) =>
+ param.name = overriding.paramss(i)(j).name // SI-6555 Retain the parameter names from the subclass.
+ }
+ }
debuglog("specialized overload %s for %s in %s: %s".format(om, overriding.name.decode, pp(env), om.info))
typeEnv(om) = env
addConcreteSpecMethod(overriding)
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 95cb052fda..a767850cba 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -327,8 +327,16 @@ abstract class TailCalls extends Transform {
transformTrees(cases).asInstanceOf[List[CaseDef]]
)
+ case Try(block, catches, finalizer @ EmptyTree) =>
+ // SI-1672 Catches are in tail position when there is no finalizer
+ treeCopy.Try(tree,
+ noTailTransform(block),
+ transformTrees(catches).asInstanceOf[List[CaseDef]],
+ EmptyTree
+ )
+
case Try(block, catches, finalizer) =>
- // no calls inside a try are in tail position, but keep recursing for nested functions
+ // no calls inside a try are in tail position if there is a finalizer, but keep recursing for nested functions
treeCopy.Try(tree,
noTailTransform(block),
noTailTransforms(catches).asInstanceOf[List[CaseDef]],
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 529009a058..838ea7d5a0 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -251,7 +251,10 @@ abstract class UnCurry extends InfoTransform
val applyMethodDef = {
val methSym = anonClass.newMethod(nme.apply, fun.pos, FINAL)
- methSym setInfoAndEnter MethodType(methSym newSyntheticValueParams formals, restpe)
+ val paramSyms = map2(formals, fun.vparams) {
+ (tp, param) => methSym.newSyntheticValueParam(tp, param.name)
+ }
+ methSym setInfoAndEnter MethodType(paramSyms, restpe)
fun.vparams foreach (_.symbol.owner = methSym)
fun.body changeOwner (fun.symbol -> methSym)
@@ -267,7 +270,7 @@ abstract class UnCurry extends InfoTransform
localTyper.typedPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyMethodDef), fun.pos)),
+ List(ClassDef(anonClass, NoMods, ListOfNil, List(applyMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
@@ -392,7 +395,7 @@ abstract class UnCurry extends InfoTransform
localTyper.typedPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
+ List(ClassDef(anonClass, NoMods, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index faacb60d75..ae3b0bc0b7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -184,14 +184,18 @@ trait ContextErrors {
}
def ParentTypesError(templ: Template, ex: TypeError) = {
- templ.tpe = null
- issueNormalTypeError(templ, ex.getMessage())
+ templ.tpe = null
+ issueNormalTypeError(templ, ex.getMessage())
+ setError(templ)
}
// additional parentTypes errors
- def ConstrArgsInTraitParentTpeError(arg: Tree, parent: Symbol) =
+ def ConstrArgsInParentWhichIsTraitError(arg: Tree, parent: Symbol) =
issueNormalTypeError(arg, parent + " is a trait; does not take constructor arguments")
+ def ConstrArgsInParentOfTraitError(arg: Tree, parent: Symbol) =
+ issueNormalTypeError(arg, "parents of traits may not have parameters")
+
def MissingTypeArgumentsParentTpeError(supertpt: Tree) =
issueNormalTypeError(supertpt, "missing type arguments")
@@ -1043,9 +1047,6 @@ trait ContextErrors {
def MaxParametersCaseClassError(tree: Tree) =
issueNormalTypeError(tree, "Implementation restriction: case classes cannot have more than " + definitions.MaxFunctionArity + " parameters.")
- def InheritsItselfError(tree: Tree) =
- issueNormalTypeError(tree, tree.tpe.typeSymbol+" inherits itself")
-
def MissingParameterOrValTypeError(vparam: Tree) =
issueNormalTypeError(vparam, "missing parameter type")
@@ -1279,7 +1280,10 @@ trait ContextErrors {
fail()
}
- private def implRefError(message: String) = genericError(methPart(macroDdef.rhs), message)
+ private def implRefError(message: String) = {
+ val treeInfo.Applied(implRef, _, _) = macroDdef.rhs
+ genericError(implRef, message)
+ }
private def compatibilityError(message: String) =
implRefError(
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 507825ff15..0907f1088a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -510,8 +510,8 @@ trait Contexts { self: Analyzer =>
/*
var c = this
while (c != NoContext && c.owner != owner) {
- if (c.outer eq null) assert(false, "accessWithin(" + owner + ") " + c);//debug
- if (c.outer.enclClass eq null) assert(false, "accessWithin(" + owner + ") " + c);//debug
+ if (c.outer eq null) abort("accessWithin(" + owner + ") " + c);//debug
+ if (c.outer.enclClass eq null) abort("accessWithin(" + owner + ") " + c);//debug
c = c.outer.enclClass
}
c != NoContext
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index fc10f68454..ad01de9447 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -149,9 +149,20 @@ trait Implicits {
class SearchResult(val tree: Tree, val subst: TreeTypeSubstituter) {
override def toString = "SearchResult(%s, %s)".format(tree,
if (subst.isEmpty) "" else subst)
+
+ def isFailure = false
+ def isAmbiguousFailure = false
+ final def isSuccess = !isFailure
}
- lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter)
+ lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ override def isFailure = true
+ }
+
+ lazy val AmbiguousSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ override def isFailure = true
+ override def isAmbiguousFailure = true
+ }
/** A class that records an available implicit
* @param name The name of the implicit
@@ -831,7 +842,7 @@ trait Implicits {
catch divergenceHandler
tryImplicitInfo(i) match {
- case SearchFailure =>
+ case sr if sr.isFailure =>
// We don't want errors that occur during checking implicit info
// to influence the check of further infos.
context.condBufferFlush(_.kind != ErrorKinds.Divergent)
@@ -871,14 +882,14 @@ trait Implicits {
rest find (alt => !improves(chosen, alt)) match {
case Some(competing) =>
AmbiguousImplicitError(chosen, competing, "both", "and", "")(isView, pt, tree)(context)
- return SearchFailure // Stop the search once ambiguity is encountered, see t4457_2.scala
+ return AmbiguousSearchFailure // Stop the search once ambiguity is encountered, see t4457_2.scala
case _ =>
if (isView) chosen.useCountView += 1
else chosen.useCountArg += 1
}
}
- if (best == SearchFailure) {
+ if (best.isFailure) {
/** If there is no winner, and we witnessed and caught divergence,
* now we can throw it for the error message.
*/
@@ -1377,24 +1388,25 @@ trait Implicits {
var result = searchImplicit(context.implicitss, true)
- if (result == SearchFailure) {
+ if (result.isFailure) {
if (Statistics.canEnable) Statistics.stopTimer(inscopeFailNanos, failstart)
} else {
if (Statistics.canEnable) Statistics.stopTimer(inscopeSucceedNanos, succstart)
if (Statistics.canEnable) Statistics.incCounter(inscopeImplicitHits)
}
- if (result == SearchFailure) {
+ if (result.isFailure) {
val previousErrs = context.flushAndReturnBuffer()
val failstart = if (Statistics.canEnable) Statistics.startTimer(oftypeFailNanos) else null
val succstart = if (Statistics.canEnable) Statistics.startTimer(oftypeSucceedNanos) else null
+ val wasAmbigious = result.isAmbiguousFailure // SI-6667, never search companions after an ambiguous error in in-scope implicits
result = materializeImplicit(pt)
// `materializeImplicit` does some preprocessing for `pt`
// is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`?
- if (result == SearchFailure) result = searchImplicit(implicitsOfExpectedType, false)
+ if (result.isFailure && !wasAmbigious) result = searchImplicit(implicitsOfExpectedType, false)
- if (result == SearchFailure) {
+ if (result.isFailure) {
context.updateBuffer(previousErrs)
if (Statistics.canEnable) Statistics.stopTimer(oftypeFailNanos, failstart)
} else {
@@ -1403,7 +1415,7 @@ trait Implicits {
}
}
- if (result == SearchFailure && settings.debug.value)
+ if (result.isFailure && settings.debug.value)
log("no implicits found for "+pt+" "+pt.typeSymbol.info.baseClasses+" "+implicitsOfExpectedType)
result
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 5deed4ffee..7ae8923e43 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -221,7 +221,7 @@ trait Infer extends Checkable {
// such as T <: T gets completed. See #360
tvar.constr.inst = ErrorType
else
- assert(false, tvar.origin+" at "+tvar.origin.typeSymbol.owner)
+ abort(tvar.origin+" at "+tvar.origin.typeSymbol.owner)
}
tvars map instantiate
}
@@ -1003,22 +1003,22 @@ trait Infer extends Checkable {
*/
/** error if arguments not within bounds. */
def checkBounds(tree: Tree, pre: Type, owner: Symbol,
- tparams: List[Symbol], targs: List[Type], prefix: String): Boolean = {
- //@M validate variances & bounds of targs wrt variances & bounds of tparams
- //@M TODO: better place to check this?
- //@M TODO: errors for getters & setters are reported separately
- val kindErrors = checkKindBounds(tparams, targs, pre, owner)
-
- if(!kindErrors.isEmpty) {
- if (targs contains WildcardType) true
- else { KindBoundErrors(tree, prefix, targs, tparams, kindErrors); false }
- } else if (!isWithinBounds(pre, owner, tparams, targs)) {
- if (!(targs exists (_.isErroneous)) && !(tparams exists (_.isErroneous))) {
- NotWithinBounds(tree, prefix, targs, tparams, kindErrors)
- false
- } else true
- } else true
- }
+ tparams: List[Symbol], targs: List[Type], prefix: String): Boolean =
+ if ((targs exists (_.isErroneous)) || (tparams exists (_.isErroneous))) true
+ else {
+ //@M validate variances & bounds of targs wrt variances & bounds of tparams
+ //@M TODO: better place to check this?
+ //@M TODO: errors for getters & setters are reported separately
+ val kindErrors = checkKindBounds(tparams, targs, pre, owner)
+ kindErrors match {
+ case Nil =>
+ def notWithinBounds() = NotWithinBounds(tree, prefix, targs, tparams, Nil)
+ isWithinBounds(pre, owner, tparams, targs) || {notWithinBounds(); false}
+ case errors =>
+ def kindBoundErrors() = KindBoundErrors(tree, prefix, targs, tparams, errors)
+ (targs contains WildcardType) || {kindBoundErrors(); false}
+ }
+ }
def checkKindBounds(tparams: List[Symbol], targs: List[Type], pre: Type, owner: Symbol): List[String] = {
checkKindBounds0(tparams, targs, pre, owner, true) map {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 36edd46f25..3f546c9a51 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -847,13 +847,8 @@ trait Namers extends MethodSynthesis {
private def templateSig(templ: Template): Type = {
val clazz = context.owner
def checkParent(tpt: Tree): Type = {
- val tp = tpt.tpe
- val inheritsSelf = tp.typeSymbol == owner
- if (inheritsSelf)
- InheritsItselfError(tpt)
-
- if (inheritsSelf || tp.isError) AnyRefClass.tpe
- else tp
+ if (tpt.tpe.isError) AnyRefClass.tpe
+ else tpt.tpe
}
val parents = typer.parentTypes(templ) map checkParent
@@ -1260,7 +1255,11 @@ trait Namers extends MethodSynthesis {
case defn: MemberDef =>
val ainfos = defn.mods.annotations filterNot (_ eq null) map { ann =>
// need to be lazy, #1782. beforeTyper to allow inferView in annotation args, SI-5892.
- AnnotationInfo lazily beforeTyper(typer typedAnnotation ann)
+ AnnotationInfo lazily {
+ val context1 = typer.context.make(ann)
+ context1.setReportErrors()
+ beforeTyper(newTyper(context1) typedAnnotation ann)
+ }
}
if (ainfos.nonEmpty) {
annotated setAnnotations ainfos
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 834c64aaae..fa8aff5cdd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -801,8 +801,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
protected def spliceApply(binder: Symbol): Tree = {
object splice extends Transformer {
override def transform(t: Tree) = t match {
- case Apply(x, List(Ident(nme.SELECTOR_DUMMY))) =>
- treeCopy.Apply(t, x, List(CODE.REF(binder)))
+ case Apply(x, List(i @ Ident(nme.SELECTOR_DUMMY))) =>
+ treeCopy.Apply(t, x, List(CODE.REF(binder).setPos(i.pos)))
case _ => super.transform(t)
}
}
@@ -879,7 +879,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
override def transform(tree: Tree): Tree = {
def subst(from: List[Symbol], to: List[Tree]): Tree =
if (from.isEmpty) tree
- else if (tree.symbol == from.head) typedIfOrigTyped(to.head.shallowDuplicate, tree.tpe)
+ else if (tree.symbol == from.head) typedIfOrigTyped(to.head.shallowDuplicate.setPos(tree.pos), tree.tpe)
else subst(from.tail, to.tail)
tree match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 15ac3d134f..9bd3aa8fe5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1264,13 +1264,15 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
val cdef = ClassDef(mods | MODULE, name.toTypeName, Nil, impl) setSymbol classSym setType NoType
def findOrCreateModuleVar() = localTyper.typedPos(tree.pos) {
- lazy val createModuleVar = gen.mkModuleVarDef(sym)
- sym.enclClass.info.decl(nme.moduleVarName(sym.name.toTermName)) match {
- // In case we are dealing with local symbol then we already have
- // to correct error with forward reference
- case NoSymbol => createModuleVar
- case vsym => ValDef(vsym)
- }
+ // See SI-5012, SI-6712.
+ val vsym = (
+ if (sym.owner.isTerm) NoSymbol
+ else sym.enclClass.info.decl(nme.moduleVarName(sym.name.toTermName))
+ )
+ // In case we are dealing with local symbol then we already have
+ // to correct error with forward reference
+ if (vsym == NoSymbol) gen.mkModuleVarDef(sym)
+ else ValDef(vsym)
}
def createStaticModuleAccessor() = afterRefchecks {
val method = (
@@ -1677,7 +1679,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
checkAnyValSubclass(currentOwner)
if (bridges.nonEmpty) deriveTemplate(tree)(_ ::: bridges) else tree
- case dc@TypeTreeWithDeferredRefCheck() => assert(false, "adapt should have turned dc: TypeTreeWithDeferredRefCheck into tpt: TypeTree, with tpt.original == dc"); dc
+ case dc@TypeTreeWithDeferredRefCheck() => abort("adapt should have turned dc: TypeTreeWithDeferredRefCheck into tpt: TypeTree, with tpt.original == dc")
case tpt@TypeTree() =>
if(tpt.original != null) {
tpt.original foreach {
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index 64c5b41638..20db479463 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -4,7 +4,31 @@ package typechecker
trait StdAttachments {
self: Analyzer =>
+ import global._
+
+ /** Carries information necessary to expand the host tree.
+ * At times we need to store this info, because macro expansion can be delayed until its targs are inferred.
+ * After a macro application has been successfully expanded, this attachment is destroyed.
+ */
type UnaffiliatedMacroContext = scala.reflect.macros.runtime.Context
type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type }
case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext])
+
+ /** After being synthesized by the parser, primary constructors aren't fully baked yet.
+ * A call to super in such constructors is just a fill-me-in-later dummy resolved later
+ * by `parentTypes`. This attachment coordinates `parentTypes` and `typedTemplate` and
+ * allows them to complete the synthesis.
+ */
+ case class SuperArgsAttachment(argss: List[List[Tree]])
+
+ /** Convenience method for `SuperArgsAttachment`.
+ * Compared with `MacroRuntimeAttachment` this attachment has different a usage pattern,
+ * so it really benefits from a dedicated extractor.
+ */
+ def superArgs(tree: Tree): Option[List[List[Tree]]] =
+ tree.attachments.get[SuperArgsAttachment] collect { case SuperArgsAttachment(argss) => argss }
+
+ /** Determines whether the given tree has an associated SuperArgsAttachment.
+ */
+ def hasSuperArgs(tree: Tree): Boolean = superArgs(tree).nonEmpty
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 5714c2c109..f8adcaa25b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -48,12 +48,15 @@ trait Typers extends Modes with Adaptations with Tags {
resetContexts()
resetImplicits()
transformed.clear()
+ clearDocComments()
}
object UnTyper extends Traverser {
override def traverse(tree: Tree) = {
- if (tree != EmptyTree) tree.tpe = null
- if (tree.hasSymbol) tree.symbol = NoSymbol
+ if (tree.canHaveAttrs) {
+ tree.tpe = null
+ if (tree.hasSymbol) tree.symbol = NoSymbol
+ }
super.traverse(tree)
}
}
@@ -132,7 +135,7 @@ trait Typers extends Modes with Adaptations with Tags {
val res = if (paramFailed || (paramTp.isError && {paramFailed = true; true})) SearchFailure else inferImplicit(fun, paramTp, context.reportErrors, false, context)
argResultsBuff += res
- if (res != SearchFailure) {
+ if (res.isSuccess) {
argBuff += mkArg(res.tree, param.name)
} else {
mkArg = mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args
@@ -761,7 +764,7 @@ trait Typers extends Modes with Adaptations with Tags {
featureTrait.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse
val featureName = (nestedOwners map (_.name + ".")).mkString + featureTrait.name
def action(): Boolean = {
- def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context) != SearchFailure
+ def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context).isSuccess
def hasOption = settings.language.value exists (s => s == featureName || s == "_")
val OK = hasImport || hasOption
if (!OK) {
@@ -1378,13 +1381,6 @@ trait Typers extends Modes with Adaptations with Tags {
if (member(qual, name) != NoSymbol) qual
else adaptToMember(qual, HasMember(name))
- private def typePrimaryConstrBody(clazz : Symbol, cbody: Tree, tparams: List[Symbol], enclTparams: List[Symbol], vparamss: List[List[ValDef]]): Tree = {
- // XXX: see about using the class's symbol....
- enclTparams foreach (sym => context.scope.enter(sym))
- namer.enterValueParams(vparamss)
- typed(cbody)
- }
-
private def validateNoCaseAncestor(clazz: Symbol) = {
if (!phase.erasedTypes) {
for (ancestor <- clazz.ancestors find (_.isCase)) {
@@ -1486,125 +1482,243 @@ trait Typers extends Modes with Adaptations with Tags {
unit.error(tparam.pos, "type parameter of value class may not be specialized")
}
- def parentTypes(templ: Template): List[Tree] =
- if (templ.parents.isEmpty) List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe)))
- else try {
- val clazz = context.owner
- // Normalize supertype and mixins so that supertype is always a class, not a trait.
- var supertpt = typedTypeConstructor(templ.parents.head)
- val firstParent = supertpt.tpe.typeSymbol
- var mixins = templ.parents.tail map typedType
- // If first parent is a trait, make it first mixin and add its superclass as first parent
- while ((supertpt.tpe.typeSymbol ne null) && supertpt.tpe.typeSymbol.initialize.isTrait) {
- val supertpt1 = typedType(supertpt)
- if (!supertpt1.isErrorTyped) {
- mixins = supertpt1 :: mixins
- supertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus
+ /** Typechecks a parent type reference.
+ *
+ * This typecheck is harder than it might look, because it should honor early
+ * definitions and also perform type argument inference with the help of super call
+ * arguments provided in `encodedtpt`.
+ *
+ * The method is called in batches (batch = 1 time per each parent type referenced),
+ * two batches per definition: once from namer, when entering a ClassDef or a ModuleDef
+ * and once from typer, when typechecking the definition.
+ *
+ * ***Arguments***
+ *
+ * `encodedtpt` represents the parent type reference wrapped in an `Apply` node
+ * which indicates value arguments (i.e. type macro arguments or super constructor call arguments)
+ * If no value arguments are provided by the user, the `Apply` node is still
+ * there, but its `args` will be set to `Nil`.
+ * This argument is synthesized by `tools.nsc.ast.Parsers.templateParents`.
+ *
+ * `templ` is an enclosing template, which contains a primary constructor synthesized by the parser.
+ * Such a constructor is a DefDef which contains early initializers and maybe a super constructor call
+ * (I wrote "maybe" because trait constructors don't call super constructors).
+ * This argument is synthesized by `tools.nsc.ast.Trees.Template`.
+ *
+ * `inMixinPosition` indicates whether the reference is not the first in the
+ * list of parents (and therefore cannot be a class) or the opposite.
+ *
+ * ***Return value and side effects***
+ *
+ * Returns a `TypeTree` representing a resolved parent type.
+ * If the typechecked parent reference implies non-nullary and non-empty argument list,
+ * this argument list is attached to the returned value in SuperArgsAttachment.
+ * The attachment is necessary for the subsequent typecheck to fixup a super constructor call
+ * in the body of the primary constructor (see `typedTemplate` for details).
+ *
+ * This method might invoke `typedPrimaryConstrBody`, hence it might cause the side effects
+ * described in the docs of that method. It might also attribute the Super(_, _) reference
+ * (if present) inside the primary constructor of `templ`.
+ *
+ * ***Example***
+ *
+ * For the following definition:
+ *
+ * class D extends {
+ * val x = 2
+ * val y = 4
+ * } with B(x)(3) with C(y) with T
+ *
+ * this method will be called six times:
+ *
+ * (3 times from the namer)
+ * typedParentType(Apply(Apply(Ident(B), List(Ident(x))), List(3)), templ, inMixinPosition = false)
+ * typedParentType(Apply(Ident(C), List(Ident(y))), templ, inMixinPosition = true)
+ * typedParentType(Apply(Ident(T), List()), templ, inMixinPosition = true)
+ *
+ * (3 times from the typer)
+ * <the same three calls>
+ */
+ private def typedParentType(encodedtpt: Tree, templ: Template, inMixinPosition: Boolean): Tree = {
+ val app = treeInfo.dissectApplied(encodedtpt)
+ val (treeInfo.Applied(core, targs, argss), decodedtpt) = (app, app.callee)
+ val argssAreTrivial = argss == Nil || argss == ListOfNil
+
+ // we cannot avoid cyclic references with `initialize` here, because when type macros arrive,
+ // we'll have to check the probe for isTypeMacro anyways.
+ // therefore I think it's reasonable to trade a more specific "inherits itself" error
+ // for a generic, yet understandable "cyclic reference" error
+ var probe = typedTypeConstructor(core.duplicate).tpe.typeSymbol
+ if (probe == null) probe = NoSymbol
+ probe.initialize
+
+ if (probe.isTrait || inMixinPosition) {
+ if (!argssAreTrivial) {
+ if (probe.isTrait) ConstrArgsInParentWhichIsTraitError(encodedtpt, probe)
+ else () // a class in a mixin position - this warrants an error in `validateParentClasses`
+ // therefore here we do nothing, e.g. don't check that the # of ctor arguments
+ // matches the # of ctor parameters or stuff like that
+ }
+ typedType(decodedtpt)
+ } else {
+ var supertpt = typedTypeConstructor(decodedtpt)
+ val supertparams = if (supertpt.hasSymbol) supertpt.symbol.typeParams else Nil
+ if (supertparams.nonEmpty) {
+ typedPrimaryConstrBody(templ) {
+ val supertpe = PolyType(supertparams, appliedType(supertpt.tpe, supertparams map (_.tpeHK)))
+ val supercall = New(supertpe, mmap(argss)(_.duplicate))
+ val treeInfo.Applied(Select(ctor, nme.CONSTRUCTOR), _, _) = supercall
+ ctor setType supertpe // this is an essential hack, otherwise it will occasionally fail to typecheck
+ atPos(supertpt.pos.focus)(supercall)
+ } match {
+ case EmptyTree => MissingTypeArgumentsParentTpeError(supertpt)
+ case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos.focus
}
}
- if (supertpt.tpe.typeSymbol == AnyClass && firstParent.isTrait)
- supertpt.tpe = AnyRefClass.tpe
-
- // Determine
- // - supertparams: Missing type parameters from supertype
- // - supertpe: Given supertype, polymorphic in supertparams
- val supertparams = if (supertpt.hasSymbol) supertpt.symbol.typeParams else List()
- var supertpe = supertpt.tpe
- if (!supertparams.isEmpty)
- supertpe = PolyType(supertparams, appliedType(supertpe, supertparams map (_.tpeHK)))
-
- // A method to replace a super reference by a New in a supercall
- def transformSuperCall(scall: Tree): Tree = (scall: @unchecked) match {
- case Apply(fn, args) =>
- treeCopy.Apply(scall, transformSuperCall(fn), args map (_.duplicate))
- case Select(Super(_, _), nme.CONSTRUCTOR) =>
- treeCopy.Select(
- scall,
- atPos(supertpt.pos.focus)(New(TypeTree(supertpe)) setType supertpe),
- nme.CONSTRUCTOR)
- }
-
- treeInfo.firstConstructor(templ.body) match {
- case constr @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) =>
- // Convert constructor body to block in environment and typecheck it
- val (preSuperStats, superCall) = {
- val (stats, rest) = cstats span (x => !treeInfo.isSuperConstrCall(x))
- (stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate)
- }
- val cstats1 = if (superCall == EmptyTree) preSuperStats else preSuperStats :+ superCall
- val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall match {
- case Apply(_, _) if supertparams.nonEmpty => transformSuperCall(superCall)
- case _ => cunit.duplicate
- })
- val outercontext = context.outer
-
- assert(clazz != NoSymbol, templ)
- val cscope = outercontext.makeNewScope(constr, outercontext.owner)
- val cbody2 = newTyper(cscope) // called both during completion AND typing.
- .typePrimaryConstrBody(clazz,
- cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (_.map(_.duplicate)))
-
- superCall match {
- case Apply(_, _) =>
- val sarg = treeInfo.firstArgument(superCall)
- if (sarg != EmptyTree && supertpe.typeSymbol != firstParent)
- ConstrArgsInTraitParentTpeError(sarg, firstParent)
- if (!supertparams.isEmpty)
- supertpt = TypeTree(cbody2.tpe) setPos supertpt.pos.focus
- case _ =>
- if (!supertparams.isEmpty)
- MissingTypeArgumentsParentTpeError(supertpt)
- }
+ // this is the place where we tell the typer what argss should be used for the super call
+ // if argss are nullary or empty, then (see the docs for `typedPrimaryConstrBody`)
+ // the super call dummy is already good enough, so we don't need to do anything
+ if (argssAreTrivial) supertpt else supertpt updateAttachment SuperArgsAttachment(argss)
+ }
+ }
- val preSuperVals = treeInfo.preSuperFields(templ.body)
- if (preSuperVals.isEmpty && preSuperStats.nonEmpty)
- debugwarn("Wanted to zip empty presuper val list with " + preSuperStats)
- else
- map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt.tpe = ldef.symbol.tpe)
+ /** Typechecks the mishmash of trees that happen to be stuffed into the primary constructor of a given template.
+ * Before commencing the typecheck, replaces the `pendingSuperCall` dummy with the result of `actualSuperCall`.
+ * `actualSuperCall` can return `EmptyTree`, in which case the dummy is replaced with a literal unit.
+ *
+ * ***Return value and side effects***
+ *
+ * If a super call is present in the primary constructor and is not erased by the transform, returns it typechecked.
+ * Otherwise (e.g. if the primary constructor is missing or the super call isn't there) returns `EmptyTree`.
+ *
+ * As a side effect, this method attributes the underlying fields of early vals.
+ * Early vals aren't typechecked anywhere else, so it's essential to call `typedPrimaryConstrBody`
+ * at least once per definition. It'd be great to disentangle this logic at some point.
+ *
+ * ***Example***
+ *
+ * For the following definition:
+ *
+ * class D extends {
+ * val x = 2
+ * val y = 4
+ * } with B(x)(3) with C(y) with T
+ *
+ * the primary constructor of `templ` will be:
+ *
+ * Block(List(
+ * ValDef(NoMods, x, TypeTree(), 2)
+ * ValDef(NoMods, y, TypeTree(), 4)
+ * global.pendingSuperCall,
+ * Literal(Constant(())))
+ *
+ * Note the `pendingSuperCall` part. This is the representation of a fill-me-in-later supercall dummy,
+ * which encodes the fact that supercall argss are unknown during parsing and need to be transplanted
+ * from one of the parent types. Read more about why the argss are unknown in `tools.nsc.ast.Trees.Template`.
+ */
+ private def typedPrimaryConstrBody(templ: Template)(actualSuperCall: => Tree): Tree =
+ treeInfo.firstConstructor(templ.body) match {
+ case ctor @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) =>
+ val (preSuperStats, superCall) = {
+ val (stats, rest) = cstats span (x => !treeInfo.isSuperConstrCall(x))
+ (stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate)
+ }
+ val superCall1 = (superCall match {
+ case global.pendingSuperCall => actualSuperCall
+ case EmptyTree => EmptyTree
+ }) orElse cunit
+ val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall1)
+
+ val clazz = context.owner
+ assert(clazz != NoSymbol, templ)
+ val cscope = context.outer.makeNewScope(ctor, context.outer.owner)
+ val cbody2 = { // called both during completion AND typing.
+ val typer1 = newTyper(cscope)
+ // XXX: see about using the class's symbol....
+ clazz.unsafeTypeParams foreach (sym => typer1.context.scope.enter(sym))
+ typer1.namer.enterValueParams(vparamss map (_.map(_.duplicate)))
+ typer1.typed(cbody1)
+ }
- case _ =>
- if (!supertparams.isEmpty)
- MissingTypeArgumentsParentTpeError(supertpt)
- }
-/* experimental: early types as type arguments
- val hasEarlyTypes = templ.body exists (treeInfo.isEarlyTypeDef)
- val earlyMap = new EarlyMap(clazz)
- List.mapConserve(supertpt :: mixins){ tpt =>
- val tpt1 = checkNoEscaping.privates(clazz, tpt)
- if (hasEarlyTypes) tpt1 else tpt1 setType earlyMap(tpt1.tpe)
- }
-*/
+ val preSuperVals = treeInfo.preSuperFields(templ.body)
+ if (preSuperVals.isEmpty && preSuperStats.nonEmpty)
+ debugwarn("Wanted to zip empty presuper val list with " + preSuperStats)
+ else
+ map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt.tpe = ldef.symbol.tpe)
- //Console.println("parents("+clazz") = "+supertpt :: mixins);//DEBUG
+ if (superCall1 == cunit) EmptyTree else cbody2
+ case _ =>
+ EmptyTree
+ }
- // Certain parents are added in the parser before it is known whether
- // that class also declared them as parents. For instance, this is an
- // error unless we take corrective action here:
- //
- // case class Foo() extends Serializable
- //
- // So we strip the duplicates before typer.
- def fixDuplicates(remaining: List[Tree]): List[Tree] = remaining match {
- case Nil => Nil
- case x :: xs =>
- val sym = x.symbol
- x :: fixDuplicates(
- if (isPossibleSyntheticParent(sym)) xs filterNot (_.symbol == sym)
- else xs
- )
+ /** Makes sure that the first type tree in the list of parent types is always a class.
+ * If the first parent is a trait, prepend its supertype to the list until it's a class.
+ */
+ private def normalizeFirstParent(parents: List[Tree]): List[Tree] = parents match {
+ case first :: rest if treeInfo.isTraitRef(first) =>
+ def explode(supertpt: Tree, acc: List[Tree]): List[Tree] = {
+ if (treeInfo.isTraitRef(supertpt)) {
+ val supertpt1 = typedType(supertpt)
+ if (!supertpt1.isErrorTyped) {
+ val supersupertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus
+ return explode(supersupertpt, supertpt1 :: acc)
+ }
+ }
+ if (supertpt.tpe.typeSymbol == AnyClass) supertpt.tpe = AnyRefClass.tpe
+ supertpt :: acc
}
+ explode(first, Nil) ++ rest
+ case _ => parents
+ }
- fixDuplicates(supertpt :: mixins) mapConserve (tpt => checkNoEscaping.privates(clazz, tpt))
- }
- catch {
- case ex: TypeError =>
- // fallback in case of cyclic errors
- // @H none of the tests enter here but I couldn't rule it out
- log("Type error calculating parents in template " + templ)
- log("Error: " + ex)
- ParentTypesError(templ, ex)
- List(TypeTree(AnyRefClass.tpe))
- }
+ /** Certain parents are added in the parser before it is known whether
+ * that class also declared them as parents. For instance, this is an
+ * error unless we take corrective action here:
+ *
+ * case class Foo() extends Serializable
+ *
+ * So we strip the duplicates before typer.
+ */
+ private def fixDuplicateSyntheticParents(parents: List[Tree]): List[Tree] = parents match {
+ case Nil => Nil
+ case x :: xs =>
+ val sym = x.symbol
+ x :: fixDuplicateSyntheticParents(
+ if (isPossibleSyntheticParent(sym)) xs filterNot (_.symbol == sym)
+ else xs
+ )
+ }
+
+ def parentTypes(templ: Template): List[Tree] = templ.parents match {
+ case Nil => List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe)))
+ case first :: rest =>
+ try {
+ val supertpts = fixDuplicateSyntheticParents(normalizeFirstParent(
+ typedParentType(first, templ, inMixinPosition = false) +:
+ (rest map (typedParentType(_, templ, inMixinPosition = true)))))
+
+ // if that is required to infer the targs of a super call
+ // typedParentType calls typedPrimaryConstrBody to do the inferring typecheck
+ // as a side effect, that typecheck also assigns types to the fields underlying early vals
+ // however if inference is not required, the typecheck doesn't happen
+ // and therefore early fields have their type trees not assigned
+ // here we detect this situation and take preventive measures
+ if (treeInfo.hasUntypedPreSuperFields(templ.body))
+ typedPrimaryConstrBody(templ)(EmptyTree)
+
+ supertpts mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt))
+ } catch {
+ case ex: TypeError =>
+ // fallback in case of cyclic errors
+ // @H none of the tests enter here but I couldn't rule it out
+ // upd. @E when a definitions inherits itself, we end up here
+ // because `typedParentType` triggers `initialize` for parent types symbols
+ log("Type error calculating parents in template " + templ)
+ log("Error: " + ex)
+ ParentTypesError(templ, ex)
+ List(TypeTree(AnyRefClass.tpe))
+ }
+ }
/** <p>Check that</p>
* <ul>
@@ -1816,8 +1930,7 @@ trait Typers extends Modes with Adaptations with Tags {
*/
def typedTemplate(templ: Template, parents1: List[Tree]): Template = {
val clazz = context.owner
- // complete lazy annotations
- val annots = clazz.annotations
+ clazz.annotations.map(_.completeInfo)
if (templ.symbol == NoSymbol)
templ setSymbol clazz.newLocalDummy(templ.pos)
val self1 = templ.self match {
@@ -1844,9 +1957,12 @@ trait Typers extends Modes with Adaptations with Tags {
// the following is necessary for templates generated later
assert(clazz.info.decls != EmptyScope, clazz)
enterSyms(context.outer.make(templ, clazz, clazz.info.decls), templ.body)
- validateParentClasses(parents1, selfType)
+ if (!templ.isErrorTyped) // if `parentTypes` has invalidated the template, don't validate it anymore
+ validateParentClasses(parents1, selfType)
if (clazz.isCase)
validateNoCaseAncestor(clazz)
+ if (clazz.isTrait && hasSuperArgs(parents1.head))
+ ConstrArgsInParentOfTraitError(parents1.head, clazz)
if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass)
unit.error(clazz.pos, "inner classes cannot be classfile annotations")
@@ -1854,9 +1970,21 @@ trait Typers extends Modes with Adaptations with Tags {
if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType])
- val body =
- if (isPastTyper || reporter.hasErrors) templ.body
- else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _))
+ val body = {
+ val body =
+ if (isPastTyper || reporter.hasErrors) templ.body
+ else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _))
+ val primaryCtor = treeInfo.firstConstructor(body)
+ val primaryCtor1 = primaryCtor match {
+ case DefDef(_, _, _, _, _, Block(earlyVals :+ global.pendingSuperCall, unit)) =>
+ val argss = superArgs(parents1.head) getOrElse Nil
+ val pos = wrappingPos(parents1.head.pos, argss.flatten)
+ val superCall = atPos(pos)(PrimarySuperCall(argss))
+ deriveDefDef(primaryCtor)(block => Block(earlyVals :+ superCall, unit) setPos pos) setPos pos
+ case _ => primaryCtor
+ }
+ body mapConserve { case `primaryCtor` => primaryCtor1; case stat => stat }
+ }
val body1 = typedStats(body, templ.symbol)
@@ -1897,8 +2025,7 @@ trait Typers extends Modes with Adaptations with Tags {
val typer1 = constrTyperIf(sym.isParameter && sym.owner.isConstructor)
val typedMods = typedModifiers(vdef.mods)
- // complete lazy annotations
- val annots = sym.annotations
+ sym.annotations.map(_.completeInfo)
var tpt1 = checkNoEscaping.privates(sym, typer1.typedType(vdef.tpt))
checkNonCyclic(vdef, tpt1)
@@ -2141,8 +2268,7 @@ trait Typers extends Modes with Adaptations with Tags {
val tparams1 = ddef.tparams mapConserve typedTypeDef
val vparamss1 = ddef.vparamss mapConserve (_ mapConserve typedValDef)
- // complete lazy annotations
- val annots = meth.annotations
+ meth.annotations.map(_.completeInfo)
for (vparams1 <- vparamss1; vparam1 <- vparams1 dropRight 1)
if (isRepeatedParamType(vparam1.symbol.tpe))
@@ -2217,8 +2343,7 @@ trait Typers extends Modes with Adaptations with Tags {
reenterTypeParams(tdef.tparams)
val tparams1 = tdef.tparams mapConserve typedTypeDef
val typedMods = typedModifiers(tdef.mods)
- // complete lazy annotations
- val annots = tdef.symbol.annotations
+ tdef.symbol.annotations.map(_.completeInfo)
// @specialized should not be pickled when compiling with -no-specialize
if (settings.nospecialization.value && currentRun.compiles(tdef.symbol)) {
@@ -2603,7 +2728,7 @@ trait Typers extends Modes with Adaptations with Tags {
if (members.head eq EmptyTree) setError(tree)
else {
val typedBlock = typedPos(tree.pos, mode, pt) {
- Block(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, members, tree.pos.focus), atPos(tree.pos.focus)(New(anonClass.tpe)))
+ Block(ClassDef(anonClass, NoMods, ListOfNil, members, tree.pos.focus), atPos(tree.pos.focus)(New(anonClass.tpe)))
}
// Don't leak implementation details into the type, see SI-6575
if (isPartial && !typedBlock.isErrorTyped)
@@ -2710,6 +2835,7 @@ trait Typers extends Modes with Adaptations with Tags {
def typedRefinement(templ: Template) {
val stats = templ.body
namer.enterSyms(stats)
+
// need to delay rest of typedRefinement to avoid cyclic reference errors
unit.toCheck += { () =>
val stats1 = typedStats(stats, NoSymbol)
@@ -2828,7 +2954,11 @@ trait Typers extends Modes with Adaptations with Tags {
var moreToAdd = true
while (moreToAdd) {
val initElems = scope.elems
- for (sym <- scope)
+ // SI-5877 The decls of a package include decls of the package object. But we don't want to add
+ // the corresponding synthetics to the package class, only to the package object class.
+ def shouldAdd(sym: Symbol) =
+ inBlock || !isInPackageObject(sym, context.owner)
+ for (sym <- scope if shouldAdd(sym))
for (tree <- context.unit.synthetics get sym) {
newStats += typedStat(tree) // might add even more synthetics to the scope
context.unit.synthetics -= sym
@@ -3891,7 +4021,7 @@ trait Typers extends Modes with Adaptations with Tags {
case DynamicApplicationNamed(qual, _) if acceptsApplyDynamic(qual.tpe.widen) => true
case _ => false
// look deeper?
- // val methPart = treeInfo.methPart(fun)
+ // val treeInfo.Applied(methPart, _, _) = fun
// println("methPart of "+ fun +" is "+ methPart)
// if (methPart ne fun) isApplyDynamicNamed(methPart)
// else false
@@ -3926,54 +4056,44 @@ trait Typers extends Modes with Adaptations with Tags {
*
*/
def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = {
- debuglog(s"mkInvoke($cxTree, $tree, $qual, $name)")
+ log(s"dyna.mkInvoke($cxTree, $tree, $qual, $name)")
+ val treeInfo.Applied(treeSelection, _, _) = tree
+ def isDesugaredApply = treeSelection match {
+ case Select(`qual`, nme.apply) => true
+ case _ => false
+ }
acceptsApplyDynamicWithType(qual, name) map { tp =>
- // tp eq NoType => can call xxxDynamic, but not passing any type args (unless specified explicitly by the user)
- // in scala-virtualized, when not NoType, tp is passed as type argument (for selection on a staged Struct)
-
- // strip off type application -- we're not doing much with outer,
- // so don't bother preserving cxTree's attributes etc
- val cxTree1 = cxTree match {
- case t: ValOrDefDef => t.rhs
- case t => t
- }
- val cxTree2 = cxTree1 match {
- case Typed(t, tpe) => t // ignore outer type annotation
- case t => t
- }
- val (outer, explicitTargs) = cxTree2 match {
- case TypeApply(fun, targs) => (fun, targs)
- case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
- case Select(TypeApply(fun, targs), nme) => (Select(fun, nme), targs)
- case t => (t, Nil)
- }
- def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty
-
- def desugaredApply = tree match {
- case Select(`qual`, nme.apply) => true
- case _ => false
+ // If tp == NoType, pass only explicit type arguments to applyXXX. Not used at all
+ // here - it is for scala-virtualized, where tp will be passed as an argument (for
+ // selection on a staged Struct)
+ def hasNamed(args: List[Tree]): Boolean = args exists (_.isInstanceOf[AssignOrNamedArg])
+ // not supported: foo.bar(a1,..., an: _*)
+ def hasStar(args: List[Tree]) = treeInfo.isWildcardStarArgList(args)
+ def applyOp(args: List[Tree]) = if (hasNamed(args)) nme.applyDynamicNamed else nme.applyDynamic
+ def matches(t: Tree) = isDesugaredApply || treeInfo.dissectApplied(t).core == treeSelection
+
+ /** Note that the trees which arrive here are potentially some distance from
+ * the trees of direct interest. `cxTree` is some enclosing expression which
+ * may apparently be arbitrarily larger than `tree`; and `tree` itself is
+ * too small, having at least in some cases lost its explicit type parameters.
+ * This logic is designed to use `tree` to pinpoint the immediately surrounding
+ * Apply/TypeApply/Select node, and only then creates the dynamic call.
+ * See SI-6731 among others.
+ */
+ def findSelection(t: Tree): Option[(TermName, Tree)] = t match {
+ case Apply(fn, args) if hasStar(args) => DynamicVarArgUnsupported(tree, applyOp(args)) ; None
+ case Apply(fn, args) if matches(fn) => Some((applyOp(args), fn))
+ case Assign(lhs, _) if matches(lhs) => Some((nme.updateDynamic, lhs))
+ case _ if matches(t) => Some((nme.selectDynamic, t))
+ case _ => t.children flatMap findSelection headOption
}
- // note: context.tree includes at most one Apply node
- // thus, we can't use it to detect we're going to receive named args in expressions such as:
- // qual.sel(a)(a2, arg2 = "a2")
- val oper = outer match {
- case Apply(q, as) if q == tree || desugaredApply =>
- val oper =
- if (hasNamedArg(as)) nme.applyDynamicNamed
- else nme.applyDynamic
- // not supported: foo.bar(a1,..., an: _*)
- if (treeInfo.isWildcardStarArgList(as)) {
- DynamicVarArgUnsupported(tree, oper)
- return Some(setError(tree))
- } else oper
- case Assign(`tree`, _) => nme.updateDynamic
- case _ => nme.selectDynamic
+ findSelection(cxTree) match {
+ case Some((opName, treeInfo.Applied(_, targs, _))) =>
+ val fun = gen.mkTypeApply(Select(qual, opName), targs)
+ atPos(qual.pos)(Apply(fun, Literal(Constant(name.decode)) :: Nil))
+ case _ =>
+ setError(tree)
}
-
- val dynSel = Select(qual, oper)
- val tappSel = if (explicitTargs.nonEmpty) TypeApply(dynSel, explicitTargs) else dynSel
-
- atPos(qual.pos)(Apply(tappSel, List(Literal(Constant(name.decode)))))
}
}
@@ -3981,7 +4101,7 @@ trait Typers extends Modes with Adaptations with Tags {
silent(typeTree) match {
case SilentResultValue(r) => r
case SilentTypeError(err) => DynamicRewriteError(tree, err)
- }
+ }
}
}
@@ -4158,8 +4278,8 @@ trait Typers extends Modes with Adaptations with Tags {
return fail()
if (treeInfo.mayBeVarGetter(varsym)) {
- treeInfo.methPart(lhs1) match {
- case Select(qual, name) =>
+ lhs1 match {
+ case treeInfo.Applied(Select(qual, name), _, _) =>
val sel = Select(qual, nme.getterToSetter(name.toTermName)) setPos lhs.pos
val app = Apply(sel, List(rhs)) setPos tree.pos
return typed(app, mode, pt)
@@ -4577,9 +4697,9 @@ trait Typers extends Modes with Adaptations with Tags {
}
case Apply(fn, indices) =>
- treeInfo.methPart(fn) match {
- case Select(table, nme.apply) => mkUpdate(table, indices)
- case _ => UnexpectedTreeAssignmentConversionError(qual)
+ fn match {
+ case treeInfo.Applied(Select(table, nme.apply), _, _) => mkUpdate(table, indices)
+ case _ => UnexpectedTreeAssignmentConversionError(qual)
}
}
typed1(tree1, mode, pt)
@@ -5036,7 +5156,7 @@ trait Typers extends Modes with Adaptations with Tags {
val tree1 = (
if (qual == EmptyTree) tree
// atPos necessary because qualifier might come from startContext
- else atPos(tree.pos)(Select(qual, name))
+ else atPos(tree.pos)(Select(qual, name) setAttachments tree.attachments)
)
val (tree2, pre2) = makeAccessible(tree1, defSym, pre, qual)
// assert(pre.typeArgs isEmpty) // no need to add #2416-style check here, right?
@@ -5061,14 +5181,20 @@ trait Typers extends Modes with Adaptations with Tags {
def typedCompoundTypeTree(tree: CompoundTypeTree) = {
val templ = tree.templ
val parents1 = templ.parents mapConserve (typedType(_, mode))
- if (parents1 exists (_.isErrorTyped)) tree setType ErrorType
+
+ // This is also checked later in typedStats, but that is too late for SI-5361, so
+ // we eagerly check this here.
+ for (stat <- templ.body if !treeInfo.isDeclarationOrTypeDef(stat))
+ OnlyDeclarationsError(stat)
+
+ if ((parents1 ++ templ.body) exists (_.isErrorTyped)) tree setType ErrorType
else {
val decls = newScope
//Console.println("Owner: " + context.enclClass.owner + " " + context.enclClass.owner.id)
val self = refinedType(parents1 map (_.tpe), context.enclClass.owner, decls, templ.pos)
newTyper(context.make(templ, self.typeSymbol, decls)).typedRefinement(templ)
templ updateAttachment CompoundTypeTreeOriginalAttachment(parents1, Nil) // stats are set elsewhere
- tree setType self
+ tree setType (if (templ.exists(_.isErroneous)) ErrorType else self) // Being conservative to avoid SI-5361
}
}
@@ -5131,16 +5257,14 @@ trait Typers extends Modes with Adaptations with Tags {
def typedPackageDef(pdef: PackageDef) = {
val pid1 = typedQualifier(pdef.pid).asInstanceOf[RefTree]
assert(sym.moduleClass ne NoSymbol, sym)
- // complete lazy annotations
- val annots = sym.annotations
val stats1 = newTyper(context.make(tree, sym.moduleClass, sym.info.decls))
.typedStats(pdef.stats, NoSymbol)
treeCopy.PackageDef(tree, pid1, stats1) setType NoType
}
def typedDocDef(docdef: DocDef) = {
- val comment = docdef.comment
if (forScaladoc && (sym ne null) && (sym ne NoSymbol)) {
+ val comment = docdef.comment
docComments(sym) = comment
comment.defineVariables(sym)
val typer1 = newTyper(context.makeNewScope(tree, context.owner))
@@ -5375,7 +5499,7 @@ trait Typers extends Modes with Adaptations with Tags {
case tt @ TypeTree() => tree setOriginal tt.original
case _ => tree
}
- }
+ }
else
// we should get here only when something before failed
// and we try again (@see tryTypedApply). In that case we can assign
@@ -5611,21 +5735,21 @@ trait Typers extends Modes with Adaptations with Tags {
// enough to see those. See #3938
ConstructorPrefixError(tree, restpe)
} else {
- //@M fix for #2208
- // if there are no type arguments, normalization does not bypass any checks, so perform it to get rid of AnyRef
- if (result.tpe.typeArgs.isEmpty) {
- // minimal check: if(result.tpe.typeSymbolDirect eq AnyRefClass) {
- // must expand the fake AnyRef type alias, because bootstrapping (init in Definitions) is not
- // designed to deal with the cycles in the scala package (ScalaObject extends
- // AnyRef, but the AnyRef type alias is entered after the scala package is
- // loaded and completed, so that ScalaObject is unpickled while AnyRef is not
- // yet defined )
- // !!! TODO - revisit now that ScalaObject is gone.
- result setType(restpe)
- } else { // must not normalize: type application must be (bounds-)checked (during RefChecks), see #2208
- // during uncurry (after refchecks), all types are normalized
- result
- }
+ //@M fix for #2208
+ // if there are no type arguments, normalization does not bypass any checks, so perform it to get rid of AnyRef
+ if (result.tpe.typeArgs.isEmpty) {
+ // minimal check: if(result.tpe.typeSymbolDirect eq AnyRefClass) {
+ // must expand the fake AnyRef type alias, because bootstrapping (init in Definitions) is not
+ // designed to deal with the cycles in the scala package (ScalaObject extends
+ // AnyRef, but the AnyRef type alias is entered after the scala package is
+ // loaded and completed, so that ScalaObject is unpickled while AnyRef is not
+ // yet defined )
+ // !!! TODO - revisit now that ScalaObject is gone.
+ result setType(restpe)
+ } else { // must not normalize: type application must be (bounds-)checked (during RefChecks), see #2208
+ // during uncurry (after refchecks), all types are normalized
+ result
+ }
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index bf44b65406..a34d7389bf 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -126,7 +126,7 @@ trait Unapplies extends ast.TreeDSL
ModuleDef(
Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin),
cdef.name.toTermName,
- Template(parents, emptyValDef, NoMods, Nil, ListOfNil, body, cdef.impl.pos.focus))
+ Template(parents, emptyValDef, NoMods, Nil, body, cdef.impl.pos.focus))
}
private val caseMods = Modifiers(SYNTHETIC | CASE)
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 95135b84e0..0125f1b189 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -230,7 +230,6 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
emptyValDef,
NoMods,
List(),
- List(List()),
List(methdef),
NoPosition))
trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value))
diff --git a/src/eclipse/continuations-library/.classpath b/src/eclipse/continuations-library/.classpath
new file mode 100644
index 0000000000..b3ca4eeb48
--- /dev/null
+++ b/src/eclipse/continuations-library/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="library"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
+ <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="build-quick-continuations-library"/>
+</classpath>
diff --git a/src/eclipse/continuations-library/.project b/src/eclipse/continuations-library/.project
new file mode 100644
index 0000000000..f3a53a3d97
--- /dev/null
+++ b/src/eclipse/continuations-library/.project
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>continuations-library</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.scala-ide.sdt.core.scalabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.scala-ide.sdt.core.scalanature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+ <linkedResources>
+ <link>
+ <name>build-quick-continuations-library</name>
+ <type>2</type>
+ <locationURI>SCALA_BASEDIR/build/quick/classes/continuations/library</locationURI>
+ </link>
+ <link>
+ <name>library</name>
+ <type>2</type>
+ <locationURI>SCALA_BASEDIR/src/continuations/library</locationURI>
+ </link>
+ </linkedResources>
+</projectDescription>
diff --git a/src/eclipse/continuations-library/.settings/org.scala-ide.sdt.core.prefs b/src/eclipse/continuations-library/.settings/org.scala-ide.sdt.core.prefs
new file mode 100644
index 0000000000..63e1df247f
--- /dev/null
+++ b/src/eclipse/continuations-library/.settings/org.scala-ide.sdt.core.prefs
@@ -0,0 +1,2 @@
+P=continuations\:enable
+scala.compiler.useProjectSettings=true
diff --git a/src/eclipse/partest/.classpath b/src/eclipse/partest/.classpath
index b14e465aa6..7936d4d4b4 100644
--- a/src/eclipse/partest/.classpath
+++ b/src/eclipse/partest/.classpath
@@ -10,5 +10,6 @@
<classpathentry kind="lib" path="lib/jline.jar"/>
<classpathentry kind="lib" path="lib/msil.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/asm"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/>
<classpathentry kind="output" path="build-quick-partest"/>
</classpath>
diff --git a/src/eclipse/reflect/.classpath b/src/eclipse/reflect/.classpath
index 57a3928dc3..36e6b6adf1 100644
--- a/src/eclipse/reflect/.classpath
+++ b/src/eclipse/reflect/.classpath
@@ -3,5 +3,6 @@
<classpathentry kind="src" path="reflect"/>
<classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/>
<classpathentry kind="output" path="build-quick-reflect"/>
</classpath>
diff --git a/src/eclipse/scala-compiler/.classpath b/src/eclipse/scala-compiler/.classpath
index 40a4ed9996..d438d3e610 100644
--- a/src/eclipse/scala-compiler/.classpath
+++ b/src/eclipse/scala-compiler/.classpath
@@ -9,5 +9,6 @@
<classpathentry kind="lib" path="lib/ant/ant.jar"/>
<classpathentry kind="lib" path="lib/jline.jar"/>
<classpathentry kind="lib" path="lib/msil.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/>
<classpathentry kind="output" path="build-quick-compiler"/>
</classpath>
diff --git a/src/eclipse/scalap/.classpath b/src/eclipse/scalap/.classpath
index 2b44ad19b2..16737bd9cd 100644
--- a/src/eclipse/scalap/.classpath
+++ b/src/eclipse/scalap/.classpath
@@ -8,5 +8,6 @@
<classpathentry kind="lib" path="lib/ant/ant.jar"/>
<classpathentry kind="lib" path="lib/jline.jar"/>
<classpathentry kind="lib" path="lib/msil.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/>
<classpathentry kind="output" path="build-quick-scalap"/>
</classpath>
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index 8be0cb1619..1b5fd6c8d3 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -100,8 +100,8 @@ case class StringContext(parts: String*) {
* ''Note:'' Even when using the raw interpolator, Scala will preprocess unicode escapes.
* For example:
* {{{
- * scala> raw"\u0123"
- * res0: String = ģ
+ * scala> raw"\u005cu0025"
+ * res0: String = #
* }}}
*
* @param `args` The arguments to be inserted into the resulting string.
@@ -191,7 +191,7 @@ object StringContext {
var cur = 0
var idx = 0
def output(ch: Char) = {
- bldr append str.substring (start, cur)
+ bldr.append(str, start, cur)
bldr append ch
start = idx
}
@@ -199,14 +199,15 @@ object StringContext {
cur = idx
if (str(idx) == '\\') {
idx += 1
+ if (idx >= len) throw new InvalidEscapeException(str, cur)
if ('0' <= str(idx) && str(idx) <= '7') {
val leadch = str(idx)
var oct = leadch - '0'
idx += 1
- if ('0' <= str(idx) && str(idx) <= '7') {
+ if (idx < len && '0' <= str(idx) && str(idx) <= '7') {
oct = oct * 8 + str(idx) - '0'
idx += 1
- if (leadch <= '3' && '0' <= str(idx) && str(idx) <= '7') {
+ if (idx < len && leadch <= '3' && '0' <= str(idx) && str(idx) <= '7') {
oct = oct * 8 + str(idx) - '0'
idx += 1
}
@@ -234,6 +235,6 @@ object StringContext {
}
}
if (start == 0) str
- else (bldr append str.substring(start, idx)).toString
+ else bldr.append(str, start, idx).toString
}
}
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index 6871a3cb73..f65e2ef9cd 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -22,7 +22,7 @@ import scala.math.{ min, max, Ordering }
* Sequences are special cases of iterable collections of class `Iterable`.
* Unlike iterables, sequences always have a defined order of elements.
* Sequences provide a method `apply` for indexing. Indices range from `0` up to the `length` of
- * a sequence. Sequences support a number to find occurrences of elements or subsequences, including
+ * a sequence. Sequences support a number of methods to find occurrences of elements or subsequences, including
* `segmentLength`, `prefixLength`, `indexWhere`, `indexOf`, `lastIndexWhere`, `lastIndexOf`,
* `startsWith`, `endsWith`, `indexOfSlice`.
*
diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala
index 9115b9e5fb..5e6126a7cf 100644
--- a/src/library/scala/collection/convert/WrapAsJava.scala
+++ b/src/library/scala/collection/convert/WrapAsJava.scala
@@ -10,10 +10,11 @@ package scala.collection
package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
-import Wrappers._
import scala.language.implicitConversions
trait WrapAsJava {
+ import Wrappers._
+
/**
* Implicitly converts a Scala Iterator to a Java Iterator.
* The returned Java Iterator is backed by the provided Scala
diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala
index 5a5d204ece..ffcca62291 100644
--- a/src/library/scala/collection/convert/WrapAsScala.scala
+++ b/src/library/scala/collection/convert/WrapAsScala.scala
@@ -10,11 +10,13 @@ package scala.collection
package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
-import Wrappers._
import scala.language.implicitConversions
trait LowPriorityWrapAsScala {
this: WrapAsScala =>
+
+ import Wrappers._
+
/**
* Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap.
* The returned Scala ConcurrentMap is backed by the provided Java
@@ -34,6 +36,7 @@ trait LowPriorityWrapAsScala {
}
trait WrapAsScala extends LowPriorityWrapAsScala {
+ import Wrappers._
/**
* Implicitly converts a Java `Iterator` to a Scala `Iterator`.
*
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 3b6ab81146..802e16605d 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -33,7 +33,6 @@ import scala.collection.parallel.immutable.ParRange
* @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#ranges "Scala's Collection Library overview"]]
* section on `Ranges` for more information.
*
- * @define Coll Range
* @define coll range
* @define mayNotTerminateInf
* @define willNotTerminateInf
diff --git a/src/library/scala/collection/mutable/MutableList.scala b/src/library/scala/collection/mutable/MutableList.scala
index 183de5b727..fd92d2e555 100644
--- a/src/library/scala/collection/mutable/MutableList.scala
+++ b/src/library/scala/collection/mutable/MutableList.scala
@@ -56,12 +56,16 @@ extends AbstractSeq[A]
/** Returns the rest of this list
*/
override def tail: MutableList[A] = {
- require(nonEmpty, "tail of empty list")
val tl = new MutableList[A]
+ tailImpl(tl)
+ tl
+ }
+
+ protected final def tailImpl(tl: MutableList[A]) {
+ require(nonEmpty, "tail of empty list")
tl.first0 = first0.tail
- tl.last0 = last0
tl.len = len - 1
- tl
+ tl.last0 = if (tl.len == 0) tl.first0 else last0
}
/** Prepends a single element to this list. This operation takes constant
diff --git a/src/library/scala/collection/mutable/Queue.scala b/src/library/scala/collection/mutable/Queue.scala
index 5ea012eb9f..b947fa3cca 100644
--- a/src/library/scala/collection/mutable/Queue.scala
+++ b/src/library/scala/collection/mutable/Queue.scala
@@ -66,7 +66,7 @@ extends MutableList[A]
else {
val res = first0.elem
first0 = first0.next
- len -= 1
+ decrementLength()
res
}
@@ -82,11 +82,11 @@ extends MutableList[A]
else if (p(first0.elem)) {
val res: Option[A] = Some(first0.elem)
first0 = first0.next
- len -= 1
+ decrementLength()
res
} else {
val optElem = removeFromList(p)
- if (optElem != None) len -= 1
+ if (optElem != None) decrementLength()
optElem
}
@@ -119,7 +119,7 @@ extends MutableList[A]
while ((first0.nonEmpty) && p(first0.elem)) {
res += first0.elem
first0 = first0.next
- len -= 1
+ decrementLength()
}
if (first0.isEmpty) res
else removeAllFromList(p, res)
@@ -130,10 +130,10 @@ extends MutableList[A]
var leftlst = first0
while (leftlst.next.nonEmpty) {
if (p(leftlst.next.elem)) {
- res += leftlst.next.elem
- if (leftlst.next eq last0) last0 = leftlst
- leftlst.next = leftlst.next.next
- len -= 1
+ res += leftlst.next.elem
+ if (leftlst.next eq last0) last0 = leftlst
+ leftlst.next = leftlst.next.next
+ decrementLength()
} else leftlst = leftlst.next
}
res
@@ -154,7 +154,7 @@ extends MutableList[A]
else {
val res: Option[LinkedList[A]] = Some(cell.next)
cell.next = cell.next.next
- len -= 1
+ decrementLength()
res
}
}
@@ -170,11 +170,8 @@ extends MutableList[A]
// TODO - Don't override this just for new to create appropriate type....
override def tail: Queue[A] = {
- require(nonEmpty, "tail of empty list")
val tl = new Queue[A]
- tl.first0 = first0.tail
- tl.last0 = last0
- tl.len = len - 1
+ tailImpl(tl)
tl
}
@@ -183,6 +180,11 @@ extends MutableList[A]
bf ++= seq
bf.result
}
+
+ private[this] def decrementLength() {
+ len -= 1
+ if (len == 0) last0 = first0
+ }
}
diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala
index 24c4cd7a32..2b11594f66 100644
--- a/src/library/scala/util/Random.scala
+++ b/src/library/scala/util/Random.scala
@@ -17,7 +17,7 @@ import scala.language.{implicitConversions, higherKinds}
* @author Stephane Micheloud
*
*/
-class Random(val self: java.util.Random) {
+class Random(val self: java.util.Random) extends AnyRef with Serializable {
/** Creates a new random number generator using a single long seed. */
def this(seed: Long) = this(new java.util.Random(seed))
diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala
index 8c18809ad6..483cb491a1 100644
--- a/src/partest/scala/tools/partest/DirectTest.scala
+++ b/src/partest/scala/tools/partest/DirectTest.scala
@@ -39,6 +39,10 @@ abstract class DirectTest extends App {
// new compiler
def newCompiler(args: String*): Global = {
val settings = newSettings((CommandLineParser tokenize ("-d \"" + testOutput.path + "\" " + extraSettings)) ++ args.toList)
+ newCompiler(settings)
+ }
+
+ def newCompiler(settings: Settings): Global = {
if (settings.Yrangepos.value) new Global(settings, reporter(settings)) with interactive.RangePositions
else new Global(settings, reporter(settings))
}
diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala
index e7134d0271..b9abff69d8 100644
--- a/src/partest/scala/tools/partest/ScaladocModelTest.scala
+++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala
@@ -12,7 +12,7 @@ import scala.tools.nsc.util.CommandLineParser
import scala.tools.nsc.doc.{Settings, DocFactory, Universe}
import scala.tools.nsc.doc.model._
import scala.tools.nsc.doc.model.diagram._
-import scala.tools.nsc.doc.model.comment._
+import scala.tools.nsc.doc.base.comment._
import scala.tools.nsc.reporters.ConsoleReporter
/** A class for testing scaladoc model generation
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 0c8e81a220..8f256aa1f5 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -59,8 +59,6 @@ private[reflect] trait BuildUtils { self: Universe =>
def flagsFromBits(bits: Long): FlagSet
- def emptyValDef: ValDef
-
def This(sym: Symbol): Tree
def Select(qualifier: Tree, sym: Symbol): Select
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index c98107f9b5..cfa6315797 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -75,11 +75,26 @@ trait Trees { self: Universe =>
def isDef: Boolean
/** Is this tree one of the empty trees?
+ *
* Empty trees are: the `EmptyTree` null object, `TypeTree` instances that don't carry a type
* and the special `emptyValDef` singleton.
+ *
+ * In the compiler the `isEmpty` check and the derived `orElse` method are mostly used
+ * as a check for a tree being a null object (`EmptyTree` for term trees and empty TypeTree for type trees).
+ *
+ * Unfortunately `emptyValDef` is also considered to be `isEmpty`, but this is deemed to be
+ * a conceptual mistake pending a fix in https://issues.scala-lang.org/browse/SI-6762.
+ *
+ * @see `canHaveAttrs`
*/
def isEmpty: Boolean
+ /** Can this tree carry attributes (i.e. symbols, types or positions)?
+ * Typically the answer is yes, except for the `EmptyTree` null object and
+ * two special singletons: `emptyValDef` and `pendingSuperCall`.
+ */
+ def canHaveAttrs: Boolean
+
/** The canonical way to test if a Tree represents a term.
*/
def isTerm: Boolean
@@ -1611,14 +1626,23 @@ trait Trees { self: Universe =>
* This node always occurs in the following context:
*
* (`new` tpt).<init>[targs](args)
+ *
+ * For example, an AST representation of:
+ *
+ * new Example[Int](2)(3)
+ *
+ * is the following code:
+ *
+ * Apply(
+ * Apply(
+ * TypeApply(
+ * Select(New(TypeTree(typeOf[Example])), nme.CONSTRUCTOR)
+ * TypeTree(typeOf[Int])),
+ * List(Literal(Constant(2)))),
+ * List(Literal(Constant(3))))
* @group Extractors
*/
abstract class NewExtractor {
- /** A user level `new`.
- * One should always use this factory method to build a user level `new`.
- *
- * @param tpt a class type
- */
def apply(tpt: Tree): New
def unapply(new_ : New): Option[Tree]
}
@@ -1720,6 +1744,16 @@ trait Trees { self: Universe =>
* This AST node corresponds to the following Scala code:
*
* fun[args]
+ *
+ * Should only be used with `fun` nodes which are terms, i.e. which have `isTerm` returning `true`.
+ * Otherwise `AppliedTypeTree` should be used instead.
+ *
+ * def foo[T] = ???
+ * foo[Int] // represented as TypeApply(Ident(<foo>), List(TypeTree(<Int>)))
+ *
+ * List[Int] as in `val x: List[Int] = ???`
+ * // represented as AppliedTypeTree(Ident(<List>), List(TypeTree(<Int>)))
+ *
* @group Extractors
*/
abstract class TypeApplyExtractor {
@@ -1890,6 +1924,12 @@ trait Trees { self: Universe =>
* This AST node corresponds to the following Scala code:
*
* qualifier.selector
+ *
+ * Should only be used with `qualifier` nodes which are terms, i.e. which have `isTerm` returning `true`.
+ * Otherwise `SelectFromTypeTree` should be used instead.
+ *
+ * foo.Bar // represented as Select(Ident(<foo>), <Bar>)
+ * Foo#Bar // represented as SelectFromTypeTree(Ident(<Foo>), <Bar>)
* @group Extractors
*/
abstract class SelectExtractor {
@@ -2122,7 +2162,6 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- // [Eugene++] don't see why we need it, when we have Select
type SelectFromTypeTree >: Null <: TypTree with RefTree with SelectFromTypeTreeApi
/** A tag that preserves the identity of the `SelectFromTypeTree` abstract type from erasure.
@@ -2142,6 +2181,12 @@ trait Trees { self: Universe =>
* qualifier # selector
*
* Note: a path-dependent type p.T is expressed as p.type # T
+ *
+ * Should only be used with `qualifier` nodes which are types, i.e. which have `isType` returning `true`.
+ * Otherwise `Select` should be used instead.
+ *
+ * Foo#Bar // represented as SelectFromTypeTree(Ident(<Foo>), <Bar>)
+ * foo.Bar // represented as Select(Ident(<foo>), <Bar>)
* @group Extractors
*/
abstract class SelectFromTypeTreeExtractor {
@@ -2217,6 +2262,15 @@ trait Trees { self: Universe =>
* This AST node corresponds to the following Scala code:
*
* tpt[args]
+ *
+ * Should only be used with `tpt` nodes which are types, i.e. which have `isType` returning `true`.
+ * Otherwise `TypeApply` should be used instead.
+ *
+ * List[Int] as in `val x: List[Int] = ???`
+ * // represented as AppliedTypeTree(Ident(<List>), List(TypeTree(<Int>)))
+ *
+ * def foo[T] = ???
+ * foo[Int] // represented as TypeApply(Ident(<foo>), List(TypeTree(<Int>)))
* @group Extractors
*/
abstract class AppliedTypeTreeExtractor {
@@ -2366,123 +2420,155 @@ trait Trees { self: Universe =>
*/
val emptyValDef: ValDef
+ /** An empty superclass constructor call corresponding to:
+ * super.<init>()
+ * This is used as a placeholder in the primary constructor body in class templates
+ * to denote the insertion point of a call to superclass constructor after the typechecker
+ * figures out the superclass of a given template.
+ * @group Trees
+ */
+ val pendingSuperCall: Apply
+
// ---------------------- factories ----------------------------------------------
/** A factory method for `ClassDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical ClassDef constructor to create a class and then initialize its position and symbol manually", "2.10.1")
def ClassDef(sym: Symbol, impl: Template): ClassDef
/** A factory method for `ModuleDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical ModuleDef constructor to create an object and then initialize its position and symbol manually", "2.10.1")
def ModuleDef(sym: Symbol, impl: Template): ModuleDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical ValDef constructor to create a val and then initialize its position and symbol manually", "2.10.1")
def ValDef(sym: Symbol, rhs: Tree): ValDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical ValDef constructor to create a val with an empty right-hand side and then initialize its position and symbol manually", "2.10.1")
def ValDef(sym: Symbol): ValDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, rhs: Tree): DefDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef
/** A factory method for `TypeDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical TypeDef constructor to create a type alias and then initialize its position and symbol manually", "2.10.1")
def TypeDef(sym: Symbol, rhs: Tree): TypeDef
/** A factory method for `TypeDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical TypeDef constructor to create an abstract type or type parameter and then initialize its position and symbol manually", "2.10.1")
def TypeDef(sym: Symbol): TypeDef
/** A factory method for `LabelDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical LabelDef constructor to create a label and then initialize its position and symbol manually", "2.10.1")
def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef
/** A factory method for `Block` nodes.
* Flattens directly nested blocks.
* @group Factories
*/
+ @deprecated("Use the canonical Block constructor, explicitly specifying its expression if necessary. Flatten directly nested blocks manually if needed", "2.10.1")
def Block(stats: Tree*): Block
/** A factory method for `CaseDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical CaseDef constructor passing EmptyTree for guard", "2.10.1")
def CaseDef(pat: Tree, body: Tree): CaseDef
/** A factory method for `Bind` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical Bind constructor to create a bind and then initialize its symbol manually", "2.10.1")
def Bind(sym: Symbol, body: Tree): Bind
/** A factory method for `Try` nodes.
* @group Factories
*/
+ @deprecated("Use canonical CaseDef constructors to to create exception catching expressions and then wrap them in Try", "2.10.1")
def Try(body: Tree, cases: (Tree, Tree)*): Try
/** A factory method for `Throw` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical New constructor to create an object instantiation expression and then wrap it in Throw", "2.10.1")
def Throw(tpe: Type, args: Tree*): Throw
/** Factory method for object creation `new tpt(args_1)...(args_n)`
* A `New(t, as)` is expanded to: `(new t).<init>(as)`
* @group Factories
*/
+ @deprecated("Use Apply(...Apply(Select(New(tpt), nme.CONSTRUCTOR), args1)...argsN) instead", "2.10.1")
def New(tpt: Tree, argss: List[List[Tree]]): Tree
/** 0-1 argument list new, based on a type.
* @group Factories
*/
+ @deprecated("Use New(TypeTree(tpe), args.toList) instead", "2.10.1")
def New(tpe: Type, args: Tree*): Tree
/** 0-1 argument list new, based on a symbol.
* @group Factories
*/
+ @deprecated("Use New(sym.toType, args) instead", "2.10.1")
def New(sym: Symbol, args: Tree*): Tree
/** A factory method for `Apply` nodes.
* @group Factories
*/
+ @deprecated("Use Apply(Ident(sym), args.toList) instead", "2.10.1")
def Apply(sym: Symbol, args: Tree*): Tree
/** 0-1 argument list new, based on a type tree.
* @group Factories
*/
+ @deprecated("Use Apply(Select(New(tpt), nme.CONSTRUCTOR), args) instead", "2.10.1")
def ApplyConstructor(tpt: Tree, args: List[Tree]): Tree
/** A factory method for `Super` nodes.
* @group Factories
*/
+ @deprecated("Use Super(This(sym), mix) instead", "2.10.1")
def Super(sym: Symbol, mix: TypeName): Tree
/** A factory method for `This` nodes.
@@ -2494,6 +2580,7 @@ trait Trees { self: Universe =>
* The string `name` argument is assumed to represent a [[scala.reflect.api.Names#TermName `TermName`]].
* @group Factories
*/
+ @deprecated("Use Select(tree, newTermName(name)) instead", "2.10.1")
def Select(qualifier: Tree, name: String): Select
/** A factory method for `Select` nodes.
@@ -2504,6 +2591,7 @@ trait Trees { self: Universe =>
/** A factory method for `Ident` nodes.
* @group Factories
*/
+ @deprecated("Use Ident(newTermName(name)) instead", "2.10.1")
def Ident(name: String): Ident
/** A factory method for `Ident` nodes.
@@ -2843,7 +2931,8 @@ trait Trees { self: Universe =>
trees mapConserve (tree => transform(tree).asInstanceOf[TypeDef])
/** Transforms a `ValDef`. */
def transformValDef(tree: ValDef): ValDef =
- if (tree.isEmpty) tree else transform(tree).asInstanceOf[ValDef]
+ if (tree eq emptyValDef) tree
+ else transform(tree).asInstanceOf[ValDef]
/** Transforms a list of `ValDef` nodes. */
def transformValDefs(trees: List[ValDef]): List[ValDef] =
trees mapConserve (transformValDef(_))
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index 7c12b5979d..6a5a742cc7 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -201,6 +201,8 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
override def toString = if (forced) forcedInfo.toString else "@<?>"
override def pos: Position = if (forced) forcedInfo.pos else NoPosition
+
+ override def completeInfo(): Unit = forcedInfo
}
/** Typed information about an annotation. It can be attached to either
@@ -242,6 +244,9 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
this
}
+ // Forces LazyAnnotationInfo, no op otherwise
+ def completeInfo(): Unit = ()
+
/** Annotations annotating annotations are confusing so I drew
* an example. Given the following code:
*
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index d72f08674e..3c2b128c52 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -60,7 +60,7 @@ trait BaseTypeSeqs {
elems(i) match {
case rtp @ RefinedType(variants, decls) =>
// can't assert decls.isEmpty; see t0764
- //if (!decls.isEmpty) assert(false, "computing closure of "+this+":"+this.isInstanceOf[RefinedType]+"/"+closureCache(j))
+ //if (!decls.isEmpty) abort("computing closure of "+this+":"+this.isInstanceOf[RefinedType]+"/"+closureCache(j))
//Console.println("compute closure of "+this+" => glb("+variants+")")
pending += i
try {
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 9f41f0336e..b1b0c5b60b 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -47,8 +47,6 @@ trait BuildUtils { self: SymbolTable =>
def flagsFromBits(bits: Long): FlagSet = bits
- def emptyValDef: ValDef = self.emptyValDef
-
def This(sym: Symbol): Tree = self.This(sym)
def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym)
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index 43902c1930..2f2b02975c 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -334,6 +334,8 @@ trait Importers extends api.Importers { self: SymbolTable =>
new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl))
case from.emptyValDef =>
emptyValDef
+ case from.pendingSuperCall =>
+ pendingSuperCall
case from.ValDef(mods, name, tpt, rhs) =>
new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs))
case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index faa161d6b1..f8c670827a 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -38,7 +38,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
protected class DefaultPosAssigner extends PosAssigner {
var pos: Position = _
override def traverse(t: Tree) {
- if (t eq EmptyTree) ()
+ if (!t.canHaveAttrs) ()
else if (t.pos == NoPosition) {
t.setPos(pos)
super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 80d247c0ea..a8085a4c58 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -435,7 +435,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case tree =>
xprintTree(this, tree)
}
- if (printTypes && tree.isTerm && !tree.isEmpty) {
+ if (printTypes && tree.isTerm && tree.canHaveAttrs) {
print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
}
}
@@ -542,8 +542,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
print(")")
case EmptyTree =>
print("EmptyTree")
- case emptyValDef: AnyRef if emptyValDef eq self.emptyValDef =>
+ case self.emptyValDef =>
print("emptyValDef")
+ case self.pendingSuperCall =>
+ print("pendingSuperCall")
case tree: Tree =>
val hasSymbol = tree.hasSymbol && tree.symbol != NoSymbol
val isError = hasSymbol && tree.symbol.name.toString == nme.ERROR.toString
diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index 1df91a67b0..b782353ed3 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -10,6 +10,7 @@ trait StdAttachments {
trait Attachable {
protected var rawatt: scala.reflect.macros.Attachments { type Pos = Position } = NoPosition
def attachments = rawatt
+ def setAttachments(attachments: scala.reflect.macros.Attachments { type Pos = Position }): this.type = { rawatt = attachments; this }
def updateAttachment[T: ClassTag](attachment: T): this.type = { rawatt = rawatt.update(attachment); this }
def removeAttachment[T: ClassTag]: this.type = { rawatt = rawatt.remove[T]; this }
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 5e7f5777b2..c870d8972d 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -730,6 +730,7 @@ trait StdNames {
val null_ : NameType = "null"
val ofDim: NameType = "ofDim"
val origin: NameType = "origin"
+ val pendingSuperCall: NameType = "pendingSuperCall"
val prefix : NameType = "prefix"
val productArity: NameType = "productArity"
val productElement: NameType = "productElement"
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index a27afe9dfd..a4287fb181 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -3090,7 +3090,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
class RefinementClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position)
extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) {
override def name_=(name: Name) {
- assert(false, "Cannot set name of RefinementClassSymbol to " + name)
+ abort("Cannot set name of RefinementClassSymbol to " + name)
super.name_=(name)
}
override def isRefinementClass = true
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 8ad15f37e4..8908036442 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -159,7 +159,7 @@ abstract class TreeInfo {
* Also accounts for varargs.
*/
private def applyMethodParameters(fn: Tree): List[Symbol] = {
- val depth = applyDepth(fn)
+ val depth = dissectApplied(fn).applyDepth
// There could be applies which go beyond the parameter list(s),
// being applied to the result of the method call.
// !!! Note that this still doesn't seem correct, although it should
@@ -195,29 +195,26 @@ abstract class TreeInfo {
def isGetter = mayBeVarGetter(sym) && sym.owner.info.member(nme.getterToSetter(sym.name.toTermName)) != NoSymbol
tree match {
- case Ident(_) => isVar
- case Select(_, _) => isVar || isGetter
- case _ =>
- methPart(tree) match {
- case Select(qual, nme.apply) => qual.tpe.member(nme.update) != NoSymbol
- case _ => false
- }
+ case Ident(_) => isVar
+ case Select(_, _) => isVar || isGetter
+ case Applied(Select(qual, nme.apply), _, _) => qual.tpe.member(nme.update) != NoSymbol
+ case _ => false
}
}
/** Is tree a self constructor call this(...)? I.e. a call to a constructor of the
* same object?
*/
- def isSelfConstrCall(tree: Tree): Boolean = methPart(tree) match {
- case Ident(nme.CONSTRUCTOR)
- | Select(This(_), nme.CONSTRUCTOR) => true
+ def isSelfConstrCall(tree: Tree): Boolean = tree match {
+ case Applied(Ident(nme.CONSTRUCTOR), _, _) => true
+ case Applied(Select(This(_), nme.CONSTRUCTOR), _, _) => true
case _ => false
}
/** Is tree a super constructor call?
*/
- def isSuperConstrCall(tree: Tree): Boolean = methPart(tree) match {
- case Select(Super(_, _), nme.CONSTRUCTOR) => true
+ def isSuperConstrCall(tree: Tree): Boolean = tree match {
+ case Applied(Select(Super(_, _), nme.CONSTRUCTOR), _, _) => true
case _ => false
}
@@ -333,6 +330,9 @@ abstract class TreeInfo {
def preSuperFields(stats: List[Tree]): List[ValDef] =
stats collect { case vd: ValDef if isEarlyValDef(vd) => vd }
+ def hasUntypedPreSuperFields(stats: List[Tree]): Boolean =
+ preSuperFields(stats) exists (_.tpt.isEmpty)
+
def isEarlyDef(tree: Tree) = tree match {
case TypeDef(mods, _, _, _) => mods hasFlag PRESUPER
case ValDef(mods, _, _, _) => mods hasFlag PRESUPER
@@ -399,22 +399,6 @@ abstract class TreeInfo {
case _ => false
}
- /** If this tree represents a type application (after unwrapping
- * any applies) the first type argument. Otherwise, EmptyTree.
- */
- def firstTypeArg(tree: Tree): Tree = tree match {
- case Apply(fn, _) => firstTypeArg(fn)
- case TypeApply(_, targ :: _) => targ
- case _ => EmptyTree
- }
-
- /** If this tree represents a type application the type arguments. Otherwise Nil.
- */
- def typeArguments(tree: Tree): List[Tree] = tree match {
- case TypeApply(_, targs) => targs
- case _ => Nil
- }
-
/** If this tree has type parameters, those. Otherwise Nil.
*/
def typeParameters(tree: Tree): List[TypeDef] = tree match {
@@ -513,31 +497,126 @@ abstract class TreeInfo {
def isSynthCaseSymbol(sym: Symbol) = sym hasAllFlags SYNTH_CASE_FLAGS
def hasSynthCaseSymbol(t: Tree) = t.symbol != null && isSynthCaseSymbol(t.symbol)
+ def isTraitRef(tree: Tree): Boolean = {
+ val sym = if (tree.tpe != null) tree.tpe.typeSymbol else null
+ ((sym ne null) && sym.initialize.isTrait)
+ }
- /** The method part of an application node
+ /** Applications in Scala can have one of the following shapes:
+ *
+ * 1) naked core: Ident(_) or Select(_, _) or basically anything else
+ * 2) naked core with targs: TypeApply(core, targs) or AppliedTypeTree(core, targs)
+ * 3) apply or several applies wrapping a core: Apply(core, _), or Apply(Apply(core, _), _), etc
+ *
+ * This class provides different ways to decompose applications and simplifies their analysis.
+ *
+ * ***Examples***
+ * (TypeApply in the examples can be replaced with AppliedTypeTree)
+ *
+ * Ident(foo):
+ * * callee = Ident(foo)
+ * * core = Ident(foo)
+ * * targs = Nil
+ * * argss = Nil
+ *
+ * TypeApply(foo, List(targ1, targ2...))
+ * * callee = TypeApply(foo, List(targ1, targ2...))
+ * * core = foo
+ * * targs = List(targ1, targ2...)
+ * * argss = Nil
+ *
+ * Apply(foo, List(arg1, arg2...))
+ * * callee = foo
+ * * core = foo
+ * * targs = Nil
+ * * argss = List(List(arg1, arg2...))
+ *
+ * Apply(Apply(foo, List(arg21, arg22, ...)), List(arg11, arg12...))
+ * * callee = foo
+ * * core = foo
+ * * targs = Nil
+ * * argss = List(List(arg11, arg12...), List(arg21, arg22, ...))
+ *
+ * Apply(Apply(TypeApply(foo, List(targs1, targs2, ...)), List(arg21, arg22, ...)), List(arg11, arg12...))
+ * * callee = TypeApply(foo, List(targs1, targs2, ...))
+ * * core = foo
+ * * targs = Nil
+ * * argss = List(List(arg11, arg12...), List(arg21, arg22, ...))
*/
- def methPart(tree: Tree): Tree = tree match {
- case Apply(fn, _) => methPart(fn)
- case TypeApply(fn, _) => methPart(fn)
- case AppliedTypeTree(fn, _) => methPart(fn)
- case _ => tree
+ class Applied(val tree: Tree) {
+ /** The tree stripped of the possibly nested applications.
+ * The original tree if it's not an application.
+ */
+ def callee: Tree = {
+ def loop(tree: Tree): Tree = tree match {
+ case Apply(fn, _) => loop(fn)
+ case tree => tree
+ }
+ loop(tree)
+ }
+
+ /** The `callee` unwrapped from type applications.
+ * The original `callee` if it's not a type application.
+ */
+ def core: Tree = callee match {
+ case TypeApply(fn, _) => fn
+ case AppliedTypeTree(fn, _) => fn
+ case tree => tree
+ }
+
+ /** The type arguments of the `callee`.
+ * `Nil` if the `callee` is not a type application.
+ */
+ def targs: List[Tree] = callee match {
+ case TypeApply(_, args) => args
+ case AppliedTypeTree(_, args) => args
+ case _ => Nil
+ }
+
+ /** (Possibly multiple lists of) value arguments of an application.
+ * `Nil` if the `callee` is not an application.
+ */
+ def argss: List[List[Tree]] = {
+ def loop(tree: Tree): List[List[Tree]] = tree match {
+ case Apply(fn, args) => loop(fn) :+ args
+ case _ => Nil
+ }
+ loop(tree)
+ }
+
+ /** The depth of the nested applies: e.g. Apply(Apply(Apply(_, _), _), _)
+ * has depth 3. Continues through type applications (without counting them.)
+ */
+ def applyDepth: Int = {
+ def loop(tree: Tree): Int = tree match {
+ case Apply(fn, _) => 1 + loop(fn)
+ case TypeApply(fn, _) => loop(fn)
+ case AppliedTypeTree(fn, _) => loop(fn)
+ case _ => 0
+ }
+ loop(tree)
+ }
}
- /** The depth of the nested applies: e.g. Apply(Apply(Apply(_, _), _), _)
- * has depth 3. Continues through type applications (without counting them.)
+ /** Returns a wrapper that knows how to destructure and analyze applications.
*/
- def applyDepth(tree: Tree): Int = tree match {
- case Apply(fn, _) => 1 + applyDepth(fn)
- case TypeApply(fn, _) => applyDepth(fn)
- case AppliedTypeTree(fn, _) => applyDepth(fn)
- case _ => 0
- }
- def firstArgument(tree: Tree): Tree = tree match {
- case Apply(fn, args) =>
- val f = firstArgument(fn)
- if (f == EmptyTree && !args.isEmpty) args.head else f
- case _ =>
- EmptyTree
+ def dissectApplied(tree: Tree) = new Applied(tree)
+
+ /** Destructures applications into important subparts described in `Applied` class,
+ * namely into: core, targs and argss (in the specified order).
+ *
+ * Trees which are not applications are also accepted. Their callee and core will
+ * be equal to the input, while targs and argss will be Nil.
+ *
+ * The provided extractors don't expose all the API of the `Applied` class.
+ * For advanced use, call `dissectApplied` explicitly and use its methods instead of pattern matching.
+ */
+ object Applied {
+ def unapply(applied: Applied): Option[(Tree, List[Tree], List[List[Tree]])] =
+ Some((applied.core, applied.targs, applied.argss))
+
+ def unapply(tree: Tree): Option[(Tree, List[Tree], List[List[Tree]])] =
+ unapply(dissectApplied(tree))
}
/** Does list of trees start with a definition of
@@ -634,7 +713,7 @@ abstract class TreeInfo {
}
def unapply(tree: Tree) = refPart(tree) match {
- case ref: RefTree => Some((ref.qualifier.symbol, ref.symbol, typeArguments(tree)))
+ case ref: RefTree => Some((ref.qualifier.symbol, ref.symbol, dissectApplied(tree).targs))
case _ => None
}
}
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 6df4b75a88..dceec18e57 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -36,6 +36,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
def isDef = false
def isEmpty = false
+ def canHaveAttrs = true
/** The canonical way to test if a Tree represents a term.
*/
@@ -228,14 +229,6 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def isDef = true
}
- case object EmptyTree extends TermTree {
- val asList = List(this)
- super.tpe_=(NoType)
- override def tpe_=(t: Type) =
- if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
- override def isEmpty = true
- }
-
abstract class MemberDef extends DefTree with MemberDefApi {
def mods: Modifiers
def keyword: String = this match {
@@ -599,6 +592,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args)
case _: ApplyImplicitView => new ApplyImplicitView(fun, args)
// TODO: ApplyConstructor ???
+ case self.pendingSuperCall => self.pendingSuperCall
case _ => new Apply(fun, args)
}).copyAttrs(tree)
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
@@ -961,12 +955,23 @@ trait Trees extends api.Trees { self: SymbolTable =>
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
- object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) {
- override def isEmpty = true
+ trait CannotHaveAttrs extends Tree {
+ override def canHaveAttrs = false
+
+ private def unsupported(what: String, args: Any*) =
+ throw new UnsupportedOperationException(s"$what($args) inapplicable for "+self.toString)
+
super.setPos(NoPosition)
- override def setPos(pos: Position) = { assert(false); this }
+ override def setPos(pos: Position) = unsupported("setPos", pos)
+
+ super.setType(NoType)
+ override def tpe_=(t: Type) = if (t != NoType) unsupported("tpe_=", t)
}
+ case object EmptyTree extends TermTree with CannotHaveAttrs { override def isEmpty = true; val asList = List(this) }
+ object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with CannotHaveAttrs
+ object pendingSuperCall extends Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List()) with CannotHaveAttrs
+
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
atPos(sym.pos) {
assert(sym != NoSymbol)
@@ -1034,6 +1039,9 @@ trait Trees extends api.Trees { self: SymbolTable =>
def New(tpe: Type, args: Tree*): Tree =
ApplyConstructor(TypeTree(tpe), args.toList)
+ def New(tpe: Type, argss: List[List[Tree]]): Tree =
+ New(TypeTree(tpe), argss)
+
def New(sym: Symbol, args: Tree*): Tree =
New(sym.tpe, args: _*)
@@ -1114,7 +1122,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
traverse(annot); traverse(arg)
case Template(parents, self, body) =>
traverseTrees(parents)
- if (!self.isEmpty) traverse(self)
+ if (self ne emptyValDef) traverse(self)
traverseStats(body, tree.symbol)
case Block(stats, expr) =>
traverseTrees(stats); traverse(expr)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 0c4cda8313..119a57d268 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -1401,7 +1401,7 @@ trait Types extends api.Types { self: SymbolTable =>
if (!sym.isClass) {
// SI-6640 allow StubSymbols to reveal what's missing from the classpath before we trip the assertion.
sym.failIfStub()
- assert(false, sym)
+ abort(s"ThisType($sym) for sym which is not a class")
}
//assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym)
@@ -6605,11 +6605,11 @@ trait Types extends api.Types { self: SymbolTable =>
case ExistentialType(qs, _) => qs
case t => List()
}
- def stripType(tp: Type) = tp match {
+ def stripType(tp: Type): Type = tp match {
case ExistentialType(_, res) =>
res
case tv@TypeVar(_, constr) =>
- if (tv.instValid) constr.inst
+ if (tv.instValid) stripType(constr.inst)
else if (tv.untouchable) tv
else abort("trying to do lub/glb of typevar "+tp)
case t => t
@@ -7067,7 +7067,7 @@ trait Types extends api.Types { self: SymbolTable =>
case ExistentialType(tparams, quantified) :: rest =>
mergePrefixAndArgs(quantified :: rest, variance, depth) map (existentialAbstraction(tparams, _))
case _ =>
- assert(false, tps); None
+ abort(s"mergePrefixAndArgs($tps, $variance, $depth): unsupported tps")
}
def addMember(thistp: Type, tp: Type, sym: Symbol): Unit = addMember(thistp, tp, sym, AnyDepth)
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index f3a5053a91..603fff4f1c 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -309,7 +309,7 @@ abstract class UnPickler {
if (isModuleRoot) moduleRoot setFlag pflags
else owner.newLinkedModule(clazz, pflags)
case VALsym =>
- if (isModuleRoot) { assert(false); NoSymbol }
+ if (isModuleRoot) { abort(s"VALsym at module root: owner = $owner, name = $name") }
else owner.newTermSymbol(name.toTermName, NoPosition, pflags)
case _ =>
diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
index 0c1640ceb9..6dc6a0f7b8 100644
--- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala
+++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
@@ -19,8 +19,7 @@ trait UnCurry {
case MethodType(params, MethodType(params1, restpe)) =>
apply(MethodType(params ::: params1, restpe))
case MethodType(params, ExistentialType(tparams, restpe @ MethodType(_, _))) =>
- assert(false, "unexpected curried method types with intervening existential")
- tp0
+ abort("unexpected curried method types with intervening existential")
case MethodType(h :: t, restpe) if h.isImplicit =>
apply(MethodType(h.cloneSymbol.resetFlag(IMPLICIT) :: t, restpe))
case NullaryMethodType(restpe) =>
diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala
index 0725e9775b..3d10d4c9ce 100644
--- a/src/reflect/scala/reflect/internal/util/Position.scala
+++ b/src/reflect/scala/reflect/internal/util/Position.scala
@@ -7,6 +7,7 @@
package scala.reflect.internal.util
import scala.reflect.ClassTag
+import scala.reflect.internal.FatalError
import scala.reflect.macros.Attachments
object Position {
@@ -269,7 +270,7 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e
/** new for position ranges */
class RangePosition(source: SourceFile, override val start: Int, point: Int, override val end: Int)
extends OffsetPosition(source, point) {
- if (start > end) assert(false, "bad position: "+show)
+ if (start > end) sys.error("bad position: "+show)
override def isRange: Boolean = true
override def isOpaqueRange: Boolean = true
override def startOrPoint: Int = start
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index ab93d7033a..d110bd4273 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -416,7 +416,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
case sym if sym.owner.isPrimitiveValueClass => invokePrimitiveMethod
case sym if sym == Predef_classOf => fail("Predef.classOf is a compile-time function")
case sym if sym.isTermMacro => fail(s"${symbol.fullName} is a macro, i.e. a compile-time function")
- case _ => assert(false, this)
+ case _ => abort(s"unsupported symbol $symbol when invoking $this")
}
}
}
diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala
index 34b64938b4..f2c47aad77 100644
--- a/test/files/jvm/serialization.scala
+++ b/test/files/jvm/serialization.scala
@@ -604,6 +604,7 @@ object Test {
Test7
Test8
Test9_parallel
+ Test10_util
}
}
@@ -669,3 +670,17 @@ object Test9_parallel {
throw e
}
}
+
+//############################################################################
+// Test classes in package scala.util
+
+object Test10_util {
+ import scala.util.Random
+ def rep[A](n: Int)(f: => A) { if (n > 0) { f; rep(n-1)(f) } }
+
+ try {
+ val random = new Random(345)
+ val random2: Random = read(write(random))
+ rep(5) { assert(random.nextInt == random2.nextInt) }
+ }
+}
diff --git a/test/files/neg/anyval-anyref-parent.check b/test/files/neg/anyval-anyref-parent.check
index fe20e5de81..8c2aa36583 100644
--- a/test/files/neg/anyval-anyref-parent.check
+++ b/test/files/neg/anyval-anyref-parent.check
@@ -3,7 +3,7 @@ trait Foo2 extends AnyVal // fail
^
anyval-anyref-parent.scala:5: error: Any does not have a constructor
class Bar1 extends Any // fail
- ^
+ ^
anyval-anyref-parent.scala:6: error: value class needs to have exactly one public val parameter
class Bar2(x: Int) extends AnyVal // fail
^
diff --git a/test/files/neg/case-collision.check b/test/files/neg/case-collision.check
new file mode 100644
index 0000000000..4edc6f1205
--- /dev/null
+++ b/test/files/neg/case-collision.check
@@ -0,0 +1,10 @@
+case-collision.scala:5: error: Class foo.BIPPY differs only in case from foo.Bippy. Such classes will overwrite one another on case-insensitive filesystems.
+class BIPPY
+ ^
+case-collision.scala:11: error: Class foo.HyRaX$ differs only in case from foo.Hyrax$. Such classes will overwrite one another on case-insensitive filesystems.
+object HyRaX
+ ^
+case-collision.scala:8: error: Class foo.DINGO$ differs only in case from foo.Dingo$. Such classes will overwrite one another on case-insensitive filesystems.
+object DINGO
+ ^
+three errors found
diff --git a/test/files/neg/case-collision.flags b/test/files/neg/case-collision.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/case-collision.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/case-collision.scala b/test/files/neg/case-collision.scala
new file mode 100644
index 0000000000..241169a77a
--- /dev/null
+++ b/test/files/neg/case-collision.scala
@@ -0,0 +1,11 @@
+package foo
+
+class Bippy
+
+class BIPPY
+
+object Dingo
+object DINGO
+
+case class Hyrax()
+object HyRaX
diff --git a/test/files/neg/cyclics-import.check b/test/files/neg/cyclics-import.check
index ef355fab0a..be09fca374 100644
--- a/test/files/neg/cyclics-import.check
+++ b/test/files/neg/cyclics-import.check
@@ -3,13 +3,4 @@ Note: this is often due in part to a class depending on a definition nested with
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
+one error found
diff --git a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala
index 845a168ff2..7a7293422e 100644
--- a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala
+++ b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala
@@ -5,10 +5,10 @@ object Impls {
def foo_targs[T, U: c.WeakTypeTag](c: Ctx)(implicit x: c.Expr[Int]) = {
import c.{prefix => prefix}
import c.universe._
- val body = Block(
+ val body = Block(List(
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))),
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.staticType)))),
- Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + implicitly[c.WeakTypeTag[U]].tpe)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + implicitly[c.WeakTypeTag[U]].tpe))))),
Literal(Constant(())))
c.Expr[Unit](body)
}
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index f3c45a6aa0..6f9dc7d127 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -100,7 +100,7 @@ Error occurred in an application involving default arguments.
^
names-defaults-neg.scala:86: error: module extending its companion class cannot use default constructor arguments
object C extends C()
- ^
+ ^
names-defaults-neg.scala:90: error: deprecated parameter name x has to be distinct from any other parameter name (deprecated or not).
def deprNam1(x: Int, @deprecatedName('x) y: String) = 0
^
diff --git a/test/files/neg/protected-constructors.check b/test/files/neg/protected-constructors.check
index f137158ed6..e295917050 100644
--- a/test/files/neg/protected-constructors.check
+++ b/test/files/neg/protected-constructors.check
@@ -19,7 +19,4 @@ protected-constructors.scala:15: error: class Foo3 in object Ding cannot be acce
object Ding in package dingus where target is defined
class Bar3 extends Ding.Foo3("abc")
^
-protected-constructors.scala:15: error: too many arguments for constructor Object: ()Object
- class Bar3 extends Ding.Foo3("abc")
- ^
-5 errors found
+four errors found
diff --git a/test/files/neg/t1672b.check b/test/files/neg/t1672b.check
new file mode 100644
index 0000000000..60ccf77174
--- /dev/null
+++ b/test/files/neg/t1672b.check
@@ -0,0 +1,16 @@
+t1672b.scala:3: error: could not optimize @tailrec annotated method bar: it contains a recursive call not in tail position
+ def bar : Nothing = {
+ ^
+t1672b.scala:14: error: could not optimize @tailrec annotated method baz: it contains a recursive call not in tail position
+ def baz : Nothing = {
+ ^
+t1672b.scala:29: error: could not optimize @tailrec annotated method boz: it contains a recursive call not in tail position
+ case _: Throwable => boz; ???
+ ^
+t1672b.scala:34: error: could not optimize @tailrec annotated method bez: it contains a recursive call not in tail position
+ def bez : Nothing = {
+ ^
+t1672b.scala:46: error: could not optimize @tailrec annotated method bar: it contains a recursive call not in tail position
+ else 1 + (try {
+ ^
+5 errors found
diff --git a/test/files/neg/t1672b.scala b/test/files/neg/t1672b.scala
new file mode 100644
index 0000000000..0ccdd03633
--- /dev/null
+++ b/test/files/neg/t1672b.scala
@@ -0,0 +1,52 @@
+object Test {
+ @annotation.tailrec
+ def bar : Nothing = {
+ try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => bar
+ } finally {
+ bar
+ }
+ }
+
+ @annotation.tailrec
+ def baz : Nothing = {
+ try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => baz
+ } finally {
+ ???
+ }
+ }
+
+ @annotation.tailrec
+ def boz : Nothing = {
+ try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => boz; ???
+ }
+ }
+
+ @annotation.tailrec
+ def bez : Nothing = {
+ try {
+ bez
+ } finally {
+ ???
+ }
+ }
+
+ // the `liftedTree` local method will prevent a tail call here.
+ @annotation.tailrec
+ def bar(i : Int) : Int = {
+ if (i == 0) 0
+ else 1 + (try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => bar(i - 1)
+ })
+ }
+}
diff --git a/test/files/neg/t2148.check b/test/files/neg/t2148.check
index 5113b48e51..27b5dce507 100644
--- a/test/files/neg/t2148.check
+++ b/test/files/neg/t2148.check
@@ -1,4 +1,4 @@
-t2148.scala:9: error: type A is not a stable prefix
+t2148.scala:9: error: A is not a legal prefix for a constructor
val b = new A with A#A1
^
one error found
diff --git a/test/files/neg/t3222.check b/test/files/neg/t3222.check
index e724024f45..6170827cc9 100644
--- a/test/files/neg/t3222.check
+++ b/test/files/neg/t3222.check
@@ -1,7 +1,13 @@
-t3222.scala:4: error: not found: type D
- def foo(@throws(classOf[D]) x: Int) {}
- ^
t3222.scala:1: error: not found: type B
@throws(classOf[B])
^
-two errors found
+t3222.scala:4: error: not found: type D
+ def foo(@throws(classOf[D]) x: Int) {}
+ ^
+t3222.scala:3: error: not found: type C
+ @throws(classOf[C])
+ ^
+t3222.scala:6: error: not found: type E
+ @throws(classOf[E])
+ ^
+four errors found
diff --git a/test/files/neg/t3614.check b/test/files/neg/t3614.check
index 0f9c83aa0d..81628ef37f 100644
--- a/test/files/neg/t3614.check
+++ b/test/files/neg/t3614.check
@@ -1,4 +1,4 @@
-t3614.scala:2: error: class type required but AnyRef{def a: Int} found
+t3614.scala:2: error: only declarations allowed here
def v = new ({ def a=0 })
- ^
+ ^
one error found
diff --git a/test/files/neg/t4044.check b/test/files/neg/t4044.check
index 41a04f69b9..0e1ea4f51d 100644
--- a/test/files/neg/t4044.check
+++ b/test/files/neg/t4044.check
@@ -1,11 +1,6 @@
t4044.scala:9: error: AnyRef takes no type parameters, expected: one
M[AnyRef] // error, (AnyRef :: *) not kind-conformant to (N :: * -> * -> *)
^
-t4044.scala:9: error: kinds of the type arguments (<error>) do not conform to the expected kinds of the type parameters (type N).
-<error>'s type parameters do not match type N's expected parameters:
-<none> has no type parameters, but type N has one
- M[AnyRef] // error, (AnyRef :: *) not kind-conformant to (N :: * -> * -> *)
- ^
t4044.scala:11: error: kinds of the type arguments (Test.A) do not conform to the expected kinds of the type parameters (type N).
Test.A's type parameters do not match type N's expected parameters:
type _ has no type parameters, but type O has one
@@ -16,4 +11,4 @@ Test.C's type parameters do not match type N's expected parameters:
type _ has one type parameter, but type _ has none
M[C] // error, (C :: (* -> * -> * -> *) not kind-conformant to (N :: * -> * -> *)
^
-four errors found
+three errors found
diff --git a/test/files/neg/t409.check b/test/files/neg/t409.check
index 433d64d25d..0edc0d03cd 100644
--- a/test/files/neg/t409.check
+++ b/test/files/neg/t409.check
@@ -1,4 +1,4 @@
-t409.scala:6: error: traits or objects may not have parameters
+t409.scala:6: error: class Case1 needs to be a trait to be mixed in
class Toto extends Expr with Case1(12);
- ^
+ ^
one error found
diff --git a/test/files/neg/t5361.check b/test/files/neg/t5361.check
new file mode 100644
index 0000000000..d7fee87ccd
--- /dev/null
+++ b/test/files/neg/t5361.check
@@ -0,0 +1,4 @@
+t5361.scala:2: error: only declarations allowed here
+ val x : { val self = this } = new { self => }
+ ^
+one error found
diff --git a/test/files/neg/t5361.scala b/test/files/neg/t5361.scala
new file mode 100644
index 0000000000..1705c09df3
--- /dev/null
+++ b/test/files/neg/t5361.scala
@@ -0,0 +1,3 @@
+class A {
+ val x : { val self = this } = new { self => }
+}
diff --git a/test/files/neg/t5529.check b/test/files/neg/t5529.check
index 5d2175fa79..da3f84e1ec 100644
--- a/test/files/neg/t5529.check
+++ b/test/files/neg/t5529.check
@@ -4,7 +4,4 @@ t5529.scala:12: error: File is already defined as class File
t5529.scala:10: error: class type required but test.Test.File found
sealed class Dir extends File { }
^
-t5529.scala:10: error: test.Test.File does not have a constructor
- sealed class Dir extends File { }
- ^
-three errors found
+two errors found
diff --git a/test/files/neg/t5696.check b/test/files/neg/t5696.check
index 72b7781fc4..e0fb61b839 100644
--- a/test/files/neg/t5696.check
+++ b/test/files/neg/t5696.check
@@ -15,5 +15,5 @@ t5696.scala:38: error: too many argument lists for constructor invocation
^
t5696.scala:46: error: too many argument lists for constructor invocation
object x extends G(1)(2) {}
- ^
+ ^
6 errors found
diff --git a/test/files/neg/t6260.check b/test/files/neg/t6260.check
index 2b7f1a8bfb..46e9bd1dfc 100644
--- a/test/files/neg/t6260.check
+++ b/test/files/neg/t6260.check
@@ -1,10 +1,10 @@
-t6260.scala:3: error: bridge generated for member method apply: (x$1: Box[X])Box[Y] in anonymous class $anonfun
+t6260.scala:3: error: bridge generated for member method apply: (bx: Box[X])Box[Y] in anonymous class $anonfun
which overrides method apply: (v1: T1)R in trait Function1
clashes with definition of the member itself;
both have erased type (v1: Object)Object
((bx: Box[X]) => new Box(f(bx.x)))(this)
^
-t6260.scala:8: error: bridge generated for member method apply: (x$1: Box[X])Box[Y] in anonymous class $anonfun
+t6260.scala:8: error: bridge generated for member method apply: (bx: Box[X])Box[Y] in anonymous class $anonfun
which overrides method apply: (v1: T1)R in trait Function1
clashes with definition of the member itself;
both have erased type (v1: Object)Object
diff --git a/test/files/neg/t6535.check b/test/files/neg/t6535.check
new file mode 100644
index 0000000000..1225ea70db
--- /dev/null
+++ b/test/files/neg/t6535.check
@@ -0,0 +1,6 @@
+t6535.scala:2: 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 Bs.B._
+ ^
+one error found
diff --git a/test/files/neg/t6535.scala b/test/files/neg/t6535.scala
new file mode 100644
index 0000000000..30a750311c
--- /dev/null
+++ b/test/files/neg/t6535.scala
@@ -0,0 +1,15 @@
+object As {
+ import Bs.B._
+
+ object A
+ extends scala.AnyRef // needed for the cycle;
+ // replacing with a locally defined closs doesn't
+ // hit the locked import and hence doesn't cycle.
+}
+
+object Bs {
+ import As.A._
+
+ object B
+ extends scala.AnyRef // scala.Immutable, ...
+}
diff --git a/test/files/neg/t6558.check b/test/files/neg/t6558.check
new file mode 100644
index 0000000000..6ad3cecd50
--- /dev/null
+++ b/test/files/neg/t6558.check
@@ -0,0 +1,10 @@
+t6558.scala:4: error: not found: type classs
+ @classs
+ ^
+t6558.scala:7: error: not found: type typeparam
+ class D[@typeparam T]
+ ^
+t6558.scala:10: error: not found: type valueparam
+ @valueparam x: Any
+ ^
+three errors found
diff --git a/test/files/neg/t6558.scala b/test/files/neg/t6558.scala
new file mode 100644
index 0000000000..b4304ff686
--- /dev/null
+++ b/test/files/neg/t6558.scala
@@ -0,0 +1,12 @@
+class AnnotNotFound {
+ def foo(a: Any) = ()
+
+ @classs
+ class C
+
+ class D[@typeparam T]
+
+ class E(
+ @valueparam x: Any
+ )
+}
diff --git a/test/files/neg/t6558b.check b/test/files/neg/t6558b.check
new file mode 100644
index 0000000000..cfa384fc08
--- /dev/null
+++ b/test/files/neg/t6558b.check
@@ -0,0 +1,7 @@
+t6558b.scala:5: error: not found: type inargument
+ @inargument
+ ^
+t6558b.scala:11: error: not found: type infunction
+ @infunction
+ ^
+two errors found
diff --git a/test/files/neg/t6558b.scala b/test/files/neg/t6558b.scala
new file mode 100644
index 0000000000..2aa06f69cf
--- /dev/null
+++ b/test/files/neg/t6558b.scala
@@ -0,0 +1,15 @@
+class AnnotNotFound {
+ def foo(a: Any) = ()
+
+ foo {
+ @inargument
+ def foo = 0
+ foo
+ }
+
+ () => {
+ @infunction
+ def foo = 0
+ ()
+ }
+}
diff --git a/test/files/neg/t6667.check b/test/files/neg/t6667.check
new file mode 100644
index 0000000000..43313fa4fe
--- /dev/null
+++ b/test/files/neg/t6667.check
@@ -0,0 +1,13 @@
+t6667.scala:8: error: ambiguous implicit values:
+ both value inScope1 in object Test of type => C
+ and value inScope2 in object Test of type => C
+ match expected type C
+ implicitly[C]: Unit // C.companion was used; whereas the ambiguity should abort the implicit search.
+ ^
+t6667.scala:9: error: ambiguous implicit values:
+ both value inScope1 in object Test of type => C
+ and value inScope2 in object Test of type => C
+ match expected type C
+ implicitly[C] // ambiguity reported, rather than falling back to C.companion
+ ^
+two errors found
diff --git a/test/files/neg/t6667.scala b/test/files/neg/t6667.scala
new file mode 100644
index 0000000000..fb857ebd33
--- /dev/null
+++ b/test/files/neg/t6667.scala
@@ -0,0 +1,10 @@
+class C
+object C {
+ implicit def companion = new C
+}
+
+object Test {
+ implicit val inScope1, inScope2 = new C
+ implicitly[C]: Unit // C.companion was used; whereas the ambiguity should abort the implicit search.
+ implicitly[C] // ambiguity reported, rather than falling back to C.companion
+}
diff --git a/test/files/neg/t6667b.check b/test/files/neg/t6667b.check
new file mode 100644
index 0000000000..99cea9a47c
--- /dev/null
+++ b/test/files/neg/t6667b.check
@@ -0,0 +1,13 @@
+t6667b.scala:16: error: ambiguous implicit values:
+ both value a in object Test of type => Test.Box
+ and value b of type Test.Box
+ match expected type Test.Box
+ new Test()
+ ^
+t6667b.scala:19: error: ambiguous implicit values:
+ both value a in object Test of type => Test.Box
+ and value b of type Test.Box
+ match expected type Test.Box
+ new Test()
+ ^
+two errors found
diff --git a/test/files/neg/t6667b.scala b/test/files/neg/t6667b.scala
new file mode 100644
index 0000000000..4e64e1af17
--- /dev/null
+++ b/test/files/neg/t6667b.scala
@@ -0,0 +1,25 @@
+object Test {
+ abstract class Box {
+ val value: Int
+ }
+
+ implicit val a: Box = new Box {
+ val value= 1
+ }
+
+ def main(args: Array[String]) {
+ implicit val b: Box= new Box {
+ val value= 2
+ }
+
+ new Object {
+ new Test()
+ }
+ // compare with:
+ new Test()
+ }
+}
+
+class Test()(implicit x: Test.Box) {
+ println(x.value)
+}
diff --git a/test/files/neg/t667.check b/test/files/neg/t667.check
index d4367bc87b..e68c6dea00 100644
--- a/test/files/neg/t667.check
+++ b/test/files/neg/t667.check
@@ -1,4 +1,4 @@
-t667.scala:8: error: class Ni inherits itself
+t667.scala:8: error: illegal cyclic reference involving class Ni
class Ni extends super.Ni with Ni;
- ^
+ ^
one error found
diff --git a/test/files/neg/t6758.check b/test/files/neg/t6758.check
new file mode 100644
index 0000000000..2cdd6b8ae5
--- /dev/null
+++ b/test/files/neg/t6758.check
@@ -0,0 +1,28 @@
+t6758.scala:5: error: not found: type inargument
+ @inargument
+ ^
+t6758.scala:11: error: not found: type infunction
+ @infunction
+ ^
+t6758.scala:18: error: not found: type nested
+ @nested
+ ^
+t6758.scala:25: error: not found: type param
+ def func(@param x: Int): Int = 0
+ ^
+t6758.scala:28: error: not found: type typealias
+ @typealias
+ ^
+t6758.scala:32: error: not found: type classs
+ @classs
+ ^
+t6758.scala:35: error: not found: type module
+ @module
+ ^
+t6758.scala:38: error: not found: type typeparam
+ class D[@typeparam T]
+ ^
+t6758.scala:41: error: not found: type valueparam
+ @valueparam x: Any
+ ^
+9 errors found
diff --git a/test/files/neg/t6758.scala b/test/files/neg/t6758.scala
new file mode 100644
index 0000000000..acf333bf90
--- /dev/null
+++ b/test/files/neg/t6758.scala
@@ -0,0 +1,43 @@
+class AnnotNotFound {
+ def foo(a: Any) = ()
+
+ foo {
+ @inargument
+ def foo = 0
+ foo
+ }
+
+ () => {
+ @infunction
+ def foo = 0
+ ()
+ }
+
+ () => {
+ val bar: Int = {
+ @nested
+ val bar2: Int = 2
+ 2
+ }
+ ()
+ }
+
+ def func(@param x: Int): Int = 0
+
+ abstract class A {
+ @typealias
+ type B = Int
+ }
+
+ @classs
+ class C
+
+ @module
+ object D
+
+ class D[@typeparam T]
+
+ class E(
+ @valueparam x: Any
+ )
+}
diff --git a/test/files/neg/t877.check b/test/files/neg/t877.check
index 5f25bd439c..c3d4ab6584 100644
--- a/test/files/neg/t877.check
+++ b/test/files/neg/t877.check
@@ -1,7 +1,7 @@
t877.scala:3: error: Invalid literal number
trait Foo extends A(22A, Bug!) {}
^
-t877.scala:3: error: parents of traits may not have parameters
+t877.scala:3: error: ')' expected but eof found.
trait Foo extends A(22A, Bug!) {}
- ^
+ ^
two errors found
diff --git a/test/files/pos/attachments-typed-ident.check b/test/files/pos/attachments-typed-ident.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/pos/attachments-typed-ident.check
diff --git a/test/files/pos/attachments-typed-ident.flags b/test/files/pos/attachments-typed-ident.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/pos/attachments-typed-ident.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/pos/attachments-typed-ident/Impls_1.scala b/test/files/pos/attachments-typed-ident/Impls_1.scala
new file mode 100644
index 0000000000..cc40893a93
--- /dev/null
+++ b/test/files/pos/attachments-typed-ident/Impls_1.scala
@@ -0,0 +1,17 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object MyAttachment
+
+object Macros {
+ def impl(c: Context) = {
+ import c.universe._
+ val ident = Ident(newTermName("bar")) updateAttachment MyAttachment
+ assert(ident.attachments.get[MyAttachment.type].isDefined, ident.attachments)
+ val typed = c.typeCheck(ident)
+ assert(typed.attachments.get[MyAttachment.type].isDefined, typed.attachments)
+ c.Expr[Int](typed)
+ }
+
+ def foo = macro impl
+} \ No newline at end of file
diff --git a/test/files/pos/attachments-typed-ident/Macros_Test_2.scala b/test/files/pos/attachments-typed-ident/Macros_Test_2.scala
new file mode 100644
index 0000000000..37065ead4b
--- /dev/null
+++ b/test/files/pos/attachments-typed-ident/Macros_Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def bar = 2
+ Macros.foo
+} \ No newline at end of file
diff --git a/test/files/pos/strip-tvars-for-lubbasetypes.scala b/test/files/pos/strip-tvars-for-lubbasetypes.scala
new file mode 100644
index 0000000000..2be8625bae
--- /dev/null
+++ b/test/files/pos/strip-tvars-for-lubbasetypes.scala
@@ -0,0 +1,25 @@
+object Test {
+
+ implicit final class EqualOps[T](val x: T) extends AnyVal {
+ def ===[T1, Ph >: T <: T1, Ph2 >: Ph <: T1](other: T1): Boolean = x == other
+ def !!![T1, Ph2 >: Ph <: T1, Ph >: T <: T1](other: T1): Boolean = x == other
+ }
+
+ class A
+ class B extends A
+ class C extends A
+
+ val a = new A
+ val b = new B
+ val c = new C
+
+ val x1 = a === b
+ val x2 = b === a
+ val x3 = b === c // error, infers Object{} for T1
+ val x4 = b.===[A, B, B](c)
+
+ val x5 = b !!! c // always compiled due to the order of Ph2 and Ph
+
+
+
+}
diff --git a/test/files/pos/t1672.scala b/test/files/pos/t1672.scala
new file mode 100644
index 0000000000..5ee6bb1759
--- /dev/null
+++ b/test/files/pos/t1672.scala
@@ -0,0 +1,10 @@
+object Test {
+ @annotation.tailrec
+ def bar : Nothing = {
+ try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => bar
+ }
+ }
+}
diff --git a/test/files/pos/t5726.scala b/test/files/pos/t5726.scala
new file mode 100644
index 0000000000..b28ebd8674
--- /dev/null
+++ b/test/files/pos/t5726.scala
@@ -0,0 +1,17 @@
+import scala.language.dynamics
+
+class DynamicTest extends Dynamic {
+ def selectDynamic(name: String) = s"value of $name"
+ def updateDynamic(name: String)(value: Any) {
+ println(s"You have just updated property '$name' with value: $value")
+ }
+}
+
+object MyApp extends App {
+ def testing() {
+ val test = new DynamicTest
+ test.firstName = "John"
+ }
+
+ testing()
+}
diff --git a/test/files/pos/t5877.scala b/test/files/pos/t5877.scala
new file mode 100644
index 0000000000..c7827df99f
--- /dev/null
+++ b/test/files/pos/t5877.scala
@@ -0,0 +1,14 @@
+package foo {
+ class Foo
+
+ object Test {
+ new Foo().huzzah
+ }
+}
+
+package object foo {
+ // Crasher: No synthetics for method PimpedFoo2: synthetics contains
+ implicit class PimpedFoo2(value: Foo) {
+ def huzzah = ""
+ }
+}
diff --git a/test/files/pos/t5877b.scala b/test/files/pos/t5877b.scala
new file mode 100644
index 0000000000..6b8cbd473e
--- /dev/null
+++ b/test/files/pos/t5877b.scala
@@ -0,0 +1,13 @@
+package foo
+
+class Foo
+
+object Test {
+ new Foo().huzzah
+}
+
+object `package` {
+ implicit class PimpedFoo2(value: Foo) {
+ def huzzah = ""
+ }
+}
diff --git a/test/files/pos/t6547.flags b/test/files/pos/t6547.flags
new file mode 100644
index 0000000000..c9b68d70dc
--- /dev/null
+++ b/test/files/pos/t6547.flags
@@ -0,0 +1 @@
+-optimise
diff --git a/test/files/pos/t6547.scala b/test/files/pos/t6547.scala
new file mode 100644
index 0000000000..53bd798219
--- /dev/null
+++ b/test/files/pos/t6547.scala
@@ -0,0 +1,6 @@
+trait ConfigurableDefault[@specialized V] {
+ def fillArray(arr: Array[V], v: V) = (arr: Any) match {
+ case x: Array[Int] => null
+ case x: Array[Long] => v.asInstanceOf[Long]
+ }
+}
diff --git a/test/files/pos/t6551.scala b/test/files/pos/t6551.scala
index fb68663809..8bb396a19f 100644
--- a/test/files/pos/t6551.scala
+++ b/test/files/pos/t6551.scala
@@ -1,4 +1,4 @@
-import language.dynamics
+import scala.language.dynamics
object Test {
def main(args: Array[String]) {
diff --git a/test/files/pos/t6712.scala b/test/files/pos/t6712.scala
new file mode 100644
index 0000000000..3c96eb14fb
--- /dev/null
+++ b/test/files/pos/t6712.scala
@@ -0,0 +1,5 @@
+class H {
+ object O
+
+ def foo() { object O }
+}
diff --git a/test/files/pos/t6722.scala b/test/files/pos/t6722.scala
new file mode 100644
index 0000000000..576746c915
--- /dev/null
+++ b/test/files/pos/t6722.scala
@@ -0,0 +1,11 @@
+import scala.language.dynamics
+
+class Dyn extends Dynamic {
+ def selectDynamic(s: String): Dyn = new Dyn
+ def get[T]: T = null.asInstanceOf[T]
+}
+
+object Foo {
+ val dyn = new Dyn
+ dyn.foo.bar.baz.get[String]
+}
diff --git a/test/files/presentation/doc.check b/test/files/presentation/doc.check
new file mode 100755
index 0000000000..62b3bfc2e3
--- /dev/null
+++ b/test/files/presentation/doc.check
@@ -0,0 +1,48 @@
+body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text(
+))))))
+@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba)))))))))
+@version:
+@since:
+@todo:
+@note:
+@see:
+body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text(
+))))))
+@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba)))))))))
+@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012))))))
+@since:
+@todo:
+@note:
+@see:
+body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text(
+))))))
+@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba)))))))))
+@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012))))))
+@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10))))))
+@todo:
+@note:
+@see:
+body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text(
+))))))
+@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba)))))))))
+@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012))))))
+@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10))))))
+@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe)))))))
+@note:
+@see:
+body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text(
+))))))
+@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba)))))))))
+@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012))))))
+@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10))))))
+@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe)))))))
+@note:Body(List(Paragraph(Chain(List(Summary(Text(Don't inherit!)))))))
+@see:
+body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text(
+))))))
+@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba)))))))))
+@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012))))))
+@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10))))))
+@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe)))))))
+@note:Body(List(Paragraph(Chain(List(Summary(Text(Don't inherit!)))))))
+@see:Body(List(Paragraph(Chain(List(Summary(Text(some other method)))))))
diff --git a/test/files/presentation/doc.scala b/test/files/presentation/doc.scala
new file mode 100755
index 0000000000..4b0d6baa1f
--- /dev/null
+++ b/test/files/presentation/doc.scala
@@ -0,0 +1,71 @@
+import scala.tools.nsc.doc
+import scala.tools.nsc.doc.base.LinkTo
+import scala.tools.nsc.doc.base.comment._
+import scala.tools.nsc.interactive._
+import scala.tools.nsc.interactive.tests._
+import scala.tools.nsc.util._
+import scala.tools.nsc.io._
+
+object Test extends InteractiveTest {
+ override val settings: doc.Settings = docSettings
+
+ val tags = Seq(
+ "@example `\"abb\".permutations = Iterator(abb, bab, bba)`",
+ "@version 1.0, 09/07/2012",
+ "@since 2.10",
+ "@todo this method is unsafe",
+ "@note Don't inherit!",
+ "@see some other method"
+ )
+
+ val comment = "This is a test comment."
+ val caret = "<caret>"
+
+ def text(nTags: Int) =
+ """|/** %s
+ |
+ | * %s */
+ |trait Commented {}
+ |class User(c: %sCommented)""".stripMargin.format(comment, tags take nTags mkString "\n", caret)
+
+ override def main(args: Array[String]) {
+ val documenter = new Doc(settings) {
+ val global: compiler.type = compiler
+
+ def chooseLink(links: List[LinkTo]): LinkTo = links.head
+ }
+ for (i <- 1 to tags.length) {
+ val markedText = text(i)
+ val idx = markedText.indexOf(caret)
+ val fileText = markedText.substring(0, idx) + markedText.substring(idx + caret.length)
+ val source = sourceFiles(0)
+ val batch = new BatchSourceFile(source.file, fileText.toCharArray)
+ val reloadResponse = new Response[Unit]
+ compiler.askReload(List(batch), reloadResponse)
+ reloadResponse.get.left.toOption match {
+ case None =>
+ reporter.println("Couldn't reload")
+ case Some(_) =>
+ val treeResponse = new compiler.Response[compiler.Tree]
+ val pos = compiler.rangePos(batch, idx, idx, idx)
+ compiler.askTypeAt(pos, treeResponse)
+ treeResponse.get.left.toOption match {
+ case Some(tree) =>
+ val sym = tree.tpe.typeSymbol
+ documenter.retrieve(sym, sym.owner) match {
+ case Some(HtmlResult(comment)) =>
+ import comment._
+ val tags: List[(String, Iterable[Body])] =
+ List(("@example", example), ("@version", version), ("@since", since.toList), ("@todo", todo), ("@note", note), ("@see", see))
+ val str = ("body:" + body + "\n") +
+ tags.map{ case (name, bodies) => name + ":" + bodies.mkString("\n") }.mkString("\n")
+ reporter.println(str)
+ case Some(_) => reporter.println("Got unexpected result")
+ case None => reporter.println("Got no result")
+ }
+ case None => reporter.println("Couldn't find a typedTree")
+ }
+ }
+ }
+ }
+}
diff --git a/test/files/presentation/doc/src/Test.scala b/test/files/presentation/doc/src/Test.scala
new file mode 100755
index 0000000000..fcc1554994
--- /dev/null
+++ b/test/files/presentation/doc/src/Test.scala
@@ -0,0 +1 @@
+object Test \ No newline at end of file
diff --git a/test/files/presentation/memory-leaks/MemoryLeaksTest.scala b/test/files/presentation/memory-leaks/MemoryLeaksTest.scala
index a5533a623a..159097cc10 100644
--- a/test/files/presentation/memory-leaks/MemoryLeaksTest.scala
+++ b/test/files/presentation/memory-leaks/MemoryLeaksTest.scala
@@ -5,6 +5,7 @@ import java.util.Calendar
import scala.tools.nsc.interactive.tests._
import scala.tools.nsc.util._
import scala.tools.nsc.io._
+import scala.tools.nsc.doc
/** This test runs the presentation compiler on the Scala compiler project itself and records memory consumption.
*
@@ -24,6 +25,8 @@ import scala.tools.nsc.io._
object Test extends InteractiveTest {
final val mega = 1024 * 1024
+ override val settings: doc.Settings = docSettings
+
override def execute(): Unit = memoryConsumptionTest()
def batchSource(name: String) =
@@ -120,4 +123,4 @@ object Test extends InteractiveTest {
r.totalMemory() - r.freeMemory()
}
-} \ No newline at end of file
+}
diff --git a/test/files/run/idempotency-case-classes.check b/test/files/run/idempotency-case-classes.check
new file mode 100644
index 0000000000..d2fb8169cb
--- /dev/null
+++ b/test/files/run/idempotency-case-classes.check
@@ -0,0 +1,52 @@
+C(2,3)
+()
+{
+ case class C extends AnyRef with Product with Serializable {
+ <caseaccessor> <paramaccessor> private[this] val x: Int = _;
+ <stable> <caseaccessor> <accessor> <paramaccessor> def x: Int = C.this.x;
+ <caseaccessor> <paramaccessor> private[this] val y: Int = _;
+ <stable> <caseaccessor> <accessor> <paramaccessor> def y: Int = C.this.y;
+ def <init>(x: Int, y: Int): C = {
+ C.super.<init>();
+ ()
+ };
+ <synthetic> def copy(x: Int = x, y: Int = y): C = new C(x, y);
+ <synthetic> def copy$default$1: Int = C.this.x;
+ <synthetic> def copy$default$2: Int = C.this.y;
+ override <synthetic> def productPrefix: String = "C";
+ <synthetic> def productArity: Int = 2;
+ <synthetic> def productElement(x$1: Int): Any = x$1 match {
+ case 0 => C.this.x
+ case 1 => C.this.y
+ case _ => throw new IndexOutOfBoundsException(x$1.toString())
+ };
+ override <synthetic> def productIterator: Iterator[Any] = runtime.this.ScalaRunTime.typedProductIterator[Any](C.this);
+ <synthetic> def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[C]();
+ override <synthetic> def hashCode(): Int = {
+ <synthetic> var acc: Int = -889275714;
+ acc = Statics.this.mix(acc, x);
+ acc = Statics.this.mix(acc, y);
+ Statics.this.finalizeHash(acc, 2)
+ };
+ override <synthetic> def toString(): String = ScalaRunTime.this._toString(C.this);
+ override <synthetic> def equals(x$1: Any): Boolean = C.this.eq(x$1.asInstanceOf[Object]).||(x$1.isInstanceOf[C].&&({
+ <synthetic> val C$1: C = x$1.asInstanceOf[C];
+ C.this.x.==(C$1.x).&&(C.this.y.==(C$1.y)).&&(C$1.canEqual(C.this))
+ }))
+ };
+ <synthetic> object C extends scala.runtime.AbstractFunction2[Int,Int,C] with Serializable {
+ def <init>(): C.type = {
+ C.super.<init>();
+ ()
+ };
+ final override def toString(): String = "C";
+ case <synthetic> def apply(x: Int, y: Int): C = new C(x, y);
+ case <synthetic> def unapply(x$0: C): Option[(Int, Int)] = if (x$0.==(null))
+ scala.this.None
+ else
+ Some.apply[(Int, Int)](Tuple2.apply[Int, Int](x$0.x, x$0.y));
+ <synthetic> private def readResolve(): Object = C
+ };
+ scala.this.Predef.println(C.apply(2, 3))
+}
+error!
diff --git a/test/files/run/idempotency-case-classes.scala b/test/files/run/idempotency-case-classes.scala
new file mode 100644
index 0000000000..4da8393cb6
--- /dev/null
+++ b/test/files/run/idempotency-case-classes.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val casee = reify {
+ case class C(x: Int, y: Int)
+ println(C(2, 3))
+ }
+ println(casee.eval)
+ val tb = cm.mkToolBox()
+ val tcasee = tb.typeCheck(casee.tree)
+ println(tcasee)
+ val rtcasee = tb.resetAllAttrs(tcasee)
+ try {
+ println(tb.eval(rtcasee))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-5467
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-extractors.check b/test/files/run/idempotency-extractors.check
new file mode 100644
index 0000000000..fcd50faa79
--- /dev/null
+++ b/test/files/run/idempotency-extractors.check
@@ -0,0 +1,5 @@
+2
+2 match {
+ case Test.this.Extractor.unapply(<unapply-selector>) <unapply> ((x @ _)) => x
+}
+error!
diff --git a/test/files/run/idempotency-extractors.scala b/test/files/run/idempotency-extractors.scala
new file mode 100644
index 0000000000..fe033295f5
--- /dev/null
+++ b/test/files/run/idempotency-extractors.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ object Extractor { def unapply(x: Int): Option[Int] = Some(x) }
+ val extractor = reify {
+ 2 match { case Extractor(x) => x }
+ }
+ println(extractor.eval)
+ val tb = cm.mkToolBox()
+ val textractor = tb.typeCheck(extractor.tree)
+ println(textractor)
+ val rtextractor = tb.resetAllAttrs(textractor)
+ try {
+ println(tb.eval(rtextractor))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-5465
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-labels.check b/test/files/run/idempotency-labels.check
new file mode 100644
index 0000000000..8709efeb43
--- /dev/null
+++ b/test/files/run/idempotency-labels.check
@@ -0,0 +1,15 @@
+2
+{
+ var x: Int = 0;
+ while$1(){
+ if (x.<(2))
+ {
+ x = x.+(1);
+ while$1()
+ }
+ else
+ ()
+ };
+ x
+}
+2
diff --git a/test/files/run/idempotency-labels.scala b/test/files/run/idempotency-labels.scala
new file mode 100644
index 0000000000..82d009751a
--- /dev/null
+++ b/test/files/run/idempotency-labels.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val label = reify {
+ var x = 0
+ while (x < 2) { x += 1 }
+ x
+ }
+ println(label.eval)
+ val tb = cm.mkToolBox()
+ val tlabel = tb.typeCheck(label.tree)
+ println(tlabel)
+ val rtlabel = tb.resetAllAttrs(tlabel)
+ try {
+ println(tb.eval(rtlabel))
+ } catch {
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-lazy-vals.check b/test/files/run/idempotency-lazy-vals.check
new file mode 100644
index 0000000000..4dcbf96184
--- /dev/null
+++ b/test/files/run/idempotency-lazy-vals.check
@@ -0,0 +1,23 @@
+6
+{
+ class C extends AnyRef {
+ def <init>(): C = {
+ C.super.<init>();
+ ()
+ };
+ lazy private[this] val x: Int = _;
+ <stable> <accessor> lazy def x: Int = {
+ C.this.x = 2;
+ C.this.x
+ };
+ lazy private[this] val y: Int = _;
+ implicit <stable> <accessor> lazy def y: Int = {
+ C.this.y = 3;
+ C.this.y
+ }
+ };
+ val c: C = new C();
+ import c._;
+ c.x.*(scala.this.Predef.implicitly[Int](c.y))
+}
+error!
diff --git a/test/files/run/idempotency-lazy-vals.scala b/test/files/run/idempotency-lazy-vals.scala
new file mode 100644
index 0000000000..3531f9ff4b
--- /dev/null
+++ b/test/files/run/idempotency-lazy-vals.scala
@@ -0,0 +1,27 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val lazee = reify {
+ class C {
+ lazy val x = 2
+ implicit lazy val y = 3
+ }
+ val c = new C()
+ import c._
+ x * implicitly[Int]
+ }
+ println(lazee.eval)
+ val tb = cm.mkToolBox()
+ val tlazee = tb.typeCheck(lazee.tree)
+ println(tlazee)
+ val rtlazee = tb.resetAllAttrs(tlazee)
+ try {
+ println(tb.eval(rtlazee))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-5466
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-partial-functions.check b/test/files/run/idempotency-partial-functions.check
new file mode 100644
index 0000000000..5c8a411655
--- /dev/null
+++ b/test/files/run/idempotency-partial-functions.check
@@ -0,0 +1,2 @@
+error!!
+error!
diff --git a/test/files/run/idempotency-partial-functions.scala b/test/files/run/idempotency-partial-functions.scala
new file mode 100644
index 0000000000..dd5f1167f1
--- /dev/null
+++ b/test/files/run/idempotency-partial-functions.scala
@@ -0,0 +1,25 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val partials = reify {
+ List((false,true)) collect { case (x,true) => x }
+ }
+ try {
+ println(partials.eval)
+ } catch {
+ case _: ToolBoxError => println("error!!")
+ }
+ try {
+ val tb = cm.mkToolBox()
+ val tpartials = tb.typeCheck(partials.tree)
+ println(tpartials)
+ val rtpartials = tb.resetAllAttrs(tpartials)
+ println(tb.eval(rtpartials))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-6187
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-this.check b/test/files/run/idempotency-this.check
new file mode 100644
index 0000000000..08738c4565
--- /dev/null
+++ b/test/files/run/idempotency-this.check
@@ -0,0 +1,4 @@
+List()
+immutable.this.List.apply[String]("")
+Apply(TypeApply(Select(Select(This(newTypeName("immutable")), scala.collection.immutable.List), newTermName("apply")), List(TypeTree().setOriginal(Ident(newTypeName("String"))))), List(Literal(Constant(""))))
+error!
diff --git a/test/files/run/idempotency-this.scala b/test/files/run/idempotency-this.scala
new file mode 100644
index 0000000000..5cd4226326
--- /dev/null
+++ b/test/files/run/idempotency-this.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val thiss = reify {
+ List[String]("")
+ }
+ println(thiss.eval)
+ val tb = cm.mkToolBox()
+ val tthiss = tb.typeCheck(thiss.tree)
+ println(tthiss)
+ println(showRaw(tthiss))
+ val rtthiss = tb.resetAllAttrs(tthiss)
+ try {
+ println(tb.eval(rtthiss))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-5705
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check
index e786c780d6..45db7c3a15 100644
--- a/test/files/run/inline-ex-handlers.check
+++ b/test/files/run/inline-ex-handlers.check
@@ -47,7 +47,7 @@
< 106 LOAD_LOCAL(value message)
---
> ? LOAD_LOCAL(value x5)
-> ? CALL_METHOD MyException.message (dynamic)
+> 106 CALL_METHOD MyException.message (dynamic)
502c504
< blocks: [1,2,3,4,6,7,8,9,10]
---
@@ -162,12 +162,12 @@
< 176 LOAD_LOCAL(value message)
---
> ? LOAD_LOCAL(value x5)
-> ? CALL_METHOD MyException.message (dynamic)
+> 176 CALL_METHOD MyException.message (dynamic)
783c833,834
< 177 LOAD_LOCAL(value message)
---
> ? LOAD_LOCAL(value x5)
-> ? CALL_METHOD MyException.message (dynamic)
+> 177 CALL_METHOD MyException.message (dynamic)
785c836,837
< 177 THROW(MyException)
---
@@ -194,12 +194,12 @@
< 181 LOAD_LOCAL(value message)
---
> ? LOAD_LOCAL(value x5)
-> ? CALL_METHOD MyException.message (dynamic)
+> 181 CALL_METHOD MyException.message (dynamic)
822c878,879
< 182 LOAD_LOCAL(value message)
---
> ? LOAD_LOCAL(value x5)
-> ? CALL_METHOD MyException.message (dynamic)
+> 182 CALL_METHOD MyException.message (dynamic)
824c881,882
< 182 THROW(MyException)
---
@@ -260,7 +260,7 @@
< 127 LOAD_LOCAL(value message)
---
> ? LOAD_LOCAL(value x5)
-> ? CALL_METHOD MyException.message (dynamic)
+> 127 CALL_METHOD MyException.message (dynamic)
966c1042
< catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19) starting at: 3
---
@@ -299,7 +299,7 @@
< 154 LOAD_LOCAL(value message)
---
> ? LOAD_LOCAL(value x5)
-> ? CALL_METHOD MyException.message (dynamic)
+> 154 CALL_METHOD MyException.message (dynamic)
1275c1354
< blocks: [1,2,3,4,5,7]
---
@@ -354,22 +354,23 @@
< 213 LOAD_LOCAL(value message)
---
> ? LOAD_LOCAL(value x5)
-> ? CALL_METHOD MyException.message (dynamic)
+> 213 CALL_METHOD MyException.message (dynamic)
1470c1560
< blocks: [1,2,3,4,5,7]
---
> blocks: [1,2,3,4,5,7,8]
-1494c1584,1591
+1494c1584,1585
< 58 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
> ? JUMP 8
->
+1495a1587,1592
> 8:
> 62 LOAD_MODULE object Predef
> 62 CONSTANT("RuntimeException")
> 62 CALL_METHOD scala.Predef.println (dynamic)
> 62 JUMP 2
+>
1543c1640
< blocks: [1,2,3,4]
---
diff --git a/test/files/run/macro-abort-fresh/Test_2.scala b/test/files/run/macro-abort-fresh/Test_2.scala
index 15c498efb0..0b9986e9f6 100644
--- a/test/files/run/macro-abort-fresh/Test_2.scala
+++ b/test/files/run/macro-abort-fresh/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Select(Ident("Macros"), newTermName("foo"))
+ val tree = Select(Ident(newTermName("Macros")), newTermName("foo"))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class-class/Impls_1.scala b/test/files/run/macro-declared-in-class-class/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-class-class/Impls_1.scala
+++ b/test/files/run/macro-declared-in-class-class/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class-object/Impls_1.scala b/test/files/run/macro-declared-in-class-object/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-class-object/Impls_1.scala
+++ b/test/files/run/macro-declared-in-class-object/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class/Impls_1.scala b/test/files/run/macro-declared-in-class/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-class/Impls_1.scala
+++ b/test/files/run/macro-declared-in-class/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala
index d506de4252..837b306976 100644
--- a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala
+++ b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, newTermName("x")), newTermName("toInt")))))
+ val body = Block(List(printPrefix), Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, newTermName("x")), newTermName("toInt")))))
c.Expr[Option[Int]](body)
}
}
diff --git a/test/files/run/macro-declared-in-method/Impls_1.scala b/test/files/run/macro-declared-in-method/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-method/Impls_1.scala
+++ b/test/files/run/macro-declared-in-method/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object-class/Impls_1.scala b/test/files/run/macro-declared-in-object-class/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-object-class/Impls_1.scala
+++ b/test/files/run/macro-declared-in-object-class/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object-object/Impls_1.scala b/test/files/run/macro-declared-in-object-object/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-object-object/Impls_1.scala
+++ b/test/files/run/macro-declared-in-object-object/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object/Impls_1.scala b/test/files/run/macro-declared-in-object/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-object/Impls_1.scala
+++ b/test/files/run/macro-declared-in-object/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-package-object/Impls_1.scala b/test/files/run/macro-declared-in-package-object/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-package-object/Impls_1.scala
+++ b/test/files/run/macro-declared-in-package-object/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-refinement/Impls_1.scala b/test/files/run/macro-declared-in-refinement/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-refinement/Impls_1.scala
+++ b/test/files/run/macro-declared-in-refinement/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-trait/Impls_1.scala b/test/files/run/macro-declared-in-trait/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-trait/Impls_1.scala
+++ b/test/files/run/macro-declared-in-trait/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-b/Test_2.scala b/test/files/run/macro-def-infer-return-type-b/Test_2.scala
index ef2920a432..ea0fd4bbff 100644
--- a/test/files/run/macro-def-infer-return-type-b/Test_2.scala
+++ b/test/files/run/macro-def-infer-return-type-b/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42))))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-expand-implicit-argument/Macros_1.scala b/test/files/run/macro-expand-implicit-argument/Macros_1.scala
index b1665256cd..d9fd5b8cb0 100644
--- a/test/files/run/macro-expand-implicit-argument/Macros_1.scala
+++ b/test/files/run/macro-expand-implicit-argument/Macros_1.scala
@@ -43,16 +43,16 @@ object Macros {
val n = as.length
val arr = newTermName("arr")
- val create = Apply(Select(ct.tree, "newArray"), List(const(n)))
+ val create = Apply(Select(ct.tree, newTermName("newArray")), List(const(n)))
val arrtpe = TypeTree(implicitly[c.WeakTypeTag[Array[A]]].tpe)
val valdef = ValDef(Modifiers(), arr, arrtpe, create)
val updates = (0 until n).map {
- i => Apply(Select(Ident(arr), "update"), List(const(i), as(i).tree))
+ i => Apply(Select(Ident(arr), newTermName("update")), List(const(i), as(i).tree))
}
- val exprs = Seq(valdef) ++ updates ++ Seq(Ident(arr))
- val block = Block(exprs:_*)
+ val exprs = (Seq(valdef) ++ updates ++ Seq(Ident(arr))).toList
+ val block = Block(exprs.init, exprs.last)
c.Expr[Array[A]](block)
}
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala
index 16d2c1e6ac..c832826d64 100644
--- a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala
@@ -6,7 +6,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Typed(Apply(Ident(definitions.ListModule), List(Literal(Constant(1)), Literal(Constant(2)))), Ident(tpnme.WILDCARD_STAR))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Typed(Apply(Ident(definitions.ListModule), List(Literal(Constant(1)), Literal(Constant(2)))), Ident(tpnme.WILDCARD_STAR))))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
} \ No newline at end of file
diff --git a/test/files/run/macro-impl-default-params/Impls_Macros_1.scala b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala
index db77b1923a..7c40045c0f 100644
--- a/test/files/run/macro-impl-default-params/Impls_Macros_1.scala
+++ b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala
@@ -6,11 +6,11 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val U = implicitly[c.WeakTypeTag[U]]
- val body = Block(
+ val body = Block(List(
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))),
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.staticType)))),
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix tree is: " + prefix.tree.tpe)))),
- Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + U.tpe)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + U.tpe))))),
Literal(Constant(())))
c.Expr[Unit](body)
}
diff --git a/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala
index 537f1db8c6..56c23f5faf 100644
--- a/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala
+++ b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala
@@ -3,8 +3,8 @@ import scala.reflect.macros.{Context => Ctx}
object Impls {
def foo(unconventionalName: Ctx)(x: unconventionalName.Expr[Int]) = {
import unconventionalName.universe._
- val body = Block(
- Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo...")))),
+ val body = Block(List(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo..."))))),
Literal(Constant(())))
unconventionalName.Expr[Unit](body)
}
diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala
index 15c498efb0..0b9986e9f6 100644
--- a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala
+++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Select(Ident("Macros"), newTermName("foo"))
+ val tree = Select(Ident(newTermName("Macros")), newTermName("foo"))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
} \ No newline at end of file
diff --git a/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala
index 405ae7024f..fb0d55208c 100644
--- a/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala
+++ b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala
@@ -3,7 +3,7 @@ import scala.reflect.macros.{Context => Ctx}
object Impls {
def foo(c: Ctx) = {
import c.universe._
- val body = Ident("IDoNotExist")
+ val body = Ident(newTermName("IDoNotExist"))
c.Expr[Int](body)
}
}
diff --git a/test/files/run/macro-invalidret-nontypeable/Test_2.scala b/test/files/run/macro-invalidret-nontypeable/Test_2.scala
index 15c498efb0..0daee49a08 100644
--- a/test/files/run/macro-invalidret-nontypeable/Test_2.scala
+++ b/test/files/run/macro-invalidret-nontypeable/Test_2.scala
@@ -1,8 +1,8 @@
-object Test extends App {
+ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Select(Ident("Macros"), newTermName("foo"))
+ val tree = Select(Ident(newTermName("Macros")), newTermName("foo"))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
} \ No newline at end of file
diff --git a/test/files/run/macro-invalidusage-badret/Test_2.scala b/test/files/run/macro-invalidusage-badret/Test_2.scala
index f3a76f3fff..5cb0be5ddd 100644
--- a/test/files/run/macro-invalidusage-badret/Test_2.scala
+++ b/test/files/run/macro-invalidusage-badret/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Typed(Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))), Ident(newTypeName("String")))
+ val tree = Typed(Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42)))), Ident(newTypeName("String")))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala b/test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala
index c91fd7d380..e453d0b70c 100644
--- a/test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala
+++ b/test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Select(Ident("Macros"), newTermName("foo"))
+ val tree = Select(Ident(newTermName("Macros")), newTermName("foo"))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-invalidusage-partialapplication/Test_2.scala b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala
index cbfee725e2..dc48c127f4 100644
--- a/test/files/run/macro-invalidusage-partialapplication/Test_2.scala
+++ b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(40))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(40))))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala
index 373c6a6fca..2e64c01e35 100644
--- a/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala
+++ b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala
@@ -2,6 +2,6 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42))))
println(cm.mkToolBox().eval(tree))
}
diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala
index adecfcff17..70560009b1 100644
--- a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala
+++ b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala
@@ -11,10 +11,10 @@ object Test extends App {
val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo"))
val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.toType), EmptyTree)
val macrodef = DefDef(Modifiers(MACRO), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody)
- val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())))
+ val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(()))))
val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef)))
- val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
- val tree = Block(macrodef, module, macroapp)
+ val macroapp = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Block(List(macrodef, module), macroapp)
val toolbox = cm.mkToolBox(options = "-language:experimental.macros")
println(toolbox.eval(tree))
}
diff --git a/test/files/run/macro-reify-freevars/Test_2.scala b/test/files/run/macro-reify-freevars/Test_2.scala
index e24758cfb4..7af9d89bdb 100644
--- a/test/files/run/macro-reify-freevars/Test_2.scala
+++ b/test/files/run/macro-reify-freevars/Test_2.scala
@@ -2,8 +2,8 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val q = New(AppliedTypeTree(Select(Select(Select(Ident("scala"), newTermName("collection")), newTermName("slick")), newTypeName("Queryable")), List(Ident("Int"))))
- val x = ValDef(NoMods, newTermName("x"), Ident("Int"), EmptyTree)
+ val q = New(AppliedTypeTree(Select(Select(Select(Ident(newTermName("scala")), newTermName("collection")), newTermName("slick")), newTypeName("Queryable")), List(Ident(newTermName("Int")))))
+ val x = ValDef(NoMods, newTermName("x"), Ident(newTermName("Int")), EmptyTree)
val fn = Function(List(x), Apply(Select(Ident(newTermName("x")), newTermName("$plus")), List(Literal(Constant("5")))))
val tree = Apply(Select(q, newTermName("map")), List(fn))
try cm.mkToolBox().eval(tree)
diff --git a/test/files/run/macro-reify-splice-outside-reify/Test_2.scala b/test/files/run/macro-reify-splice-outside-reify/Test_2.scala
index 8f96ea199d..54bd03fcd2 100644
--- a/test/files/run/macro-reify-splice-outside-reify/Test_2.scala
+++ b/test/files/run/macro-reify-splice-outside-reify/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42))))
try println(cm.mkToolBox().eval(tree))
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-reify-tagless-a/Test_2.scala b/test/files/run/macro-reify-tagless-a/Test_2.scala
index 1bb3945ece..584c4bdf5b 100644
--- a/test/files/run/macro-reify-tagless-a/Test_2.scala
+++ b/test/files/run/macro-reify-tagless-a/Test_2.scala
@@ -6,9 +6,9 @@ object Test extends App {
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass)))
- val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world"))))
+ val rhs = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant("hello world"))))
val list = ValDef(NoMods, newTermName("list"), tpt, rhs)
- val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name))))
+ val tree = Block(List(list), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name))))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/reify_renamed_term_basic.check b/test/files/run/reify_renamed_term_basic.check
new file mode 100644
index 0000000000..e78f94fffd
--- /dev/null
+++ b/test/files/run/reify_renamed_term_basic.check
@@ -0,0 +1 @@
+((),(),())
diff --git a/test/files/run/reify_renamed_term_basic.scala b/test/files/run/reify_renamed_term_basic.scala
new file mode 100644
index 0000000000..cd76def395
--- /dev/null
+++ b/test/files/run/reify_renamed_term_basic.scala
@@ -0,0 +1,20 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object A {
+ object B {
+ val c = ()
+ }
+}
+
+object Test extends App {
+ import A.{B => X}
+ import A.B.{c => y}
+ import X.{c => z}
+
+ val expr = reify (
+ X.c, y, z
+ )
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_term_local_to_reifee.check b/test/files/run/reify_renamed_term_local_to_reifee.check
new file mode 100644
index 0000000000..e78f94fffd
--- /dev/null
+++ b/test/files/run/reify_renamed_term_local_to_reifee.check
@@ -0,0 +1 @@
+((),(),())
diff --git a/test/files/run/reify_renamed_term_local_to_reifee.scala b/test/files/run/reify_renamed_term_local_to_reifee.scala
new file mode 100644
index 0000000000..1860316a5b
--- /dev/null
+++ b/test/files/run/reify_renamed_term_local_to_reifee.scala
@@ -0,0 +1,20 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object A {
+ object B {
+ val c = ()
+ }
+}
+
+object Test extends App {
+ val expr = reify {
+ import A.{B => X}
+ import A.B.{c => y}
+ import X.{c => z}
+
+ (X.c, y, z)
+ }
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_term_overloaded_method.check b/test/files/run/reify_renamed_term_overloaded_method.check
new file mode 100644
index 0000000000..48082f72f0
--- /dev/null
+++ b/test/files/run/reify_renamed_term_overloaded_method.check
@@ -0,0 +1 @@
+12
diff --git a/test/files/run/reify_renamed_term_overloaded_method.scala b/test/files/run/reify_renamed_term_overloaded_method.scala
new file mode 100644
index 0000000000..3ef442d203
--- /dev/null
+++ b/test/files/run/reify_renamed_term_overloaded_method.scala
@@ -0,0 +1,17 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object O {
+ def show(i: Int) = i.toString
+ def show(s: String) = s
+}
+
+object Test extends App {
+ import O.{show => s}
+
+ val expr = reify {
+ s("1") + s(2)
+ }
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_term_si5841.check b/test/files/run/reify_renamed_term_si5841.check
new file mode 100644
index 0000000000..6031277b76
--- /dev/null
+++ b/test/files/run/reify_renamed_term_si5841.check
@@ -0,0 +1 @@
+class scala.reflect.runtime.JavaUniverse
diff --git a/test/files/run/reify_renamed_term_si5841.scala b/test/files/run/reify_renamed_term_si5841.scala
new file mode 100644
index 0000000000..ef18d650bf
--- /dev/null
+++ b/test/files/run/reify_renamed_term_si5841.scala
@@ -0,0 +1,7 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ println(reify{ru}.eval.getClass)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_type_basic.check b/test/files/run/reify_renamed_type_basic.check
new file mode 100644
index 0000000000..6a452c185a
--- /dev/null
+++ b/test/files/run/reify_renamed_type_basic.check
@@ -0,0 +1 @@
+()
diff --git a/test/files/run/reify_renamed_type_basic.scala b/test/files/run/reify_renamed_type_basic.scala
new file mode 100644
index 0000000000..23729e5c54
--- /dev/null
+++ b/test/files/run/reify_renamed_type_basic.scala
@@ -0,0 +1,16 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object O {
+ type A = Unit
+}
+
+object Test extends App {
+ import O.{A => X}
+
+ def expr = reify {
+ val a: X = ()
+ }
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_type_local_to_reifee.check b/test/files/run/reify_renamed_type_local_to_reifee.check
new file mode 100644
index 0000000000..6a452c185a
--- /dev/null
+++ b/test/files/run/reify_renamed_type_local_to_reifee.check
@@ -0,0 +1 @@
+()
diff --git a/test/files/run/reify_renamed_type_local_to_reifee.scala b/test/files/run/reify_renamed_type_local_to_reifee.scala
new file mode 100644
index 0000000000..ed1bad239e
--- /dev/null
+++ b/test/files/run/reify_renamed_type_local_to_reifee.scala
@@ -0,0 +1,24 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object O {
+ type A = Unit
+}
+
+object Test extends App {
+ val expr = reify {
+ import O.{A => X}
+
+ val a: X = ()
+
+ object P {
+ type B = Unit
+ }
+
+ import P.{B => Y}
+
+ val b: Y = ()
+ }
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_type_spliceable.check b/test/files/run/reify_renamed_type_spliceable.check
new file mode 100644
index 0000000000..6a452c185a
--- /dev/null
+++ b/test/files/run/reify_renamed_type_spliceable.check
@@ -0,0 +1 @@
+()
diff --git a/test/files/run/reify_renamed_type_spliceable.scala b/test/files/run/reify_renamed_type_spliceable.scala
new file mode 100644
index 0000000000..9c2cff5199
--- /dev/null
+++ b/test/files/run/reify_renamed_type_spliceable.scala
@@ -0,0 +1,21 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+abstract class C {
+ type T >: Null
+}
+
+object Test extends App {
+ def foo(c: C) = {
+ import c.{T => U}
+ reify {
+ val x: U = null
+ }
+ }
+
+ val expr = foo(new C {
+ type T = AnyRef
+ })
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/t1672.scala b/test/files/run/t1672.scala
new file mode 100644
index 0000000000..ee025b9031
--- /dev/null
+++ b/test/files/run/t1672.scala
@@ -0,0 +1,28 @@
+object Test {
+ @annotation.tailrec
+ def bar(i : Int) : Int = {
+ if (i == 0) 0
+ else try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => bar(i - 1)
+ }
+ }
+
+ @annotation.tailrec
+ def nestedTry1(i : Int) : Int = {
+ if (i == 0) 0
+ else try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable =>
+ try { ??? } catch { case _: Throwable => nestedTry1(i - 1) }
+ }
+ }
+
+ def main(args: Array[String]) {
+ assert(bar(2) == 0)
+
+ assert(nestedTry1(2) == 0)
+ }
+}
diff --git a/test/files/run/t5064.check b/test/files/run/t5064.check
index 077006abd9..61ccfd16e7 100644
--- a/test/files/run/t5064.check
+++ b/test/files/run/t5064.check
@@ -1,6 +1,6 @@
-[12] T5064.super.<init>()
-[12] T5064.super.<init>
-[12] this
+[53] T5064.super.<init>()
+[53] T5064.super.<init>
+[53] this
[16:23] immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1}))
[16:20] immutable.this.List.apply
<16:20> immutable.this.List
diff --git a/test/files/run/t5603.check b/test/files/run/t5603.check
index 5127d3c1c7..3b2eb55313 100644
--- a/test/files/run/t5603.check
+++ b/test/files/run/t5603.check
@@ -12,7 +12,7 @@
[95:101]<paramaccessor> private[this] val i: [98:101]Int = _;
<119:139>def <init>([95]i: [98]Int) = <119:139>{
<119:139>val nameElse = <134:139>"Bob";
- [94][94][94]super.<init>();
+ [NoPosition][NoPosition][NoPosition]super.<init>();
[94]()
};
[168:184]val name = [179:184]"avc";
@@ -20,7 +20,7 @@
};
[215:241]object Test extends [227:241][235:238]App {
[227]def <init>() = [227]{
- [227][227][227]super.<init>();
+ [NoPosition][NoPosition][NoPosition]super.<init>();
[227]()
};
[NoPosition]<empty>
diff --git a/test/files/run/t5733.check b/test/files/run/t5733.check
new file mode 100644
index 0000000000..e697046a94
--- /dev/null
+++ b/test/files/run/t5733.check
@@ -0,0 +1,2 @@
+Running ABTest asserts
+Done
diff --git a/test/files/run/t5733.scala b/test/files/run/t5733.scala
new file mode 100644
index 0000000000..360264e4ed
--- /dev/null
+++ b/test/files/run/t5733.scala
@@ -0,0 +1,53 @@
+import scala.language.dynamics
+
+object A extends Dynamic {
+ var a = "a"
+
+ def selectDynamic(method:String): String = a
+
+ def updateDynamic(method:String)(v:String) { a = v }
+}
+
+class B extends Dynamic {
+ var b = "b"
+
+ def selectDynamic(method:String): String = b
+
+ def updateDynamic(method:String)(v:String) { b = v }
+}
+
+object Test extends App {
+ assert( A.foo == "a" )
+ assert( A.bar == "a" )
+ A.aaa = "aaa"
+ assert( A.bar == "aaa" )
+
+ val b = new B
+ assert( b.foo == "b" )
+ assert( b.bar == "b" )
+ b.bbb = "bbb"
+ assert( b.bar == "bbb" )
+
+ {
+ println("Running ABTest asserts")
+ A.a = "a"
+ (new ABTest).test()
+ }
+
+ println("Done")
+}
+
+class ABTest {
+ def test() {
+ assert( A.foo == "a" )
+ assert( A.bar == "a" )
+ A.aaa = "aaa"
+ assert( A.bar == "aaa" )
+
+ val b = new B
+ assert( b.foo == "b" )
+ assert( b.bar == "b" )
+ b.bbb = "bbb"
+ assert( b.bar == "bbb" )
+ }
+}
diff --git a/test/files/run/t5789.check b/test/files/run/t5789.check
new file mode 100644
index 0000000000..ea8d4966b1
--- /dev/null
+++ b/test/files/run/t5789.check
@@ -0,0 +1,14 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> val n = 2
+n: Int = 2
+
+scala> () => n
+res0: () => Int = <function0>
+
+scala>
+
+scala>
diff --git a/test/files/run/t5789.scala b/test/files/run/t5789.scala
new file mode 100644
index 0000000000..461f6a4aae
--- /dev/null
+++ b/test/files/run/t5789.scala
@@ -0,0 +1,14 @@
+
+import scala.tools.nsc._
+import interpreter.ILoop
+import scala.tools.partest.ReplTest
+
+
+object Test extends ReplTest {
+ override def extraSettings = "-Yinline"
+ def code = """
+ val n = 2
+ () => n
+ """
+}
+
diff --git a/test/files/run/t5894.scala b/test/files/run/t5894.scala
new file mode 100644
index 0000000000..abeec32365
--- /dev/null
+++ b/test/files/run/t5894.scala
@@ -0,0 +1,17 @@
+import language.experimental.macros
+
+class Test
+
+object Test {
+ def foo = macro fooImpl
+ def fooImpl(c: reflect.macros.Context) = c.literalUnit
+
+ def main(args: Array[String]) {
+ try {
+ val method = classOf[Test].getMethod("foo")
+ sys.error("Static forwarder generated for macro: " + method)
+ } catch {
+ case _: NoSuchMethodException => // okay
+ }
+ }
+}
diff --git a/test/files/run/t6288.check b/test/files/run/t6288.check
new file mode 100644
index 0000000000..af6bd5d269
--- /dev/null
+++ b/test/files/run/t6288.check
@@ -0,0 +1,85 @@
+[[syntax trees at end of patmat]] // newSource1
+[7]package [7]<empty> {
+ [7]object Case3 extends [13][106]scala.AnyRef {
+ [106]def <init>(): [13]Case3.type = [106]{
+ [106][106][106]Case3.super.<init>();
+ [13]()
+ };
+ [21]def unapply([29]z: [32]<type: [32]scala.Any>): [21]Option[Int] = [56][52][52]scala.Some.apply[[52]Int]([58]-1);
+ [64]{
+ [64]case <synthetic> val x1: [64]Any = [64]"";
+ [64]case5()[84]{
+ [84]<synthetic> val o7: [84]Option[Int] = [84][84]Case3.unapply([84]x1);
+ [84]if ([84]o7.isEmpty.unary_!)
+ [84]{
+ [90]val nr: [90]Int = [90]o7.get;
+ [97][97]matchEnd4([97]())
+ }
+ else
+ [84][84]case6()
+ };
+ [64]case6(){
+ [64][64]matchEnd4([64]throw [64][64][64]new [64]MatchError([64]x1))
+ };
+ [64]matchEnd4(x: [NoPosition]Unit){
+ [64]x
+ }
+ }
+ };
+ [113]object Case4 extends [119][217]scala.AnyRef {
+ [217]def <init>(): [119]Case4.type = [217]{
+ [217][217][217]Case4.super.<init>();
+ [119]()
+ };
+ [127]def unapplySeq([138]z: [141]<type: [141]scala.Any>): [127]Option[List[Int]] = [167]scala.None;
+ [175]{
+ [175]case <synthetic> val x1: [175]Any = [175]"";
+ [175]case5()[195]{
+ [195]<synthetic> val o7: [195]Option[List[Int]] = [195][195]Case4.unapplySeq([195]x1);
+ [195]if ([195]o7.isEmpty.unary_!)
+ [195]if ([195][195][195][195]o7.get.!=([195]null).&&([195][195][195][195]o7.get.lengthCompare([195]1).==([195]0)))
+ [195]{
+ [201]val nr: [201]Int = [201][201]o7.get.apply([201]0);
+ [208][208]matchEnd4([208]())
+ }
+ else
+ [195][195]case6()
+ else
+ [195][195]case6()
+ };
+ [175]case6(){
+ [175][175]matchEnd4([175]throw [175][175][175]new [175]MatchError([175]x1))
+ };
+ [175]matchEnd4(x: [NoPosition]Unit){
+ [175]x
+ }
+ }
+ };
+ [224]object Case5 extends [230][312]scala.AnyRef {
+ [312]def <init>(): [230]Case5.type = [312]{
+ [312][312][312]Case5.super.<init>();
+ [230]()
+ };
+ [238]def unapply([246]z: [249]<type: [249]scala.Any>): [238]Boolean = [265]true;
+ [273]{
+ [273]case <synthetic> val x1: [273]Any = [273]"";
+ [273]case5()[293]{
+ [293]<synthetic> val o7: [293]Option[List[Int]] = [293][293]Case4.unapplySeq([293]x1);
+ [293]if ([293]o7.isEmpty.unary_!)
+ [293]if ([293][293][293][293]o7.get.!=([293]null).&&([293][293][293][293]o7.get.lengthCompare([293]0).==([195]0)))
+ [304][304]matchEnd4([304]())
+ else
+ [293][293]case6()
+ else
+ [293][293]case6()
+ };
+ [273]case6(){
+ [273][273]matchEnd4([273]throw [273][273][273]new [273]MatchError([273]x1))
+ };
+ [273]matchEnd4(x: [NoPosition]Unit){
+ [273]x
+ }
+ }
+ }
+}
+
diff --git a/test/files/run/t6288.scala b/test/files/run/t6288.scala
new file mode 100644
index 0000000000..cf5865e95a
--- /dev/null
+++ b/test/files/run/t6288.scala
@@ -0,0 +1,41 @@
+import scala.tools.partest._
+import java.io.{Console => _, _}
+
+object Test extends DirectTest {
+
+ override def extraSettings: String = "-usejavacp -Xprint:patmat -Xprint-pos -d " + testOutput.path
+
+ override def code =
+ """
+ |object Case3 {
+ | def unapply(z: Any): Option[Int] = Some(-1)
+ |
+ | "" match {
+ | case Case3(nr) => ()
+ | }
+ |}
+ |object Case4 {
+ | def unapplySeq(z: Any): Option[List[Int]] = None
+ |
+ | "" match {
+ | case Case4(nr) => ()
+ | }
+ |}
+ |object Case5 {
+ | def unapply(z: Any): Boolean = true
+ |
+ | "" match {
+ | case Case4() => ()
+ | }
+ |}
+ |
+ |""".stripMargin.trim
+
+ override def show(): Unit = {
+ // Now: [84][84]Case3.unapply([84]x1);
+ // Was: [84][84]Case3.unapply([64]x1);
+ Console.withErr(System.out) {
+ compile()
+ }
+ }
+}
diff --git a/test/files/run/t6288b-jump-position.check b/test/files/run/t6288b-jump-position.check
new file mode 100644
index 0000000000..45ec31c308
--- /dev/null
+++ b/test/files/run/t6288b-jump-position.check
@@ -0,0 +1,80 @@
+object Case3 extends Object {
+ // fields:
+
+ // methods
+ def unapply(z: Object (REF(class Object))): Option {
+ locals: value z
+ startBlock: 1
+ blocks: [1]
+
+ 1:
+ 2 NEW REF(class Some)
+ 2 DUP(REF(class Some))
+ 2 CONSTANT(-1)
+ 2 BOX INT
+ 2 CALL_METHOD scala.Some.<init> (static-instance)
+ 2 RETURN(REF(class Option))
+
+ }
+ Exception handlers:
+
+ def main(args: Array[String] (ARRAY[REF(class String)])): Unit {
+ locals: value args, value x1, value x2, value x
+ startBlock: 1
+ blocks: [1,2,3,6,7]
+
+ 1:
+ 4 CONSTANT("")
+ 4 STORE_LOCAL(value x1)
+ 4 SCOPE_ENTER value x1
+ 4 JUMP 2
+
+ 2:
+ 5 LOAD_LOCAL(value x1)
+ 5 IS_INSTANCE REF(class String)
+ 5 CZJUMP (BOOL)NE ? 3 : 6
+
+ 3:
+ 5 LOAD_LOCAL(value x1)
+ 5 CHECK_CAST REF(class String)
+ 5 STORE_LOCAL(value x2)
+ 5 SCOPE_ENTER value x2
+ 6 LOAD_MODULE object Predef
+ 6 CONSTANT("case 0")
+ 6 CALL_METHOD scala.Predef.println (dynamic)
+ 6 LOAD_FIELD scala.runtime.BoxedUnit.UNIT
+ 6 STORE_LOCAL(value x)
+ 6 JUMP 7
+
+ 6:
+ 8 LOAD_MODULE object Predef
+ 8 CONSTANT("default")
+ 8 CALL_METHOD scala.Predef.println (dynamic)
+ 8 LOAD_FIELD scala.runtime.BoxedUnit.UNIT
+ 8 STORE_LOCAL(value x)
+ 8 JUMP 7
+
+ 7:
+ 10 LOAD_MODULE object Predef
+ 10 CONSTANT("done")
+ 10 CALL_METHOD scala.Predef.println (dynamic)
+ 10 RETURN(UNIT)
+
+ }
+ Exception handlers:
+
+ def <init>(): Case3.type {
+ locals:
+ startBlock: 1
+ blocks: [1]
+
+ 1:
+ 12 THIS(Case3)
+ 12 CALL_METHOD java.lang.Object.<init> (super())
+ 12 RETURN(UNIT)
+
+ }
+ Exception handlers:
+
+
+}
diff --git a/test/files/run/t6288b-jump-position.scala b/test/files/run/t6288b-jump-position.scala
new file mode 100644
index 0000000000..e22a1ab120
--- /dev/null
+++ b/test/files/run/t6288b-jump-position.scala
@@ -0,0 +1,22 @@
+import scala.tools.partest.IcodeTest
+
+object Test extends IcodeTest {
+ override def code =
+ """object Case3 { // 01
+ | def unapply(z: Any): Option[Int] = Some(-1) // 02
+ | def main(args: Array[String]) { // 03
+ | ("": Any) match { // 04
+ | case x : String => // 05 Read: <linenumber> JUMP <target basic block id>
+ | println("case 0") // 06 expecting "6 JUMP 7", was "8 JUMP 7"
+ | case _ => // 07
+ | println("default") // 08 expecting "8 JUMP 7"
+ | } // 09
+ | println("done") // 10
+ | }
+ |}""".stripMargin
+
+ override def show() {
+ val lines1 = collectIcode("")
+ println(lines1 mkString "\n")
+ }
+}
diff --git a/test/files/run/t6320.check b/test/files/run/t6320.check
new file mode 100644
index 0000000000..e56bacd223
--- /dev/null
+++ b/test/files/run/t6320.check
@@ -0,0 +1,17 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import scala.language.dynamics
+import scala.language.dynamics
+
+scala> class Dyn(m: Map[String, Any]) extends Dynamic { def selectDynamic[T](s: String): T = m(s).asInstanceOf[T] }
+defined class Dyn
+
+scala> new Dyn(Map("foo" -> 10)).foo[Int]
+res0: Int = 10
+
+scala>
+
+scala>
diff --git a/test/files/run/t6320.scala b/test/files/run/t6320.scala
new file mode 100644
index 0000000000..26085a3d7d
--- /dev/null
+++ b/test/files/run/t6320.scala
@@ -0,0 +1,9 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+import scala.language.dynamics
+class Dyn(m: Map[String, Any]) extends Dynamic { def selectDynamic[T](s: String): T = m(s).asInstanceOf[T] }
+new Dyn(Map("foo" -> 10)).foo[Int]
+ """
+}
diff --git a/test/files/run/t6549.check b/test/files/run/t6549.check
new file mode 100644
index 0000000000..bc78aac741
--- /dev/null
+++ b/test/files/run/t6549.check
@@ -0,0 +1,32 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> case class `X"`(var xxx: Any)
+defined class X$u0022
+
+scala> val m = Map(("": Any) -> `X"`("\""), ('s: Any) -> `X"`("\""))
+m: scala.collection.immutable.Map[Any,X"] = Map("" -> X"("), 's -> X"("))
+
+scala> m("")
+res0: X" = X"(")
+
+scala> m("").xxx
+res1: Any = "
+
+scala> m("").xxx = 0
+m("").xxx: Any = 0
+
+scala> m("").xxx = "\""
+m("").xxx: Any = "
+
+scala> m('s).xxx = 's
+m(scala.Symbol("s")).xxx: Any = 's
+
+scala> val `"` = 0
+": Int = 0
+
+scala>
+
+scala>
diff --git a/test/files/run/t6549.scala b/test/files/run/t6549.scala
new file mode 100644
index 0000000000..7335661dc7
--- /dev/null
+++ b/test/files/run/t6549.scala
@@ -0,0 +1,22 @@
+import scala.tools.partest.ReplTest
+
+// Check that the fragments of code generated in
+// in the REPL correctly escape values added to
+// literal strings.
+//
+// Before, we saw:
+// scala> m("").x = 77
+// <console>:10: error: ')' expected but string literal found.
+// + "m("").x: Int = " + `$ires8` + "\n"
+object Test extends ReplTest {
+ def code = """
+ |case class `X"`(var xxx: Any)
+ |val m = Map(("": Any) -> `X"`("\""), ('s: Any) -> `X"`("\""))
+ |m("")
+ |m("").xxx
+ |m("").xxx = 0
+ |m("").xxx = "\""
+ |m('s).xxx = 's
+ |val `"` = 0
+ """.stripMargin
+}
diff --git a/test/files/run/t6555.check b/test/files/run/t6555.check
new file mode 100644
index 0000000000..04117b7c2f
--- /dev/null
+++ b/test/files/run/t6555.check
@@ -0,0 +1,22 @@
+[[syntax trees at end of specialize]] // newSource1
+package <empty> {
+ class Foo extends Object {
+ def <init>(): Foo = {
+ Foo.super.<init>();
+ ()
+ };
+ private[this] val f: Int => Int = {
+ @SerialVersionUID(0) final <synthetic> class $anonfun extends scala.runtime.AbstractFunction1$mcII$sp with Serializable {
+ def <init>(): anonymous class $anonfun = {
+ $anonfun.super.<init>();
+ ()
+ };
+ final def apply(param: Int): Int = $anonfun.this.apply$mcII$sp(param);
+ <specialized> def apply$mcII$sp(param: Int): Int = param
+ };
+ (new anonymous class $anonfun(): Int => Int)
+ };
+ <stable> <accessor> def f(): Int => Int = Foo.this.f
+ }
+}
+
diff --git a/test/files/run/t6555.scala b/test/files/run/t6555.scala
new file mode 100644
index 0000000000..b1a6137786
--- /dev/null
+++ b/test/files/run/t6555.scala
@@ -0,0 +1,15 @@
+import scala.tools.partest._
+import java.io.{Console => _, _}
+
+object Test extends DirectTest {
+
+ override def extraSettings: String = "-usejavacp -Xprint:specialize -d " + testOutput.path
+
+ override def code = "class Foo { val f = (param: Int) => param } "
+
+ override def show(): Unit = {
+ Console.withErr(System.out) {
+ compile()
+ }
+ }
+}
diff --git a/test/files/run/t6614.check b/test/files/run/t6614.check
new file mode 100644
index 0000000000..2e80ebda8b
--- /dev/null
+++ b/test/files/run/t6614.check
@@ -0,0 +1,11 @@
+(ArrayStack(),true)
+(ArrayStack(0),true)
+(ArrayStack(0, 1),true)
+(ArrayStack(0, 1, 2),true)
+(ArrayStack(0, 1, 2, 3),true)
+(ArrayStack(0, 1, 2, 3, 4),true)
+(ArrayStack(0, 1, 2, 3, 4, 5),true)
+(ArrayStack(0, 1, 2, 3, 4, 5, 6),true)
+(ArrayStack(0, 1, 2, 3, 4, 5, 6, 7),true)
+(ArrayStack(0, 1, 2, 3, 4, 5, 6, 7, 8),true)
+(ArrayStack(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),true)
diff --git a/test/files/run/t6614.scala b/test/files/run/t6614.scala
new file mode 100644
index 0000000000..3ad9f36fc4
--- /dev/null
+++ b/test/files/run/t6614.scala
@@ -0,0 +1,8 @@
+object Test extends App {
+ import scala.collection.mutable.ArrayStack
+
+ println((for (i <- 0 to 10) yield {
+ val in = ArrayStack.tabulate(i)(_.toString)
+ (in, (in filter (_ => true)) == in)
+ }).mkString("\n"))
+}
diff --git a/test/files/run/t6631.scala b/test/files/run/t6631.scala
new file mode 100644
index 0000000000..e472b83d50
--- /dev/null
+++ b/test/files/run/t6631.scala
@@ -0,0 +1,18 @@
+import reflect.ClassTag
+
+object Test extends App {
+ def intercept[T <: Throwable : ClassTag](act: => Any) = try {
+ act
+ } catch {
+ case x: Throwable =>
+ val cls = implicitly[ClassTag[T]].runtimeClass
+ assert(cls.isInstance(x), (x.getClass, x, cls).toString)
+ }
+ assert(s"""\f\r\n\t""" == "\f\r\n\t")
+
+ import StringContext.InvalidEscapeException
+ intercept[InvalidEscapeException](s"""\""")
+ intercept[InvalidEscapeException](s"""\x""")
+ intercept[InvalidEscapeException](s"\")
+
+}
diff --git a/test/files/run/t6690.scala b/test/files/run/t6690.scala
new file mode 100644
index 0000000000..43ede967a0
--- /dev/null
+++ b/test/files/run/t6690.scala
@@ -0,0 +1,62 @@
+import scala.collection.mutable
+
+object Test extends App {
+ def last0(ml: mutable.MutableList[Int]) =
+ ml.asInstanceOf[{def last0: mutable.LinkedList[Int]}].last0
+
+ def first0(ml: mutable.MutableList[Int]) =
+ ml.asInstanceOf[{def first0: mutable.LinkedList[Int]}].first0
+
+ val f = mutable.Queue[Int]()
+ def check(desc: String) {
+ assert(f.length == 0, s"$desc: non empty: $f")
+ assert(last0(f).isEmpty, s"$desc: last0 leak: ${last0(f)}")
+ assert(first0(f).isEmpty, s"$desc: first0 leak: ${last0(f)}")
+ }
+
+ f.enqueue(1)
+ f.dequeue()
+ check("dequeue 1")
+
+ f.enqueue(1)
+ f.enqueue(2)
+ f.dequeue()
+ assert(last0(f).toList == List(2), last0(f))
+ f.dequeue()
+ check("dequeue 2")
+
+ f.enqueue(1)
+ f.dequeueAll(_ => false)
+ f.dequeueAll(_ => true)
+ check("dequeueAll")
+
+ f.enqueue(1)
+ f.dequeueFirst(_ => true)
+ check("dequeueFirst")
+
+ {
+ f.enqueue(1)
+ val tail = f.tail
+ assert(last0(tail).isEmpty, last0(tail))
+ assert(first0(tail).isEmpty, first0(tail))
+ }
+
+ {
+ val ml = mutable.MutableList[Int]()
+ 1 +=: ml
+ val tail = ml.tail
+ assert(last0(tail).isEmpty, last0(tail))
+ assert(first0(tail).isEmpty, first0(tail))
+ }
+
+ {
+ val ml = mutable.MutableList[Int]()
+ 1 +=: ml
+ ml += 2
+ val tail = ml.tail
+ assert(last0(tail).toList == List(2), last0(tail))
+ assert(first0(tail) == last0(tail).toList, first0(tail))
+ assert(last0(tail.tail).toList == Nil, last0(tail.tail).toList)
+ assert(first0(tail.tail) == Nil, first0(tail.tail))
+ }
+}
diff --git a/test/files/run/t6731.check b/test/files/run/t6731.check
new file mode 100644
index 0000000000..a5d59bd378
--- /dev/null
+++ b/test/files/run/t6731.check
@@ -0,0 +1,40 @@
+Mono$.bar()
+Mono$.bar
+Mono$.bar()
+Mono$.bar
+Mono$.bar
+Mono$.baz
+Mono$.bar(bippy=1, boppy=2)
+Mono$.baz
+Poly.bar[Nothing]
+Poly.bar[Int]
+Poly.bar[Nothing]()
+Poly.bar[Int]()
+Poly.bar[Int](1, 2, 3)
+Poly.bar[Nothing]
+Poly.bar[Int]
+Poly.bar[Nothing]()
+Poly.bar[Int]()
+Poly.bar[Int](1, 2, 3)
+Updating.bar
+Updating.bar = b
+Nest1$Nest2$Nest3$.bippy(1, 2, 3)
+Nest1$Nest2$Nest3$.bippy
+Named.bippy(a=1, b=2)
+Named.boppy(c=3, d=4)
+Named.apply()
+Named.apply()
+Named.apply(e=5, f=6)
+Named2.bippy(1)(q0, c)
+Named2.bippy(1)(q0, c)
+Named2.bippy(1)(b, q0)
+Named2.bippy(1)(q0, c)
+Named2.bippy(1)(c, b)
+Named2.bippy(1)(b, c)
+Named2.bippy(1)(q0, c)
+Named2.bippy(2)(b, c)
+Named2.bippy(1)(q0, c)
+Named2.bippy(5)(b, c)
+Named2.dingus(100)(b, dong)
+Named2.bippy(1)(q0, q1)
+Named2.hello(100)(!!, !!)
diff --git a/test/files/run/t6731.scala b/test/files/run/t6731.scala
new file mode 100644
index 0000000000..89d212e91e
--- /dev/null
+++ b/test/files/run/t6731.scala
@@ -0,0 +1,143 @@
+import scala.language.dynamics
+import scala.reflect.{ ClassTag, classTag }
+
+object Util {
+ def show[T](x: T): T = { println(x) ; x }
+ def mkArgs(xs: Any*) = xs map { case ((k, v)) => k + "=" + v ; case x => "" + x } mkString ("(", ", ", ")")
+}
+import Util._
+
+abstract class MonoDynamic extends Dynamic {
+ def selectDynamic(name: String): String = show(this + "." + name)
+ def applyDynamic(name: String)(args: Any*): String = show(this + "." + name + mkArgs(args: _*))
+ def applyDynamicNamed(name: String)(args: (String, Any)*): String = show(this + "." + name + mkArgs(args: _*))
+
+ override def toString = this.getClass.getName split '.' last
+}
+
+object Mono extends MonoDynamic {
+ def f(s: String): String = s
+
+ def f1 = this.bar()
+ def f2 = this.bar
+ def f3 = f(this.bar())
+ def f4 = f(this.bar)
+ def f5 = f(f(f(f(f(f(this.bar)))))) + f(f(f(f(f(f(this.baz))))))
+ def f6 = f(f(f(f(f(f(this.bar(bippy = 1, boppy = 2))))))) + f(f(f(f(f(f(this.baz))))))
+}
+
+object Poly extends Dynamic {
+ def selectDynamic[T: ClassTag](name: String): String = show(s"$this.$name[${classTag[T]}]")
+ def applyDynamic[T: ClassTag](name: String)(args: Any*): String = show(args.mkString(s"$this.$name[${classTag[T]}](", ", ", ")"))
+
+ def f(s: String): String = s
+
+ def f1 = this.bar
+ def f2 = this.bar[Int]
+ def f3 = this.bar()
+ def f4 = this.bar[Int]()
+ def f5 = this.bar[Int](1, 2, 3)
+
+ def f6 = f(f(this.bar))
+ def f7 = f(f(this.bar[Int]))
+ def f8 = f(f(this.bar()))
+ def f9 = f(f(this.bar[Int]()))
+ def f10 = f(f(this.bar[Int](1, 2, 3)))
+
+ override def toString = "Poly"
+}
+
+object Updating extends Dynamic {
+ def selectDynamic(name: String): String = show(s"$this.$name")
+ def updateDynamic(name: String)(value: Any): String = show(s"$this.$name = $value")
+
+ def f1 = this.bar
+ def f2 = this.bar = "b"
+
+ override def toString = "Updating"
+}
+
+object Nest1 extends Dynamic {
+ def applyDynamic(name: String)(args: Any*): Nest2.type = Nest2
+
+ object Nest2 extends Dynamic {
+ def applyDynamicNamed(name: String)(args: (String, Any)*): Nest3.type = Nest3
+
+ object Nest3 extends MonoDynamic {
+
+ }
+ }
+
+ def f1 = Nest1.bip().bop(foo = "bar").bippy(1, 2, 3)
+ def f2 = Nest1.bip("abc").bop(foo = 5).bippy
+}
+
+object Named extends Dynamic {
+ def applyDynamic(name: String)(args: Any*): Named.type = {
+ show(this + "." + name + mkArgs(args: _*))
+ this
+ }
+ def applyDynamicNamed(name: String)(args: (String, Any)*): Named.type = {
+ show(this + "." + name + mkArgs(args: _*))
+ this
+ }
+
+ def f1 = this.bippy(a = 1, b = 2).boppy(c = 3, d = 4)()()(e = 5, f = 6)
+ override def toString = "Named"
+}
+
+object Named2 extends Dynamic {
+ def applyDynamic(name: String)(a: Any)(b: Any = "b", c: Any = "c"): Named2.type = {
+ show(this + "." + name + mkArgs(a) + mkArgs(b, c))
+ this
+ }
+ def applyDynamicNamed(name: String)(a: (String, Any))(b: (String, Any), c: (String, Any)): Named2.type = {
+ show(this + "." + name + mkArgs(a) + mkArgs(b, c))
+ this
+ }
+
+ def f1 = this.bippy(1)(b = "q0")
+ def f2 = this.bippy(1)("q0")
+ def f3 = this.bippy(1)(c = "q0")
+ def f4 = this.bippy(1)("q0")
+ def f5 = this.bippy(1)(c = "b", b = "c")
+ def f6 = this.bippy(1)("b", "c")
+ def f7 = this.bippy(1)(b = "q0").bippy(2)()
+ def f8 = this.bippy(1)("q0").bippy(5)(c = "c").dingus(100)(c = "dong")
+ def f9 = this.bippy(1)(b = "q0", c = "q1").hello(100)("!!", "!!")
+
+ override def toString = "Named2"
+}
+
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ {
+ import Mono._
+ f1 ; f2 ; f3 ; f4 ; f5
+ f6
+ }
+ {
+ import Poly._
+ f1 ; f2 ; f3 ; f4 ; f5
+ f6 ; f7 ; f8 ; f9 ; f10
+ }
+ {
+ import Updating._
+ f1 ; f2
+ }
+ {
+ import Nest1._
+ f1 ; f2
+ }
+ {
+ import Named._
+ f1
+ }
+ {
+ import Named2._
+ f1 ; f2 ; f3 ; f4 ; f5
+ f6 ; f7 ; f8 ; f9
+ }
+ }
+}
diff --git a/test/files/run/toolbox_typecheck_implicitsdisabled.scala b/test/files/run/toolbox_typecheck_implicitsdisabled.scala
index f11f0192f3..8a3d433142 100644
--- a/test/files/run/toolbox_typecheck_implicitsdisabled.scala
+++ b/test/files/run/toolbox_typecheck_implicitsdisabled.scala
@@ -6,16 +6,16 @@ import scala.tools.reflect.ToolBox
object Test extends App {
val toolbox = cm.mkToolBox()
- val tree1 = Block(
- Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))),
+ val tree1 = Block(List(
+ Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1)))),
Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2))))
)
val ttree1 = toolbox.typeCheck(tree1, withImplicitViewsDisabled = false)
println(ttree1)
try {
- val tree2 = Block(
- Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))),
+ val tree2 = Block(List(
+ Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1)))),
Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2))))
)
val ttree2 = toolbox.typeCheck(tree2, withImplicitViewsDisabled = true)
diff --git a/test/pending/run/macro-reify-tagless-b/Test_2.scala b/test/pending/run/macro-reify-tagless-b/Test_2.scala
index ebd35ffe47..10487b1515 100644
--- a/test/pending/run/macro-reify-tagless-b/Test_2.scala
+++ b/test/pending/run/macro-reify-tagless-b/Test_2.scala
@@ -6,7 +6,7 @@ object Test extends App {
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass)))
- val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world"))))
+ val rhs = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant("hello world"))))
val list = ValDef(NoMods, newTermName("list"), tpt, rhs)
val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name))))
println(cm.mkToolBox().eval(tree))
diff --git a/test/scaladoc/run/SI-191-deprecated.scala b/test/scaladoc/run/SI-191-deprecated.scala
index 746aa9c598..4ed24ff8d1 100755
--- a/test/scaladoc/run/SI-191-deprecated.scala
+++ b/test/scaladoc/run/SI-191-deprecated.scala
@@ -1,5 +1,6 @@
import scala.tools.nsc.doc.model._
-import scala.tools.nsc.doc.model.comment._
+import scala.tools.nsc.doc.base._
+import scala.tools.nsc.doc.base.comment._
import scala.tools.partest.ScaladocModelTest
import java.net.{URI, URL}
import java.io.File
diff --git a/test/scaladoc/run/SI-191.scala b/test/scaladoc/run/SI-191.scala
index 0fb28145c3..6fb5339d66 100755
--- a/test/scaladoc/run/SI-191.scala
+++ b/test/scaladoc/run/SI-191.scala
@@ -1,5 +1,6 @@
import scala.tools.nsc.doc.model._
-import scala.tools.nsc.doc.model.comment._
+import scala.tools.nsc.doc.base._
+import scala.tools.nsc.doc.base.comment._
import scala.tools.partest.ScaladocModelTest
import java.net.{URI, URL}
import java.io.File
diff --git a/test/scaladoc/run/SI-3314.scala b/test/scaladoc/run/SI-3314.scala
index fe220b08af..c856fe46a8 100644
--- a/test/scaladoc/run/SI-3314.scala
+++ b/test/scaladoc/run/SI-3314.scala
@@ -1,3 +1,4 @@
+import scala.tools.nsc.doc.base._
import scala.tools.nsc.doc.model._
import scala.tools.partest.ScaladocModelTest
@@ -88,4 +89,4 @@ object Test extends ScaladocModelTest {
assert(bar.valueParams(0)(0).resultType.name == "(AnyRef { type Lambda[X] <: Either[A,X] })#Lambda[String]",
bar.valueParams(0)(0).resultType.name + " == (AnyRef { type Lambda[X] <: Either[A,X] })#Lambda[String]")
}
-} \ No newline at end of file
+}
diff --git a/test/scaladoc/run/SI-5235.scala b/test/scaladoc/run/SI-5235.scala
index 6295fc7786..c6b7922bb8 100644
--- a/test/scaladoc/run/SI-5235.scala
+++ b/test/scaladoc/run/SI-5235.scala
@@ -1,3 +1,4 @@
+import scala.tools.nsc.doc.base._
import scala.tools.nsc.doc.model._
import scala.tools.nsc.doc.model.diagram._
import scala.tools.partest.ScaladocModelTest
@@ -84,4 +85,4 @@ object Test extends ScaladocModelTest {
assert(mcReverseType.refEntity(0)._1 == LinkToTpl(MyCollection),
mcReverse.qualifiedName + "'s return type has a link to " + MyCollection.qualifiedName)
}
-} \ No newline at end of file
+}
diff --git a/test/scaladoc/run/links.scala b/test/scaladoc/run/links.scala
index 0c67857e1c..fde24edb2a 100644
--- a/test/scaladoc/run/links.scala
+++ b/test/scaladoc/run/links.scala
@@ -1,3 +1,4 @@
+import scala.tools.nsc.doc.base._
import scala.tools.nsc.doc.model._
import scala.tools.partest.ScaladocModelTest
@@ -23,9 +24,9 @@ object Test extends ScaladocModelTest {
val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("links")
val TEST = base._object("TEST")
- val memberLinks = countLinks(TEST.comment.get, _.link.isInstanceOf[LinkToMember])
- val templateLinks = countLinks(TEST.comment.get, _.link.isInstanceOf[LinkToTpl])
+ val memberLinks = countLinks(TEST.comment.get, _.link.isInstanceOf[LinkToMember[_, _]])
+ val templateLinks = countLinks(TEST.comment.get, _.link.isInstanceOf[LinkToTpl[_]])
assert(memberLinks == 17, memberLinks + " == 17 (the member links in object TEST)")
assert(templateLinks == 6, templateLinks + " == 6 (the template links in object TEST)")
}
-} \ No newline at end of file
+}
diff --git a/test/scaladoc/run/t4922.check b/test/scaladoc/run/t4922.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/t4922.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/t4922.scala b/test/scaladoc/run/t4922.scala
new file mode 100644
index 0000000000..bce87ac980
--- /dev/null
+++ b/test/scaladoc/run/t4922.scala
@@ -0,0 +1,32 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ // Test code
+ override def code = """
+ // This the default values should be displayed
+
+ object Test {
+ def f (a: Any = "".isEmpty) = ()
+ def g[A](b: A = null) = ()
+ }
+ """
+
+ // no need for special settings
+ def scaladocSettings = ""
+
+ def testModel(rootPackage: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ val Test = rootPackage._object("Test")
+ val f = Test._method("f")
+ val g = Test._method("g")
+
+ def assertEqual(s1: String, s2: String) = assert(s1 == s2, s1 + " == " + s2)
+
+ assertEqual(f.valueParams(0)(0).defaultValue.get.expression, "\"\".isEmpty")
+ assertEqual(g.valueParams(0)(0).defaultValue.get.expression, "null")
+ }
+} \ No newline at end of file
diff --git a/test/scaladoc/scalacheck/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala
index 5e3141bdc0..96174d29d1 100644
--- a/test/scaladoc/scalacheck/CommentFactoryTest.scala
+++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala
@@ -3,8 +3,7 @@ import org.scalacheck.Prop._
import scala.tools.nsc.Global
import scala.tools.nsc.doc
-import scala.tools.nsc.doc.model._
-import scala.tools.nsc.doc.model.comment._
+import scala.tools.nsc.doc.base.comment._
import scala.tools.nsc.doc.model._
import scala.tools.nsc.doc.model.diagram._