From af0da51e1bf81c4ea1a28af227179141604f9dfe Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 15:04:22 -0800 Subject: [nomaster] run mima both ways, filter out failures Using @gkossakowski's contribution to mima (in 0.1.5-SNAPSHOT), make sure bc.run doesn't fail by filtering out all binary incompatibilities. Each subsequent commit will comment out the filters it makes irrelevant, until we only need to filter out permitted binary incompatibilities. We only allow binary incompatibilities in scala.reflect.internal. --- bincompat-backward.whitelist.conf | 159 +++++++++++++++++ bincompat-forward.whitelist.conf | 359 ++++++++++++++++++++++++++++++++++++++ build.xml | 42 ++++- 3 files changed, 557 insertions(+), 3 deletions(-) create mode 100644 bincompat-backward.whitelist.conf create mode 100644 bincompat-forward.whitelist.conf diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf new file mode 100644 index 0000000000..07f459c922 --- /dev/null +++ b/bincompat-backward.whitelist.conf @@ -0,0 +1,159 @@ +filter { + problems=[ + # Scala library + { + # can only be called from Stream::distinct, which cannot itself be inlined, so distinct is the only feasible call-site + matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$4" + problemName=MissingMethodProblem + }, + { + # can only be called from Stream::distinct, which cannot itself be inlined, so distinct is the only feasible call-site + matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$5" + problemName=MissingMethodProblem + }, + { + # private[scala] + matchName="scala.collection.immutable.ListSerializeStart$" + problemName=MissingClassProblem + }, + { + # private[scala] + matchName="scala.collection.immutable.ListSerializeStart" + problemName=MissingClassProblem + }, + { + # private nested class became private top-level class to fix SI-7018 + matchName="scala.reflect.macros.Attachments$NonemptyAttachments" + problemName=MissingClassProblem + }, + + # scala.reflect.runtime + { + matchName="scala.reflect.runtime.JavaUniverse.createClassModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.JavaUniverse.initClassModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.createClassModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.initClassModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.initClassAndModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.initAndEnterClassAndModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" + problemName=IncompatibleResultTypeProblem + }, + + + # scala.reflect.internal + { + matchName="scala.reflect.internal.TreeInfo.scala$reflect$internal$TreeInfo$$isVarPatternDeep0$1" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.typeArguments" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.applyDepth" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.firstTypeArg" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.methPart" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.firstArgument" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees.DefDef" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.ExistentialsAndSkolems.deskolemizeTypeParams" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.deAlias" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.deskolemizeTypeParams" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.AnnotationInfos#Annotatable.addThrowsAnnotation" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments#Attachable.setAttachments" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types#TypeVar.scala$reflect$internal$Types$TypeVar$$addBound$1" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.AnnotationCheckers$AnnotationChecker" + problemName=IncompatibleTemplateDefProblem + }, + { + matchName="scala.reflect.internal.Types.deAlias" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.inheritsJavaVarArgsMethod" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.nonTrivialMembers" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.isJavaVarargsAncestor" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.nestedMemberType" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.normalizeAliases" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees#ChangeOwnerTraverser.changeOwner" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments.SuppressMacroExpansionAttachment" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.Statistics#RelCounter.scala$reflect$internal$util$Statistics$RelCounter$$super$prefix" + problemName=MissingMethodProblem + } + ] +} diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf new file mode 100644 index 0000000000..28c8a33fa2 --- /dev/null +++ b/bincompat-forward.whitelist.conf @@ -0,0 +1,359 @@ +filter { + problems=[ + # rework d526f8bd74 to duplicate tailImpl as a private method + { + matchName="scala.collection.mutable.MutableList.tailImpl" + problemName=MissingMethodProblem + }, + { + # can only be called from Stream::distinct, which cannot itself be inlined, so distinct is the only feasible call-site + matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$6" + problemName=MissingMethodProblem + }, + { + # can only be called from Stream::distinct, which cannot itself be inlined, so distinct is the only feasible call-site + matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$4" + problemName=MissingMethodProblem + }, + { + # can only be called from Stream::distinct, which cannot itself be inlined, so distinct is the only feasible call-site + matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$5" + problemName=MissingMethodProblem + }, + # TODO: revert a557a97360: bridge method appeared because result is now Int but the super-method's result type erases to Object + { + matchName="scala.collection.immutable.Range.head" + problemName=IncompatibleResultTypeProblem + }, + # TODO: revert 0b92073a38 2aa66bec86: SI-4664 [Make scala.util.Random Serializable] Add test case + { + matchName="scala.util.Random" + problemName=MissingTypesProblem + }, + { + matchName="scala.util.Random$" + problemName=MissingTypesProblem + }, + { + # private[concurrent] + matchName="scala.concurrent.BatchingExecutor$Batch" + problemName=MissingClassProblem + }, + { + # private[concurrent] + matchName="scala.concurrent.BatchingExecutor" + problemName=MissingClassProblem + }, + { + # private[concurrent] + matchName="scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask" + problemName=MissingClassProblem + }, + { + # private[concurrent] + matchName="scala.concurrent.impl.ExecutionContextImpl.scala$concurrent$impl$ExecutionContextImpl$$uncaughtExceptionHandler" + problemName=MissingMethodProblem + }, + { + # private nested class became private top-level class to fix SI-7018 + matchName="scala.reflect.macros.NonemptyAttachments" + problemName=MissingClassProblem + }, + + # scala.reflect.runtime + { + matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala1" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.initClassAndModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.initAndEnterClassAndModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.createClassModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.initClassModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.JavaUniverse" + problemName=MissingTypesProblem + }, + { + matchName="scala.reflect.runtime.JavaUniverse.initClassAndModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.JavaUniverse.initAndEnterClassAndModule" + problemName=MissingMethodProblem + }, + + # scala.reflect.internal + { + matchName="scala.reflect.internal.Types#Type.dealiasWidenChain" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types#Type.dealiasWiden" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types#Type.addThrowsAnnotation" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types#TypeVar.scala$reflect$internal$Types$TypeVar$$unifySpecific$1" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types#SubstSymMap.mapTreeSymbols" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types#SubstSymMap.this" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.PrivateWithin" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.TreeInfo$Applied" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.AnnotationInfos#Annotatable.addThrowsAnnotation" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.inheritsJavaVarArgsMethod" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.nonTrivialMembers" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.isJavaVarargsAncestor" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.normalizeAliases" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.nestedMemberType" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.deAlias" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.ExistentialsAndSkolems.deskolemizeTypeParams" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments#Attachable.setAttachments" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.AnnotationInfos#AnnotationInfo.completeInfo" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.isCompileTimeOnly" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.addThrowsAnnotation" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.toOption" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.compileTimeOnlyMessage" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.setAttachments" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.addAnnotation" + problemName=IncompatibleMethTypeProblem + }, + { + matchName="scala.reflect.internal.Trees.DefDef" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees$TreeStackTraverser" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.Trees#ChangeOwnerTraverser.change" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.AnnotationCheckers$AnnotationChecker" + problemName=IncompatibleTemplateDefProblem + }, + { + matchName="scala.reflect.internal.TreeInfo$Applied$" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.Trees#Tree.setAttachments" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdNames#TermNames.DEFAULT_CASE" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.Applied" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.isWildcardStarType" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.isSyntheticDefaultCase" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.StripCast" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.dissectApplied" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.TreeInfo.stripCast" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable" + problemName=MissingTypesProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.StringContextStripMarginOps" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.inheritsJavaVarArgsMethod" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.assertCorrectThread" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.SuppressMacroExpansionAttachment" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.nonTrivialMembers" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.isJavaVarargsAncestor" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.normalizeAliases" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.DefDef" + problemName=IncompatibleMethTypeProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.nestedMemberType" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.importPrivateWithinFromJavaFlags" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments.SuppressMacroExpansionAttachment" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.ArrayModule_genericApply" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.allParameters" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.Predef_wrapArray" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.dropNullaryMethod" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.ArrayModule_apply" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.OptionModule" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.Option_apply" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.CompileTimeOnlyAttr" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.AnnotationInfos#LazyAnnotationInfo.completeInfo" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.package" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.util.package$" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.util.StripMarginInterpolator" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.util.package$StringContextStripMarginOps" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.annotations.compileTimeOnly" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.StdNames#TermNames.SelectFromTypeTree" + problemName=MissingMethodProblem + } + ] +} diff --git a/build.xml b/build.xml index af577afbaa..df6fecb354 100644 --- a/build.xml +++ b/build.xml @@ -2656,11 +2656,11 @@ Binary compatibility testing - + - - + + @@ -2673,6 +2673,9 @@ Binary compatibility testing + + + @@ -2685,6 +2688,39 @@ Binary compatibility testing + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From f9550c6ab8b72221ff68bbadcbcc423ebd37f4d5 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 15:05:03 -0800 Subject: [nomaster] Revert "Fixes SI-6521, overrides Range#head to be faster" This reverts commit a557a973608a75c7a02f251bbcf49fe6f6b6655e. This is necessary to maintain binary compatibility with 2.10.0. Mima says: matchName="scala.collection.immutable.Range.head" problemName=IncompatibleResultTypeProblem The bridge method appeared because result is now Int, whereas the super-method's result type erases to Object --- bincompat-forward.whitelist.conf | 8 ++++---- src/library/scala/collection/immutable/Range.scala | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 28c8a33fa2..1ff6cc6012 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -21,10 +21,10 @@ filter { problemName=MissingMethodProblem }, # TODO: revert a557a97360: bridge method appeared because result is now Int but the super-method's result type erases to Object - { - matchName="scala.collection.immutable.Range.head" - problemName=IncompatibleResultTypeProblem - }, + # { + # matchName="scala.collection.immutable.Range.head" + # problemName=IncompatibleResultTypeProblem + # }, # TODO: revert 0b92073a38 2aa66bec86: SI-4664 [Make scala.util.Random Serializable] Add test case { matchName="scala.util.Random" diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 02c10700b1..802e16605d 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -77,7 +77,6 @@ extends scala.collection.AbstractSeq[Int] final val terminalElement = start + numRangeElements * step override def last = if (isEmpty) Nil.last else lastElement - override def head = if (isEmpty) Nil.head else start override def min[A1 >: Int](implicit ord: Ordering[A1]): Int = if (ord eq Ordering.Int) { -- cgit v1.2.3 From 8b4af71d27ebd56f318e31ffc69225f3fdd6232d Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 15:06:15 -0800 Subject: [nomaster] Revert "SI-4664 Make scala.util.Random Serializable" Also revert "SI-4664 [Make scala.util.Random Serializable] Add test case" This reverts commit 0b92073a38f9d1823f051ac18173078bfcfafc8a. This reverts commit 2aa66bec86fd464712b0d15251cc400ff9d52821. This is necessary to maintain binary compatibility with 2.10.0. --- bincompat-forward.whitelist.conf | 18 +++++++++--------- src/library/scala/util/Random.scala | 2 +- test/files/jvm/serialization.scala | 15 --------------- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 1ff6cc6012..9673976c60 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -25,15 +25,15 @@ filter { # matchName="scala.collection.immutable.Range.head" # problemName=IncompatibleResultTypeProblem # }, - # TODO: revert 0b92073a38 2aa66bec86: SI-4664 [Make scala.util.Random Serializable] Add test case - { - matchName="scala.util.Random" - problemName=MissingTypesProblem - }, - { - matchName="scala.util.Random$" - problemName=MissingTypesProblem - }, + # revert 0b92073a38 2aa66bec86: SI-4664 [Make scala.util.Random Serializable] Add test case + # { + # matchName="scala.util.Random" + # problemName=MissingTypesProblem + # }, + # { + # matchName="scala.util.Random$" + # problemName=MissingTypesProblem + # }, { # private[concurrent] matchName="scala.concurrent.BatchingExecutor$Batch" diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala index 2b11594f66..24c4cd7a32 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) extends AnyRef with Serializable { +class Random(val self: java.util.Random) { /** Creates a new random number generator using a single long seed. */ def this(seed: Long) = this(new java.util.Random(seed)) diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala index f2c47aad77..34b64938b4 100644 --- a/test/files/jvm/serialization.scala +++ b/test/files/jvm/serialization.scala @@ -604,7 +604,6 @@ object Test { Test7 Test8 Test9_parallel - Test10_util } } @@ -670,17 +669,3 @@ 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) } - } -} -- cgit v1.2.3 From 5d487f105f1f2890506c3e99e352a02f206fad83 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 15:09:20 -0800 Subject: [nomaster] duplicate tailImpl as a private method Reworks d526f8bd74. This is necessary to maintain binary compatibility with 2.10.0. matchName="scala.collection.mutable.MutableList.tailImpl" problemName=MissingMethodProblem --- bincompat-forward.whitelist.conf | 8 ++++---- src/library/scala/collection/mutable/MutableList.scala | 3 ++- src/library/scala/collection/mutable/Queue.scala | 7 +++++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 9673976c60..cb8191fbcc 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -1,10 +1,10 @@ filter { problems=[ # rework d526f8bd74 to duplicate tailImpl as a private method - { - matchName="scala.collection.mutable.MutableList.tailImpl" - problemName=MissingMethodProblem - }, + # { + # matchName="scala.collection.mutable.MutableList.tailImpl" + # problemName=MissingMethodProblem + # }, { # can only be called from Stream::distinct, which cannot itself be inlined, so distinct is the only feasible call-site matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$6" diff --git a/src/library/scala/collection/mutable/MutableList.scala b/src/library/scala/collection/mutable/MutableList.scala index fd92d2e555..bc6272bfdb 100644 --- a/src/library/scala/collection/mutable/MutableList.scala +++ b/src/library/scala/collection/mutable/MutableList.scala @@ -61,7 +61,8 @@ extends AbstractSeq[A] tl } - protected final def tailImpl(tl: MutableList[A]) { + // this method must be private for binary compatibility + private final def tailImpl(tl: MutableList[A]) { require(nonEmpty, "tail of empty list") tl.first0 = first0.tail tl.len = len - 1 diff --git a/src/library/scala/collection/mutable/Queue.scala b/src/library/scala/collection/mutable/Queue.scala index b947fa3cca..8ef5f6aeb7 100644 --- a/src/library/scala/collection/mutable/Queue.scala +++ b/src/library/scala/collection/mutable/Queue.scala @@ -167,6 +167,13 @@ extends MutableList[A] */ def front: A = head + // this method (duplicated from MutableList) must be private for binary compatibility + private final def tailImpl(tl: Queue[A]) { + require(nonEmpty, "tail of empty list") + tl.first0 = first0.tail + tl.len = len - 1 + tl.last0 = if (tl.len == 0) tl.first0 else last0 + } // TODO - Don't override this just for new to create appropriate type.... override def tail: Queue[A] = { -- cgit v1.2.3 From 549a1fea9366af0c0a4697bc39e3a75bd8f066f5 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 16:43:26 -0800 Subject: [nomaster] bring back SerializeStart from fa3b8040eb This is necessary to maintain binary compatibility with 2.10.0. --- bincompat-backward.whitelist.conf | 20 ++++++++++---------- src/library/scala/collection/immutable/List.scala | 4 ++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 07f459c922..7baecc63a0 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -11,16 +11,16 @@ filter { matchName="scala.collection.immutable.Stream.scala$collection$immutable$Stream$$loop$5" problemName=MissingMethodProblem }, - { - # private[scala] - matchName="scala.collection.immutable.ListSerializeStart$" - problemName=MissingClassProblem - }, - { - # private[scala] - matchName="scala.collection.immutable.ListSerializeStart" - problemName=MissingClassProblem - }, + # { + # # private[scala] + # matchName="scala.collection.immutable.ListSerializeStart$" + # problemName=MissingClassProblem + # }, + # { + # # private[scala] + # matchName="scala.collection.immutable.ListSerializeStart" + # problemName=MissingClassProblem + # }, { # private nested class became private top-level class to fix SI-7018 matchName="scala.reflect.macros.Attachments$NonemptyAttachments" diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index 9765e7c52f..2d6952ff92 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -642,6 +642,10 @@ object List extends SeqFactory[List] { } } +/** Only used for list serialization */ +@SerialVersionUID(0L - 8287891243975527522L) +private[scala] case object ListSerializeStart + /** Only used for list serialization */ @SerialVersionUID(0L - 8476791151975527571L) private[scala] case object ListSerializeEnd -- cgit v1.2.3 From 56cbf233c1b3d62def022f09702f525c63141a0f Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 17:10:20 -0800 Subject: [nomaster] can't add new class BatchingExecutor This is necessary to maintain binary compatibility with 2.10.0. --- bincompat-forward.whitelist.conf | 20 ++-- .../scala/concurrent/BatchingExecutor.scala | 117 --------------------- src/library/scala/concurrent/Future.scala | 106 ++++++++++++++++++- 3 files changed, 113 insertions(+), 130 deletions(-) delete mode 100644 src/library/scala/concurrent/BatchingExecutor.scala diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index cb8191fbcc..ab43b3015f 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -34,16 +34,16 @@ filter { # matchName="scala.util.Random$" # problemName=MissingTypesProblem # }, - { - # private[concurrent] - matchName="scala.concurrent.BatchingExecutor$Batch" - problemName=MissingClassProblem - }, - { - # private[concurrent] - matchName="scala.concurrent.BatchingExecutor" - problemName=MissingClassProblem - }, + # { + # # private[concurrent] + # matchName="scala.concurrent.BatchingExecutor$Batch" + # problemName=MissingClassProblem + # }, + # { + # # private[concurrent] + # matchName="scala.concurrent.BatchingExecutor" + # problemName=MissingClassProblem + # }, { # private[concurrent] matchName="scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask" diff --git a/src/library/scala/concurrent/BatchingExecutor.scala b/src/library/scala/concurrent/BatchingExecutor.scala deleted file mode 100644 index a0d7aaea47..0000000000 --- a/src/library/scala/concurrent/BatchingExecutor.scala +++ /dev/null @@ -1,117 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.concurrent - -import java.util.concurrent.Executor -import scala.annotation.tailrec - -/** - * Mixin trait for an Executor - * which groups multiple nested `Runnable.run()` calls - * into a single Runnable passed to the original - * Executor. This can be a useful optimization - * because it bypasses the original context's task - * queue and keeps related (nested) code on a single - * thread which may improve CPU affinity. However, - * if tasks passed to the Executor are blocking - * or expensive, this optimization can prevent work-stealing - * and make performance worse. Also, some ExecutionContext - * may be fast enough natively that this optimization just - * adds overhead. - * The default ExecutionContext.global is already batching - * or fast enough not to benefit from it; while - * `fromExecutor` and `fromExecutorService` do NOT add - * this optimization since they don't know whether the underlying - * executor will benefit from it. - * A batching executor can create deadlocks if code does - * not use `scala.concurrent.blocking` when it should, - * because tasks created within other tasks will block - * on the outer task completing. - * This executor may run tasks in any order, including LIFO order. - * There are no ordering guarantees. - * - * WARNING: The underlying Executor's execute-method must not execute the submitted Runnable - * in the calling thread synchronously. It must enqueue/handoff the Runnable. - */ -private[concurrent] trait BatchingExecutor extends Executor { - - // invariant: if "_tasksLocal.get ne null" then we are inside BatchingRunnable.run; if it is null, we are outside - private val _tasksLocal = new ThreadLocal[List[Runnable]]() - - private class Batch(val initial: List[Runnable]) extends Runnable with BlockContext { - private var parentBlockContext: BlockContext = _ - // this method runs in the delegate ExecutionContext's thread - override def run(): Unit = { - require(_tasksLocal.get eq null) - - val prevBlockContext = BlockContext.current - BlockContext.withBlockContext(this) { - try { - parentBlockContext = prevBlockContext - - @tailrec def processBatch(batch: List[Runnable]): Unit = batch match { - case Nil => () - case head :: tail => - _tasksLocal set tail - try { - head.run() - } catch { - case t: Throwable => - // if one task throws, move the - // remaining tasks to another thread - // so we can throw the exception - // up to the invoking executor - val remaining = _tasksLocal.get - _tasksLocal set Nil - unbatchedExecute(new Batch(remaining)) //TODO what if this submission fails? - throw t // rethrow - } - processBatch(_tasksLocal.get) // since head.run() can add entries, always do _tasksLocal.get here - } - - processBatch(initial) - } finally { - _tasksLocal.remove() - parentBlockContext = null - } - } - } - - override def blockOn[T](thunk: => T)(implicit permission: CanAwait): T = { - // if we know there will be blocking, we don't want to keep tasks queued up because it could deadlock. - { - val tasks = _tasksLocal.get - _tasksLocal set Nil - if ((tasks ne null) && tasks.nonEmpty) - unbatchedExecute(new Batch(tasks)) - } - - // now delegate the blocking to the previous BC - require(parentBlockContext ne null) - parentBlockContext.blockOn(thunk) - } - } - - protected def unbatchedExecute(r: Runnable): Unit - - override def execute(runnable: Runnable): Unit = { - if (batchable(runnable)) { // If we can batch the runnable - _tasksLocal.get match { - case null => unbatchedExecute(new Batch(List(runnable))) // If we aren't in batching mode yet, enqueue batch - case some => _tasksLocal.set(runnable :: some) // If we are already in batching mode, add to batch - } - } else unbatchedExecute(runnable) // If not batchable, just delegate to underlying - } - - /** Override this to define which runnables will be batched. */ - def batchable(runnable: Runnable): Boolean = runnable match { - case _: OnCompleteRunnable => true - case _ => false - } -} diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 36f3be341f..5a51e97072 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -675,11 +675,111 @@ object Future { // by just not ever using it itself. scala.concurrent // doesn't need to create defaultExecutionContext as // a side effect. - private[concurrent] object InternalCallbackExecutor extends ExecutionContext with BatchingExecutor { - override protected def unbatchedExecute(r: Runnable): Unit = - r.run() + private[concurrent] object InternalCallbackExecutor extends ExecutionContext with java.util.concurrent.Executor { override def reportFailure(t: Throwable): Unit = throw new IllegalStateException("problem in scala.concurrent internal callback", t) + + /** + * The BatchingExecutor trait had to be inlined into InternalCallbackExecutor for binary compatibility. + * + * BatchingExecutor is a trait for an Executor + * which groups multiple nested `Runnable.run()` calls + * into a single Runnable passed to the original + * Executor. This can be a useful optimization + * because it bypasses the original context's task + * queue and keeps related (nested) code on a single + * thread which may improve CPU affinity. However, + * if tasks passed to the Executor are blocking + * or expensive, this optimization can prevent work-stealing + * and make performance worse. Also, some ExecutionContext + * may be fast enough natively that this optimization just + * adds overhead. + * The default ExecutionContext.global is already batching + * or fast enough not to benefit from it; while + * `fromExecutor` and `fromExecutorService` do NOT add + * this optimization since they don't know whether the underlying + * executor will benefit from it. + * A batching executor can create deadlocks if code does + * not use `scala.concurrent.blocking` when it should, + * because tasks created within other tasks will block + * on the outer task completing. + * This executor may run tasks in any order, including LIFO order. + * There are no ordering guarantees. + * + * WARNING: The underlying Executor's execute-method must not execute the submitted Runnable + * in the calling thread synchronously. It must enqueue/handoff the Runnable. + */ + // invariant: if "_tasksLocal.get ne null" then we are inside BatchingRunnable.run; if it is null, we are outside + private val _tasksLocal = new ThreadLocal[List[Runnable]]() + + private class Batch(val initial: List[Runnable]) extends Runnable with BlockContext { + private[this] var parentBlockContext: BlockContext = _ + // this method runs in the delegate ExecutionContext's thread + override def run(): Unit = { + require(_tasksLocal.get eq null) + + val prevBlockContext = BlockContext.current + BlockContext.withBlockContext(this) { + try { + parentBlockContext = prevBlockContext + + @tailrec def processBatch(batch: List[Runnable]): Unit = batch match { + case Nil => () + case head :: tail => + _tasksLocal set tail + try { + head.run() + } catch { + case t: Throwable => + // if one task throws, move the + // remaining tasks to another thread + // so we can throw the exception + // up to the invoking executor + val remaining = _tasksLocal.get + _tasksLocal set Nil + unbatchedExecute(new Batch(remaining)) //TODO what if this submission fails? + throw t // rethrow + } + processBatch(_tasksLocal.get) // since head.run() can add entries, always do _tasksLocal.get here + } + + processBatch(initial) + } finally { + _tasksLocal.remove() + parentBlockContext = null + } + } + } + + override def blockOn[T](thunk: => T)(implicit permission: CanAwait): T = { + // if we know there will be blocking, we don't want to keep tasks queued up because it could deadlock. + { + val tasks = _tasksLocal.get + _tasksLocal set Nil + if ((tasks ne null) && tasks.nonEmpty) + unbatchedExecute(new Batch(tasks)) + } + + // now delegate the blocking to the previous BC + require(parentBlockContext ne null) + parentBlockContext.blockOn(thunk) + } + } + + override def execute(runnable: Runnable): Unit = runnable match { + // If we can batch the runnable + case _: OnCompleteRunnable => + _tasksLocal.get match { + case null => unbatchedExecute(new Batch(List(runnable))) // If we aren't in batching mode yet, enqueue batch + case some => _tasksLocal.set(runnable :: some) // If we are already in batching mode, add to batch + } + + // If not batchable, just delegate to underlying + case _ => + unbatchedExecute(runnable) + } + + private def unbatchedExecute(r: Runnable): Unit = r.run() } } -- cgit v1.2.3 From 9194b37a8d402b67e41e941fddb4a741bf8eb16f Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 17:17:23 -0800 Subject: [nomaster] refactor AdaptedForkJoinTask, uncaughtExceptionHandler Inlined AdaptedForkJoinTask, made uncaughtExceptionHandler private[this]. This is necessary to maintain binary compatibility with 2.10.0. --- bincompat-forward.whitelist.conf | 20 ++++++------- .../concurrent/impl/ExecutionContextImpl.scala | 33 ++++++++++------------ 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index ab43b3015f..a870288ffb 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -44,16 +44,16 @@ filter { # matchName="scala.concurrent.BatchingExecutor" # problemName=MissingClassProblem # }, - { - # private[concurrent] - matchName="scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask" - problemName=MissingClassProblem - }, - { - # private[concurrent] - matchName="scala.concurrent.impl.ExecutionContextImpl.scala$concurrent$impl$ExecutionContextImpl$$uncaughtExceptionHandler" - problemName=MissingMethodProblem - }, + # { + # # private[concurrent] + # matchName="scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask" + # problemName=MissingClassProblem + # }, + # { + # # private[concurrent] + # matchName="scala.concurrent.impl.ExecutionContextImpl.scala$concurrent$impl$ExecutionContextImpl$$uncaughtExceptionHandler" + # problemName=MissingMethodProblem + # }, { # private nested class became private top-level class to fix SI-7018 matchName="scala.reflect.macros.NonemptyAttachments" diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala index 77625e381c..43b437dbc6 100644 --- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala @@ -25,7 +25,7 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter: case some => some } - private val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = new Thread.UncaughtExceptionHandler { + private[this] val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = new Thread.UncaughtExceptionHandler { def uncaughtException(thread: Thread, cause: Throwable): Unit = reporter(cause) } @@ -96,11 +96,24 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter: } } + def execute(runnable: Runnable): Unit = executor match { case fj: ForkJoinPool => val fjt = runnable match { case t: ForkJoinTask[_] => t - case r => new ExecutionContextImpl.AdaptedForkJoinTask(r) + case runnable => new ForkJoinTask[Unit] { + final override def setRawResult(u: Unit): Unit = () + final override def getRawResult(): Unit = () + final override def exec(): Boolean = try { runnable.run(); true } catch { + case anything: Throwable ⇒ + val t = Thread.currentThread + t.getUncaughtExceptionHandler match { + case null ⇒ + case some ⇒ some.uncaughtException(t, anything) + } + throw anything + } + } } Thread.currentThread match { case fjw: ForkJoinWorkerThread if fjw.getPool eq fj => fjt.fork() @@ -112,23 +125,7 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter: def reportFailure(t: Throwable) = reporter(t) } - private[concurrent] object ExecutionContextImpl { - - final class AdaptedForkJoinTask(runnable: Runnable) extends ForkJoinTask[Unit] { - final override def setRawResult(u: Unit): Unit = () - final override def getRawResult(): Unit = () - final override def exec(): Boolean = try { runnable.run(); true } catch { - case anything: Throwable ⇒ - val t = Thread.currentThread - t.getUncaughtExceptionHandler match { - case null ⇒ - case some ⇒ some.uncaughtException(t, anything) - } - throw anything - } - } - def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl = new ExecutionContextImpl(e, reporter) def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl with ExecutionContextExecutorService = new ExecutionContextImpl(es, reporter) with ExecutionContextExecutorService { -- cgit v1.2.3 From ddfe3a06b0fec24948ddb06fe23b3aa78d78bbe1 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 17:20:22 -0800 Subject: [nomaster] Revert "cosmetic renamings in runtime reflection" This reverts commit 0429f0fd9224499cd8b606490d04b1a8dcffbca8. This is necessary to maintain binary compatibility with 2.10.0. --- bincompat-backward.whitelist.conf | 48 +++++++++++----------- bincompat-forward.whitelist.conf | 48 +++++++++++----------- .../scala/reflect/runtime/JavaMirrors.scala | 4 +- .../scala/reflect/runtime/SymbolLoaders.scala | 8 ++-- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 7baecc63a0..3b29f7388b 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -28,30 +28,30 @@ filter { }, # scala.reflect.runtime - { - matchName="scala.reflect.runtime.JavaUniverse.createClassModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.JavaUniverse.initClassModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.SymbolLoaders.createClassModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.SymbolLoaders.initClassModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.SymbolLoaders.initClassAndModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.SymbolLoaders.initAndEnterClassAndModule" - problemName=MissingMethodProblem - }, + # { + # matchName="scala.reflect.runtime.JavaUniverse.createClassModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.JavaUniverse.initClassModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.SymbolLoaders.createClassModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.SymbolLoaders.initClassModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.SymbolLoaders.initClassAndModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.SymbolLoaders.initAndEnterClassAndModule" + # problemName=MissingMethodProblem + # }, { matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" problemName=MissingMethodProblem diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index a870288ffb..3e9871804a 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -69,34 +69,34 @@ filter { matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala1" problemName=MissingMethodProblem }, - { - matchName="scala.reflect.runtime.SymbolLoaders.initClassAndModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.SymbolLoaders.initAndEnterClassAndModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.SymbolLoaders.createClassModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.SymbolLoaders.initClassModule" - problemName=MissingMethodProblem - }, + # { + # matchName="scala.reflect.runtime.SymbolLoaders.initClassAndModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.SymbolLoaders.initAndEnterClassAndModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.SymbolLoaders.createClassModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.SymbolLoaders.initClassModule" + # problemName=MissingMethodProblem + # }, { matchName="scala.reflect.runtime.JavaUniverse" problemName=MissingTypesProblem }, - { - matchName="scala.reflect.runtime.JavaUniverse.initClassAndModule" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.JavaUniverse.initAndEnterClassAndModule" - problemName=MissingMethodProblem - }, + # { + # matchName="scala.reflect.runtime.JavaUniverse.initClassAndModule" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.JavaUniverse.initAndEnterClassAndModule" + # problemName=MissingMethodProblem + # }, # scala.reflect.internal { diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 778c826dc0..eb73ac75fb 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -574,7 +574,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni case None => // class does not have a Scala signature; it's a Java class info("translating reflection info for Java " + jclazz) //debug - initClassAndModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz)) + initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz)) } } } catch { @@ -1053,7 +1053,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni val owner = sOwner(jclazz) val name = scalaSimpleName(jclazz) val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz) - initAndEnterClassAndModule(owner, name, completer)._1 + createClassModule(owner, name, completer) match { case (clazz, module) => clazz } } /** diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index 311db64b91..61663f6181 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -57,7 +57,7 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => * @param name The simple name of the newly created class * @param completer The completer to be used to set the info of the class and the module */ - protected def initAndEnterClassAndModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { + protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { assert(!(name.toString endsWith "[]"), name) val clazz = owner.newClass(name) val module = owner.newModule(name.toTermName) @@ -67,7 +67,7 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => owner.info.decls enter clazz owner.info.decls enter module } - initClassAndModule(clazz, module, completer(clazz, module)) + initClassModule(clazz, module, completer(clazz, module)) (clazz, module) } @@ -75,7 +75,7 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => List(clazz, module, module.moduleClass) foreach (_ setInfo info) } - protected def initClassAndModule(clazz: Symbol, module: Symbol, completer: LazyType) = + protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = setAllInfos(clazz, module, completer) /** The type completer for packages. @@ -118,7 +118,7 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => val loadingMirror = currentMirror.mirrorDefining(cls) val (clazz, module) = if (loadingMirror eq currentMirror) { - initAndEnterClassAndModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) + createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) } else { val origOwner = loadingMirror.packageNameToScala(pkgClass.fullName) val clazz = origOwner.info decl name.toTypeName -- cgit v1.2.3 From 2f9b708b748e7a2fb252ae1ab546f4824ec0f283 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Sat, 9 Feb 2013 18:00:08 -0800 Subject: [nomaster] inline importPrivateWithinFromJavaFlags into SymbolTable This reworks 02ed5fb so that we don't change JavaUniverse's super classes. This is necessary to maintain binary compatibility with 2.10.0. --- bincompat-forward.whitelist.conf | 8 ++++---- .../scala/reflect/internal/PrivateWithin.scala | 23 ---------------------- .../scala/reflect/internal/SymbolTable.scala | 16 ++++++++++++++- 3 files changed, 19 insertions(+), 28 deletions(-) delete mode 100644 src/reflect/scala/reflect/internal/PrivateWithin.scala diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 3e9871804a..66d2ba7154 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -85,10 +85,10 @@ filter { # matchName="scala.reflect.runtime.SymbolLoaders.initClassModule" # problemName=MissingMethodProblem # }, - { - matchName="scala.reflect.runtime.JavaUniverse" - problemName=MissingTypesProblem - }, + # { + # matchName="scala.reflect.runtime.JavaUniverse" + # problemName=MissingTypesProblem + # }, # { # matchName="scala.reflect.runtime.JavaUniverse.initClassAndModule" # problemName=MissingMethodProblem diff --git a/src/reflect/scala/reflect/internal/PrivateWithin.scala b/src/reflect/scala/reflect/internal/PrivateWithin.scala deleted file mode 100644 index 9b99b94b41..0000000000 --- a/src/reflect/scala/reflect/internal/PrivateWithin.scala +++ /dev/null @@ -1,23 +0,0 @@ -package scala.reflect -package internal - -import ClassfileConstants._ - -trait PrivateWithin { - self: SymbolTable => - - def importPrivateWithinFromJavaFlags(sym: Symbol, jflags: Int): Symbol = { - if ((jflags & (JAVA_ACC_PRIVATE | JAVA_ACC_PROTECTED | JAVA_ACC_PUBLIC)) == 0) - // See ticket #1687 for an example of when topLevelClass is NoSymbol: it - // apparently occurs when processing v45.3 bytecode. - if (sym.enclosingTopLevelClass != NoSymbol) - sym.privateWithin = sym.enclosingTopLevelClass.owner - - // protected in java means package protected. #3946 - if ((jflags & JAVA_ACC_PROTECTED) != 0) - if (sym.enclosingTopLevelClass != NoSymbol) - sym.privateWithin = sym.enclosingTopLevelClass.owner - - sym - } -} \ No newline at end of file diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index f75855f1ec..5ccf81b4b5 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -38,7 +38,6 @@ abstract class SymbolTable extends macros.Universe with StdAttachments with StdCreators with BuildUtils - with PrivateWithin { val gen = new TreeGen { val global: SymbolTable.this.type = SymbolTable.this } @@ -352,6 +351,21 @@ abstract class SymbolTable extends macros.Universe */ implicit val StringContextStripMarginOps: StringContext => StringContextStripMarginOps = util.StringContextStripMarginOps + def importPrivateWithinFromJavaFlags(sym: Symbol, jflags: Int): Symbol = { + import ClassfileConstants._ + if ((jflags & (JAVA_ACC_PRIVATE | JAVA_ACC_PROTECTED | JAVA_ACC_PUBLIC)) == 0) + // See ticket #1687 for an example of when topLevelClass is NoSymbol: it + // apparently occurs when processing v45.3 bytecode. + if (sym.enclosingTopLevelClass != NoSymbol) + sym.privateWithin = sym.enclosingTopLevelClass.owner + + // protected in java means package protected. #3946 + if ((jflags & JAVA_ACC_PROTECTED) != 0) + if (sym.enclosingTopLevelClass != NoSymbol) + sym.privateWithin = sym.enclosingTopLevelClass.owner + + sym + } } object SymbolTableStats { -- cgit v1.2.3 From 85b63b81d5951a78547641e3feab0886f6013ea1 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 8 Feb 2013 17:45:46 -0800 Subject: [nomaster] Revert "SI-6548 reflection now correctly enters jinners" This reverts commit 54a84a36d5b435a787d93ca48d45399136c7e162. This is necessary to maintain binary compatibility with 2.10.0. run/t6989.check had to be updated as it also (indirectly) tested SI-6548 Conflicts: test/files/lib/javac-artifacts.jar.desired.sha1 test/files/run/t6548.check test/files/run/t6548/Test_2.scala --- bincompat-backward.whitelist.conf | 16 ++--- bincompat-forward.whitelist.conf | 16 ++--- .../scala/reflect/runtime/JavaMirrors.scala | 16 ++--- test/files/run/t6548.check | 2 - .../run/t6548/JavaAnnotationWithNestedEnum_1.java | 17 ----- test/files/run/t6548/Test_2.scala | 12 ---- test/files/run/t6989.check | 84 +++++++++++++++++++--- 7 files changed, 99 insertions(+), 64 deletions(-) delete mode 100644 test/files/run/t6548.check delete mode 100644 test/files/run/t6548/JavaAnnotationWithNestedEnum_1.java delete mode 100644 test/files/run/t6548/Test_2.scala diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 3b29f7388b..f559d673f0 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -52,14 +52,14 @@ filter { # matchName="scala.reflect.runtime.SymbolLoaders.initAndEnterClassAndModule" # problemName=MissingMethodProblem # }, - { - matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" - problemName=MissingMethodProblem - }, - { - matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" - problemName=IncompatibleResultTypeProblem - }, + # { + # matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" + # problemName=MissingMethodProblem + # }, + # { + # matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" + # problemName=IncompatibleResultTypeProblem + # }, # scala.reflect.internal diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 66d2ba7154..529fab1e14 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -61,14 +61,14 @@ filter { }, # scala.reflect.runtime - { - matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" - problemName=IncompatibleResultTypeProblem - }, - { - matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala1" - problemName=MissingMethodProblem - }, + # { + # matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala" + # problemName=IncompatibleResultTypeProblem + # }, + # { + # matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$jclassAsScala1" + # problemName=MissingMethodProblem + # }, # { # matchName="scala.reflect.runtime.SymbolLoaders.initClassAndModule" # problemName=MissingMethodProblem diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index eb73ac75fb..3442e3d22e 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -686,9 +686,9 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni def enter(sym: Symbol, mods: Int) = (if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym - for (jinner <- jclazz.getDeclaredClasses) - jclassAsScala(jinner) // inner class is entered as a side-effect - // no need to call enter explicitly + for (jinner <- jclazz.getDeclaredClasses) { + enter(jclassAsScala(jinner, clazz), jinner.getModifiers) + } pendingLoadActions = { () => @@ -1046,14 +1046,14 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni * @param jclazz The Java class * @return A Scala class symbol that wraps all reflection info of `jclazz` */ - private def jclassAsScala(jclazz: jClass[_]): ClassSymbol = - toScala(classCache, jclazz)(_ jclassAsScala1 _) + private def jclassAsScala(jclazz: jClass[_]): Symbol = jclassAsScala(jclazz, sOwner(jclazz)) - private def jclassAsScala1(jclazz: jClass[_]): ClassSymbol = { - val owner = sOwner(jclazz) + private def jclassAsScala(jclazz: jClass[_], owner: Symbol): ClassSymbol = { val name = scalaSimpleName(jclazz) val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz) - createClassModule(owner, name, completer) match { case (clazz, module) => clazz } + val (clazz, module) = createClassModule(owner, name, completer) + classCache enter (jclazz, clazz) + clazz } /** diff --git a/test/files/run/t6548.check b/test/files/run/t6548.check deleted file mode 100644 index 5dfcb12e02..0000000000 --- a/test/files/run/t6548.check +++ /dev/null @@ -1,2 +0,0 @@ -false -List(JavaAnnotationWithNestedEnum_1(value = VALUE)) diff --git a/test/files/run/t6548/JavaAnnotationWithNestedEnum_1.java b/test/files/run/t6548/JavaAnnotationWithNestedEnum_1.java deleted file mode 100644 index 32004de537..0000000000 --- a/test/files/run/t6548/JavaAnnotationWithNestedEnum_1.java +++ /dev/null @@ -1,17 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, - ElementType.TYPE, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface JavaAnnotationWithNestedEnum_1 -{ - public Value value() default Value.VALUE; - - public enum Value - { - VALUE; - } -} \ No newline at end of file diff --git a/test/files/run/t6548/Test_2.scala b/test/files/run/t6548/Test_2.scala deleted file mode 100644 index 6e4f6ba92a..0000000000 --- a/test/files/run/t6548/Test_2.scala +++ /dev/null @@ -1,12 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.runtime.{currentMirror => cm} - -class Bean { - @JavaAnnotationWithNestedEnum_1(JavaAnnotationWithNestedEnum_1.Value.VALUE) - def value = 1 -} - -object Test extends App { - println(cm.staticClass("Bean").isCaseClass) - println(typeOf[Bean].declaration(newTermName("value")).annotations) -} diff --git a/test/files/run/t6989.check b/test/files/run/t6989.check index 8943792115..3a94f6e8df 100644 --- a/test/files/run/t6989.check +++ b/test/files/run/t6989.check @@ -113,6 +113,18 @@ isProtected = false isPublic = false privateWithin = ============ +sym = class $PrivateJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 +isPrivate = true +isProtected = false +isPublic = false +privateWithin = +============ +sym = value this$0, signature = foo.JavaClass_1, owner = class $PrivateJavaClass +isPrivate = false +isProtected = false +isPublic = false +privateWithin = package foo +============ sym = class $ProtectedJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 isPrivate = false isProtected = true @@ -131,6 +143,18 @@ isProtected = false isPublic = false privateWithin = package foo ============ +sym = class $ProtectedJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 +isPrivate = false +isProtected = true +isPublic = false +privateWithin = package foo +============ +sym = value this$0, signature = foo.JavaClass_1, owner = class $ProtectedJavaClass +isPrivate = false +isProtected = false +isPublic = false +privateWithin = package foo +============ sym = class $PublicJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 isPrivate = false isProtected = false @@ -155,55 +179,97 @@ isProtected = false isPublic = true privateWithin = ============ -sym = constructor JavaClass_1, signature = ()foo.JavaClass_1, owner = class JavaClass_1 +sym = class $PublicJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 isPrivate = false isProtected = false isPublic = true privateWithin = ============ -sym = object JavaClass_1, signature = foo.JavaClass_1.type, owner = package foo +sym = constructor $PublicJavaClass, signature = (x$1: foo.JavaClass_1)JavaClass_1.this.$PublicJavaClass, owner = class $PublicJavaClass +isPrivate = false +isProtected = false +isPublic = true +privateWithin = +============ +sym = value this$0, signature = foo.JavaClass_1, owner = class $PublicJavaClass +isPrivate = false +isProtected = false +isPublic = false +privateWithin = package foo +============ +sym = constructor JavaClass_1, signature = ()foo.JavaClass_1, owner = class JavaClass_1 isPrivate = false isProtected = false isPublic = true privateWithin = ============ -sym = class PrivateStaticJavaClass, signature = ClassInfoType(...), owner = object JavaClass_1 +sym = class PrivateStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 isPrivate = true isProtected = false isPublic = false privateWithin = ============ -sym = object PrivateStaticJavaClass, signature = foo.JavaClass_1.PrivateStaticJavaClass.type, owner = object JavaClass_1 +sym = object PrivateStaticJavaClass, signature = JavaClass_1.this.PrivateStaticJavaClass.type, owner = class JavaClass_1 isPrivate = true isProtected = false isPublic = false privateWithin = ============ -sym = class ProtectedStaticJavaClass, signature = ClassInfoType(...), owner = object JavaClass_1 +sym = class ProtectedStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 isPrivate = true isProtected = false isPublic = false privateWithin = ============ -sym = object ProtectedStaticJavaClass, signature = foo.JavaClass_1.ProtectedStaticJavaClass.type, owner = object JavaClass_1 +sym = object ProtectedStaticJavaClass, signature = JavaClass_1.this.ProtectedStaticJavaClass.type, owner = class JavaClass_1 isPrivate = true isProtected = false isPublic = false privateWithin = ============ -sym = class PublicStaticJavaClass, signature = ClassInfoType(...), owner = object JavaClass_1 +sym = class PublicStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 +isPrivate = false +isProtected = false +isPublic = true +privateWithin = +============ +sym = constructor PublicStaticJavaClass, signature = ()JavaClass_1.this.PublicStaticJavaClass, owner = class PublicStaticJavaClass +isPrivate = false +isProtected = false +isPublic = true +privateWithin = +============ +sym = object PublicStaticJavaClass, signature = JavaClass_1.this.PublicStaticJavaClass.type, owner = class JavaClass_1 isPrivate = false isProtected = false isPublic = true privateWithin = ============ -sym = constructor PublicStaticJavaClass, signature = ()foo.JavaClass_1.PublicStaticJavaClass, owner = class PublicStaticJavaClass +sym = object JavaClass_1, signature = foo.JavaClass_1.type, owner = package foo +isPrivate = false +isProtected = false +isPublic = true +privateWithin = +============ +sym = class PrivateStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 +isPrivate = true +isProtected = false +isPublic = false +privateWithin = +============ +sym = class ProtectedStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 +isPrivate = true +isProtected = false +isPublic = false +privateWithin = +============ +sym = class PublicStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 isPrivate = false isProtected = false isPublic = true privateWithin = ============ -sym = object PublicStaticJavaClass, signature = foo.JavaClass_1.PublicStaticJavaClass.type, owner = object JavaClass_1 +sym = constructor PublicStaticJavaClass, signature = ()JavaClass_1.this.PublicStaticJavaClass, owner = class PublicStaticJavaClass isPrivate = false isProtected = false isPublic = true -- cgit v1.2.3