diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-02-11 13:02:40 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-02-11 13:02:40 -0800 |
commit | b87e9b39d9ee606aab5d86f84ca94df416451e65 (patch) | |
tree | 34dbc0c8054303eb92a6a6fea2d48b885f8c5ac4 | |
parent | db5919a7d3b18be94e79899c2f7e33c535e15a27 (diff) | |
parent | 85b63b81d5951a78547641e3feab0886f6013ea1 (diff) | |
download | scala-2.10.1-RC1.tar.gz scala-2.10.1-RC1.tar.bz2 scala-2.10.1-RC1.zip |
Merge pull request #2103 from adriaanm/bin-compatv2.10.1-RC1
Forward and backward binary compatibility between 2.10.0 and 2.10.1-RC1
20 files changed, 792 insertions, 236 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf new file mode 100644 index 0000000000..f559d673f0 --- /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..529fab1e14 --- /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 + # }, + # 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 + } + ] +} @@ -2656,11 +2656,11 @@ Binary compatibility testing <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"/> + <dependency groupId="com.typesafe" artifactId="mima-reporter_2.9.2" version="0.1.5-SNAPSHOT"/> </artifact:dependencies> <artifact:dependencies pathId="old.bc.classpath"> - <dependency groupId="org.scala-lang" artifactId="scala-library" version="2.10.0-RC2"/> - <dependency groupId="org.scala-lang" artifactId="scala-reflect" version="2.10.0-RC2"/> + <dependency groupId="org.scala-lang" artifactId="scala-library" version="2.10.0"/> + <dependency groupId="org.scala-lang" artifactId="scala-reflect" version="2.10.0"/> </artifact:dependencies> </target> @@ -2673,6 +2673,9 @@ Binary compatibility testing <arg value="${org.scala-lang:scala-library:jar}"/> <arg value="--curr"/> <arg value="${build-pack.dir}/lib/scala-library.jar"/> + <arg value="--filters"/> + <arg value="${basedir}/bincompat-backward.whitelist.conf"/> + <arg value="--generate-filters"/> <classpath> <path refid="mima.classpath"/> </classpath> @@ -2685,6 +2688,39 @@ Binary compatibility testing <arg value="${org.scala-lang:scala-reflect:jar}"/> <arg value="--curr"/> <arg value="${build-pack.dir}/lib/scala-reflect.jar"/> + <arg value="--filters"/> + <arg value="${basedir}/bincompat-backward.whitelist.conf"/> + <arg value="--generate-filters"/> + <classpath> + <path refid="mima.classpath"/> + </classpath> + </java> + <java + fork="true" + failonerror="true" + classname="com.typesafe.tools.mima.cli.Main"> + <arg value="--curr"/> + <arg value="${org.scala-lang:scala-library:jar}"/> + <arg value="--prev"/> + <arg value="${build-pack.dir}/lib/scala-library.jar"/> + <arg value="--filters"/> + <arg value="${basedir}/bincompat-forward.whitelist.conf"/> + <arg value="--generate-filters"/> + <classpath> + <path refid="mima.classpath"/> + </classpath> + </java> + <java + fork="true" + failonerror="true" + classname="com.typesafe.tools.mima.cli.Main"> + <arg value="--curr"/> + <arg value="${org.scala-lang:scala-reflect:jar}"/> + <arg value="--prev"/> + <arg value="${build-pack.dir}/lib/scala-reflect.jar"/> + <arg value="--filters"/> + <arg value="${basedir}/bincompat-forward.whitelist.conf"/> + <arg value="--generate-filters"/> <classpath> <path refid="mima.classpath"/> </classpath> 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 @@ -643,6 +643,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 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) { 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] = { 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() } } 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 { 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/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 { diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 778c826dc0..3442e3d22e 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 { @@ -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) - initAndEnterClassAndModule(owner, name, completer)._1 + val (clazz, module) = createClassModule(owner, name, completer) + classCache enter (jclazz, clazz) + 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 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) } - } -} 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 = <none> ============ +sym = class $PrivateJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 +isPrivate = true +isProtected = false +isPublic = false +privateWithin = <none> +============ +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 = <none> ============ -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 = <none> ============ -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 = <none> +============ +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 = <none> ============ -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 = <none> ============ -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 = <none> ============ -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 = <none> ============ -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 = <none> ============ -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 = <none> +============ +sym = constructor PublicStaticJavaClass, signature = ()JavaClass_1.this.PublicStaticJavaClass, owner = class PublicStaticJavaClass +isPrivate = false +isProtected = false +isPublic = true +privateWithin = <none> +============ +sym = object PublicStaticJavaClass, signature = JavaClass_1.this.PublicStaticJavaClass.type, owner = class JavaClass_1 isPrivate = false isProtected = false isPublic = true privateWithin = <none> ============ -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 = <none> +============ +sym = class PrivateStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 +isPrivate = true +isProtected = false +isPublic = false +privateWithin = <none> +============ +sym = class ProtectedStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 +isPrivate = true +isProtected = false +isPublic = false +privateWithin = <none> +============ +sym = class PublicStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1 isPrivate = false isProtected = false isPublic = true privateWithin = <none> ============ -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 |