From 21d5d3820b285b7c96fb2fadbaec7f5db12ebaa6 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 7 Feb 2013 14:05:54 +0100 Subject: moves Symbol#SymbolKind to Symbols Too bad I didn't notice that before. That will free up quite a bit of memory, removing an extraneous field in every single Symbol, namely the: private volatile Symbols.Symbol.SymbolKind$ SymbolKind$module --- src/reflect/scala/reflect/internal/Symbols.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index d9eb48ff2d..b980f3d8c2 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -108,6 +108,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => def setter: Symbol = setter(owner) } + private[Symbols] case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) + /** The class for all symbols */ abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name) extends SymbolContextApiImpl @@ -2248,7 +2250,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (isTerm && (!isParameter || isParamAccessor)) "val" else "" - private case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) private def symbolKind: SymbolKind = { var kind = if (isTermMacro) ("macro method", "macro method", "MAC") -- cgit v1.2.3 From 0262941b3c5016d84f111bb9956190d333c7acf2 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 3 Feb 2013 13:59:35 +0100 Subject: removes the crazy extraneous log --- src/reflect/scala/reflect/runtime/JavaUniverse.scala | 2 +- test/files/run/reflection-crazy-logs.check | 1 + test/files/run/reflection-crazy-logs.scala | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 test/files/run/reflection-crazy-logs.check create mode 100644 test/files/run/reflection-crazy-logs.scala diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index e18435d5b0..1b69ca4e89 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -17,7 +17,7 @@ class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.S def forInteractive = false def forScaladoc = false - def log(msg: => AnyRef): Unit = println(" [] "+msg) + def log(msg: => AnyRef): Unit = if (settings.debug.value) println(" [] "+msg) type TreeCopier = InternalTreeCopierOps def newStrictTreeCopier: TreeCopier = new StrictTreeCopier diff --git a/test/files/run/reflection-crazy-logs.check b/test/files/run/reflection-crazy-logs.check new file mode 100644 index 0000000000..27ba77ddaf --- /dev/null +++ b/test/files/run/reflection-crazy-logs.check @@ -0,0 +1 @@ +true diff --git a/test/files/run/reflection-crazy-logs.scala b/test/files/run/reflection-crazy-logs.scala new file mode 100644 index 0000000000..6844faabf6 --- /dev/null +++ b/test/files/run/reflection-crazy-logs.scala @@ -0,0 +1,5 @@ +import scala.reflect.runtime.universe._ + +object Test extends App { + println(typeOf[List[Any]] <:< typeOf[List[T] forSome { type T }]) +} \ No newline at end of file -- cgit v1.2.3 From a9dca512d8a99fd7b9866cfad6b8ae9b5f451f4b Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 29 Jan 2013 20:54:47 +0100 Subject: synchronizes symbols Synchronization via decoration would be neat if it actually worked. Unfortunately, root symbols never got decorated, therefore their children also never got decorated and all the way down to the very turtles. This commit fixes this sad issue by turning root symbols from objects to lazy vals. Yes, this is going to induce a performance penalty, which will hopefully not be high enough to invalidate this cornerstone of our synchronization strategy. Now when root symbols are lazy vals, they can be overridden in the runtime reflexive universe and decorated with SynchronizedSymbol, which makes their children sync and sound. --- src/reflect/scala/reflect/internal/Mirrors.scala | 35 ++++++++++++++-------- .../scala/reflect/runtime/JavaMirrors.scala | 5 ++++ .../reflect/runtime/SynchronizedSymbols.scala | 11 ++++--- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 0beb8e368f..4771404b29 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -262,34 +262,45 @@ trait Mirrors extends api.Mirrors { def mirror = thisMirror.asInstanceOf[Mirror] } - // This is the package _root_. The actual root cannot be referenced at - // the source level, but _root_ is essentially a function => . - final object RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol { + class RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol { this setInfo NullaryMethodType(RootClass.tpe) RootClass.sourceModule = this override def isRootPackage = true } + + // This is the package _root_. The actual root cannot be referenced at + // the source level, but _root_ is essentially a function => . + lazy val RootPackage = new RootPackage + + class RootClass extends PackageClassSymbol(rootOwner, NoPosition, tpnme.ROOT) with RootSymbol { + this setInfo rootLoader + + override def isRoot = true + override def isEffectiveRoot = true + override def isNestedClass = false + } + // This is , the actual root of everything except the package _root_. // and _root_ (RootPackage and RootClass) should be the only "well known" // symbols owned by NoSymbol. All owner chains should go through RootClass, // although it is probable that some symbols are created as direct children // of NoSymbol to ensure they will not be stumbled upon. (We should designate // a better encapsulated place for that.) - final object RootClass extends PackageClassSymbol(rootOwner, NoPosition, tpnme.ROOT) with RootSymbol { - this setInfo rootLoader + lazy val RootClass = new RootClass - override def isRoot = true - override def isEffectiveRoot = true - override def isNestedClass = false - } - // The empty package, which holds all top level types without given packages. - final object EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { + class EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { override def isEmptyPackage = true } - final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { + + // The empty package, which holds all top level types without given packages. + lazy val EmptyPackage = new EmptyPackage + + class EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { override def isEffectiveRoot = true override def isEmptyPackageClass = true } + + lazy val EmptyPackageClass = new EmptyPackageClass } } diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 778c826dc0..b38b7d0f94 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -71,6 +71,11 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni import definitions._ + override lazy val RootPackage = new RootPackage with SynchronizedTermSymbol + override lazy val RootClass = new RootClass with SynchronizedModuleClassSymbol + override lazy val EmptyPackage = new EmptyPackage with SynchronizedTermSymbol + override lazy val EmptyPackageClass = new EmptyPackageClass with SynchronizedModuleClassSymbol + /** The lazy type for root. */ override lazy val rootLoader = new LazyType with FlagAgnosticCompleter { diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 00f6952dc1..ba8ff82b1b 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -92,11 +92,14 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb override protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags - override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = createModuleSymbol(name, pos, newFlags) + override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = + createModuleSymbol(name, pos, newFlags) - // TODO - // override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long) - // override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long) + override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long) = + new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags + + override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long) = + new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags } // ------- subclasses --------------------------------------------------------------------- -- cgit v1.2.3 From b2c2493b22e2b6b8feb8124a2503fbb794c0bde7 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 29 Jan 2013 20:52:10 +0100 Subject: reflection no longer uses atPhase and friends Mentioned methods mutate the global `atPhaseStack` variable, which can easily lead to imbalances and, ultimately, to the empty stack error. Luckily for us, there's only one dummy phase, SomePhase, which is used by runtime reflection, so there is absolutely zero need to invoke atPhase in non-compiler reflexive universes. The cleanest solution would be to override `atPhase` for runtime reflection, but it's @inline final, so I didn't want to pay performance penalties for something that's used three times in runtime reflection (during unpickling, in reflection-specific completers and in `Symbol.typeParams/unsafeTypeParams`). Therefore I added overrideable analogues of `atPhase` and `atPhaseNotLaterThan` which are called from the aforementioned code shared between the compiler and runtime reflection. I also had to duplicate the code of `Symbol.XXXtypeParams`, again due to them being very performance-sensitive. --- .../scala/reflect/internal/SymbolTable.scala | 5 +++++ .../reflect/internal/pickling/UnPickler.scala | 4 ++-- .../scala/reflect/runtime/SymbolLoaders.scala | 26 +--------------------- .../reflect/runtime/SynchronizedSymbols.scala | 24 +++++++++++++++++++- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index f75855f1ec..e096bac990 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -209,6 +209,8 @@ abstract class SymbolTable extends macros.Universe finally popPhase(saved) } + def slowButSafeAtPhase[T](ph: Phase)(op: => T): T = + if (isCompilerUniverse) atPhase(ph)(op) else op /** Since when it is to be "at" a phase is inherently ambiguous, * a couple unambiguously named methods. @@ -221,6 +223,9 @@ abstract class SymbolTable extends macros.Universe @inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = if (isAtPhaseAfter(target)) atPhase(target)(op) else op + def slowButSafeAtPhaseNotLaterThan[T](target: Phase)(op: => T): T = + if (isCompilerUniverse) atPhaseNotLaterThan(target)(op) else op + final def isValid(period: Period): Boolean = period != 0 && runId(period) == currentRunId && { val pid = phaseId(period) diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index 603fff4f1c..4d61e4178a 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -853,7 +853,7 @@ abstract class UnPickler { private val p = phase override def complete(sym: Symbol) : Unit = try { val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType` - atPhase(p) (sym setInfo tp) + slowButSafeAtPhase(p)(sym setInfo tp) if (currentRunId != definedAtRunId) sym.setInfo(adaptToNewRunMap(tp)) } @@ -871,7 +871,7 @@ abstract class UnPickler { super.complete(sym) var alias = at(j, readSymbol) if (alias.isOverloaded) - alias = atPhase(picklerPhase)((alias suchThat (alt => sym.tpe =:= sym.owner.thisType.memberType(alt)))) + alias = slowButSafeAtPhase(picklerPhase)((alias suchThat (alt => sym.tpe =:= sym.owner.thisType.memberType(alt)))) sym.asInstanceOf[TermSymbol].setAlias(alias) } diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index 311db64b91..23c0e1889f 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -15,37 +15,13 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => * is found, a package is created instead. */ class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader with FlagAssigningCompleter { -// def makePackage() { -// println("wrong guess; making package "+clazz) -// val ptpe = newPackageType(module.moduleClass) -// for (sym <- List(clazz, module, module.moduleClass)) { -// sym setFlag Flags.PACKAGE -// sym setInfo ptpe -// } -// } - override def complete(sym: Symbol) = { debugInfo("completing "+sym+"/"+clazz.fullName) assert(sym == clazz || sym == module || sym == module.moduleClass) -// try { - atPhaseNotLaterThan(picklerPhase) { + slowButSafeAtPhaseNotLaterThan(picklerPhase) { val loadingMirror = mirrorThatLoaded(sym) val javaClass = loadingMirror.javaClass(clazz.javaClassName) loadingMirror.unpickleClass(clazz, module, javaClass) -// } catch { -// case ex: ClassNotFoundException => makePackage() -// case ex: NoClassDefFoundError => makePackage() - // Note: We catch NoClassDefFoundError because there are situations - // where a package and a class have the same name except for capitalization. - // It seems in this case the class is loaded even if capitalization differs - // but then a NoClassDefFound error is issued with a ("wrong name: ...") - // reason. (I guess this is a concession to Windows). - // The present behavior is a bit too forgiving, in that it masks - // all class load errors, not just wrong name errors. We should try - // to be more discriminating. To get on the right track simply delete - // the clause above and load a collection class such as collection.Iterable. - // You'll see an error that class `parallel` has the wrong name. -// } } } override def load(sym: Symbol) = complete(sym) diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index ba8ff82b1b..cf4a3bc7e2 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -44,7 +44,29 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb override def updateInfo(info: Type): Symbol = synchronized { super.updateInfo(info) } override def rawInfo: Type = synchronized { super.rawInfo } - override def typeParams: List[Symbol] = synchronized { super.typeParams } + override def typeParams: List[Symbol] = synchronized { + if (isCompilerUniverse) super.typeParams + else { + if (isMonomorphicType) Nil + else { + // analogously to the "info" getter, here we allow for two completions: + // one: sourceCompleter to LazyType, two: LazyType to completed type + if (validTo == NoPeriod) + rawInfo load this + if (validTo == NoPeriod) + rawInfo load this + + rawInfo.typeParams + } + } + } + override def unsafeTypeParams: List[Symbol] = synchronized { + if (isCompilerUniverse) super.unsafeTypeParams + else { + if (isMonomorphicType) Nil + else rawInfo.typeParams + } + } override def reset(completer: Type): this.type = synchronized { super.reset(completer) } -- cgit v1.2.3 From 981da8edfcf3a2b6c727a8f12c6b81a9535fa50b Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 29 Jan 2013 20:42:55 +0100 Subject: cleans up initialization of runtime reflection At first I just tried to remove syntheticCoreClasses from missingHook and put them into the initializer of freshly created mirrors in order to reduce the non-determinism in mutations of the global symbol table. And then it didn't work, crashing on me claiming that AnyRef is missing. Apparently we still need AnyRefClass in missingHook, just because it's impossible to initialize (i.e. unpickle) ScalaPackageClass without it. And then it still didn't work, whining about multiple overloaded defs of some synthetic symbols. That was really tricky, but I figured it out as well by initializing ScalaPackageClass first before forcing any synthetic symbols (see the details in comments). --- .../scala/reflect/internal/Definitions.scala | 18 +++++++++++- src/reflect/scala/reflect/internal/Mirrors.scala | 13 +++++++++ src/reflect/scala/reflect/internal/StdNames.scala | 2 ++ src/reflect/scala/reflect/internal/Symbols.scala | 9 +++--- .../scala/reflect/runtime/JavaMirrors.scala | 33 ++++++---------------- .../scala/reflect/runtime/JavaUniverse.scala | 4 +++ .../scala/reflect/runtime/SymbolLoaders.scala | 9 ++++++ 7 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 6e4ca76382..52873dea12 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1248,8 +1248,24 @@ trait Definitions extends api.StandardDefinitions { def init() { if (isInitialized) return + // forcing ScalaPackageClass first thing during startup is important, because syntheticCoreClasses such as AnyRefClass + // need to be entered into ScalaPackageClass, which entails calling ScalaPackageClass.info.decls.enter + // if ScalaPackageClass isn't initialized by that moment, the following will happen for runtime reflection: + // 1) initialization of ScalaPackageClass will trigger unpickling + // 2) unpickling will need to load some auxiliary types such as, for example, String + // 3) to load String, runtime reflection will call mirrorDefining(classOf[String]) + // 4) this, in turn, will call runtimeMirror(classOf[String].getClassLoader) + // 5) for some classloader configurations, the resulting mirror will be different from rootMirror + // 6) in that case, initialization of the resulting mirror will try to import definitions.syntheticCoreClasses into the mirror + // 7) this will force all the lazy vals corresponding to syntheticCoreClasses + // 8) by that time, the completer of ScalaPackageClass will have already called setInfo on ScalaPackageClass, so there won't be any stack overflow + // so far so good, but there's a subtle detail. if forcing of ScalaPackageClass was called by a syntheticCoreClasses lazy val, + // then this lazy val will be entered twice: once during step 7 and once when returning from the original call + // to avoid this we need to initialize ScalaPackageClass first and only then synthesize the core classes + ScalaPackageClass.initialize // force initialization of every symbol that is synthesized or hijacked by the compiler - val forced = symbolsNotPresentInBytecode + val forced1 = symbolsNotPresentInBytecode + val forced2 = NoSymbol isInitialized = true } //init diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 4771404b29..80c05666af 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -239,6 +239,19 @@ trait Mirrors extends api.Mirrors { RootClass.info.decls enter EmptyPackage RootClass.info.decls enter RootPackage + + if (rootOwner != NoSymbol) { + // synthetic core classes are only present in root mirrors + // because Definitions.scala, which initializes and enters them, only affects rootMirror + // therefore we need to enter them manually for non-root mirrors + definitions.syntheticCoreClasses foreach (theirSym => { + val theirOwner = theirSym.owner + assert(theirOwner.isPackageClass, s"theirSym = $theirSym, theirOwner = $theirOwner") + val ourOwner = staticPackage(theirOwner.fullName) + val ourSym = theirSym // just copy the symbol into our branch of the symbol table + ourOwner.info.decls enter ourSym + }) + } } } diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index bcda2bc1ae..09d1e649d9 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -265,6 +265,8 @@ trait StdNames { final val SourceFileATTR: NameType = "SourceFile" final val SyntheticATTR: NameType = "Synthetic" + final val scala_ : NameType = "scala" + def dropSingletonName(name: Name): TypeName = (name dropRight SINGLETON_SUFFIX.length).toTypeName def singletonName(name: Name): TypeName = (name append SINGLETON_SUFFIX).toTypeName def implClassName(name: Name): TypeName = (name append IMPL_CLASS_SUFFIX).toTypeName diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index b980f3d8c2..43832eba7f 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -3208,10 +3208,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => def name = nme.NO_NAME override def name_=(n: Name) = abort("Cannot set NoSymbol's name to " + n) - synchronized { - setInfo(NoType) - privateWithin = this - } + // Syncnote: no need to synchronize this, because NoSymbol's initialization is triggered by JavaUniverse.init + // which is called in universe's constructor - something that's inherently single-threaded + setInfo(NoType) + privateWithin = this + override def info_=(info: Type) = { infos = TypeHistory(1, NoType, null) unlock() diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index b38b7d0f94..a61e3f7b83 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -46,16 +46,6 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni trait JavaClassCompleter extends FlagAssigningCompleter - def init() = { - definitions.AnyValClass // force it. - - // establish root association to avoid cyclic dependency errors later - rootMirror.classToScala(classOf[java.lang.Object]).initialize - - // println("initializing definitions") - definitions.init() - } - def runtimeMirror(cl: ClassLoader): Mirror = mirrors get cl match { case Some(WeakReference(m)) => m case _ => createMirror(rootMirror.RootClass, cl) @@ -1251,11 +1241,6 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni case _ => abort(s"${sym}.enclosingRootClass = ${sym.enclosingRootClass}, which is not a RootSymbol") } - private lazy val syntheticCoreClasses: Map[(String, Name), Symbol] = { - def mapEntry(sym: Symbol): ((String, Name), Symbol) = (sym.owner.fullName, sym.name) -> sym - Map() ++ (definitions.syntheticCoreClasses map mapEntry) - } - /** 1. If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package * ., otherwise return NoSymbol. * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead @@ -1272,15 +1257,15 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni if (name.isTermName && !owner.isEmptyPackageClass) return mirror.makeScalaPackage( if (owner.isRootSymbol) name.toString else owner.fullName+"."+name) - syntheticCoreClasses get (owner.fullName, name) match { - case Some(tsym) => - // synthetic core classes are only present in root mirrors - // because Definitions.scala, which initializes and enters them, only affects rootMirror - // therefore we need to enter them manually for non-root mirrors - if (mirror ne thisUniverse.rootMirror) owner.info.decls enter tsym - return tsym - case None => - } + if (name == tpnme.AnyRef && owner.owner.isRoot && owner.name == tpnme.scala_) + // when we synthesize the scala.AnyRef symbol, we need to add it to the scope of the scala package + // the problem is that adding to the scope implies doing something like `owner.info.decls enter anyRef` + // which entails running a completer for the scala package + // which will try to unpickle the stuff in scala/package.class + // which will transitively load scala.AnyRef + // which doesn't exist yet, because it hasn't been added to the scope yet + // this missing hook ties the knot without introducing synchronization problems like before + return definitions.AnyRefClass } info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) super.missingHook(owner, name) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index 1b69ca4e89..7321214a65 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -24,5 +24,9 @@ class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.S def newLazyTreeCopier: TreeCopier = new LazyTreeCopier init() + + def init() { + definitions.init() + } } diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index 23c0e1889f..484053640f 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -76,6 +76,15 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => class PackageScope(pkgClass: Symbol) extends Scope(initFingerPrints = -1L) // disable fingerprinting as we do not know entries beforehand with SynchronizedScope { assert(pkgClass.isType) + + // materializing multiple copies of the same symbol in PackageScope is a very popular bug + // this override does its best to guard against it + override def enter[T <: Symbol](sym: T): T = { + val existing = super.lookupEntry(sym.name) + assert(existing == null || existing.sym.isMethod, s"pkgClass = $pkgClass, sym = $sym, existing = $existing") + super.enter(sym) + } + // disable fingerprinting as we do not know entries beforehand private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. override def lookupEntry(name: Name): ScopeEntry = { -- cgit v1.2.3 From 5b37cfb19a41fc1b775dbdaf247e765fb6d245e0 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 29 Jan 2013 20:47:37 +0100 Subject: introduces GIL to Scala reflection On a serious note, I feel really uncomfortable about having to juggle this slew of locks. Despite that I can't immediately find a deadlock, I'm 100% sure there is one hiding in the shadows. Hence, I'm abandoning all runtime reflection locks in favor of a single per-universe one. --- .../scala/reflect/internal/BaseTypeSeqs.scala | 2 +- src/reflect/scala/reflect/runtime/Gil.scala | 22 ++++++ .../scala/reflect/runtime/JavaMirrors.scala | 14 ++-- .../scala/reflect/runtime/SymbolLoaders.scala | 43 +++++++--- .../scala/reflect/runtime/SymbolTable.scala | 2 +- .../scala/reflect/runtime/SynchronizedOps.scala | 56 +++++++------ .../reflect/runtime/SynchronizedSymbols.scala | 92 +++++++++++----------- .../scala/reflect/runtime/SynchronizedTypes.scala | 48 +++++------ .../scala/reflect/runtime/TwoWayCache.scala | 66 ---------------- .../scala/reflect/runtime/TwoWayCaches.scala | 68 ++++++++++++++++ 10 files changed, 235 insertions(+), 178 deletions(-) create mode 100644 src/reflect/scala/reflect/runtime/Gil.scala delete mode 100644 src/reflect/scala/reflect/runtime/TwoWayCache.scala create mode 100644 src/reflect/scala/reflect/runtime/TwoWayCaches.scala diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala index 3c2b128c52..768ebb055b 100644 --- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala +++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala @@ -37,7 +37,7 @@ trait BaseTypeSeqs { * This is necessary because when run from reflection every base type sequence needs to have a * SynchronizedBaseTypeSeq as mixin. */ - class BaseTypeSeq protected[BaseTypeSeqs] (private[BaseTypeSeqs] val parents: List[Type], private[BaseTypeSeqs] val elems: Array[Type]) { + class BaseTypeSeq protected[reflect] (private[BaseTypeSeqs] val parents: List[Type], private[BaseTypeSeqs] val elems: Array[Type]) { self => if (Statistics.canEnable) Statistics.incCounter(baseTypeSeqCount) if (Statistics.canEnable) Statistics.incCounter(baseTypeSeqLenTotal, elems.length) diff --git a/src/reflect/scala/reflect/runtime/Gil.scala b/src/reflect/scala/reflect/runtime/Gil.scala new file mode 100644 index 0000000000..8a8bfebf8c --- /dev/null +++ b/src/reflect/scala/reflect/runtime/Gil.scala @@ -0,0 +1,22 @@ +package scala.reflect +package runtime + +private[reflect] trait Gil { + self: SymbolTable => + + // fixme... please... + // there are the following avenues of optimization we discussed with Roland: + // 1) replace PackageScope locks with ConcurrentHashMap, because PackageScope materializers seem to be idempotent + // 2) unlock unpickling completers by verifying that they are idempotent or moving non-idempotent parts + // 3) remove the necessity in global state for isSubType + lazy val gil = new java.util.concurrent.locks.ReentrantLock + + @inline final def gilSynchronized[T](body: => T): T = { + try { + gil.lock() + body + } finally { + gil.unlock() + } + } +} diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index a61e3f7b83..48d887b5c6 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -24,7 +24,7 @@ import scala.language.existentials import scala.runtime.{ScalaRunTime, BoxesRunTime} import scala.reflect.internal.util.Collections._ -private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUniverse: SymbolTable => +private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable => private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]() @@ -46,9 +46,11 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni trait JavaClassCompleter extends FlagAssigningCompleter - def runtimeMirror(cl: ClassLoader): Mirror = mirrors get cl match { - case Some(WeakReference(m)) => m - case _ => createMirror(rootMirror.RootClass, cl) + def runtimeMirror(cl: ClassLoader): Mirror = gilSynchronized { + mirrors get cl match { + case Some(WeakReference(m)) => m + case _ => createMirror(rootMirror.RootClass, cl) + } } /** The API of a mirror for a reflective universe */ @@ -662,7 +664,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni completeRest() } - def completeRest(): Unit = thisUniverse.synchronized { + def completeRest(): Unit = gilSynchronized { val tparams = clazz.rawInfo.typeParams val parents = try { @@ -878,7 +880,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni * The Scala package with given fully qualified name. Unlike `packageNameToScala`, * this one bypasses the cache. */ - private[JavaMirrors] def makeScalaPackage(fullname: String): ModuleSymbol = { + private[JavaMirrors] def makeScalaPackage(fullname: String): ModuleSymbol = gilSynchronized { val split = fullname lastIndexOf '.' val ownerModule: ModuleSymbol = if (split > 0) packageNameToScala(fullname take split) else this.RootPackage diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index 484053640f..bd5be44b35 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -73,6 +73,24 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => 0 < dp && dp < (name.length - 1) } + // Since runtime reflection doesn't have a luxury of enumerating all classes + // on the classpath, it has to materialize symbols for top-level definitions + // (packages, classes, objects) on demand. + // + // Someone asks us for a class named `foo.Bar`? Easy. Let's speculatively create + // a package named `foo` and then look up `newTypeName("bar")` in its decls. + // This lookup, implemented in `SymbolLoaders.PackageScope` tests the waters by + // trying to to `Class.forName("foo.Bar")` and then creates a ClassSymbol upon + // success (the whole story is a bit longer, but the rest is irrelevant here). + // + // That's all neat, but these non-deterministic mutations of the global symbol + // table give a lot of trouble in multi-threaded setting. One of the popular + // reflection crashes happens when multiple threads happen to trigger symbol + // materialization multiple times for the same symbol, making subsequent + // reflective operations stumble upon outrageous stuff like overloaded packages. + // + // Short of significantly changing SymbolLoaders I see no other way than just + // to slap a global lock on materialization in runtime reflection. class PackageScope(pkgClass: Symbol) extends Scope(initFingerPrints = -1L) // disable fingerprinting as we do not know entries beforehand with SynchronizedScope { assert(pkgClass.isType) @@ -85,15 +103,21 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => super.enter(sym) } - // disable fingerprinting as we do not know entries beforehand - private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. - override def lookupEntry(name: Name): ScopeEntry = { - val e = super.lookupEntry(name) - if (e != null) - e - else if (isInvalidClassName(name) || (negatives contains name)) - null - else { + // package scopes need to synchronize on the GIL + // because lookupEntry might cause changes to the global symbol table + override def syncLockSynchronized[T](body: => T): T = gilSynchronized(body) + private val negatives = new mutable.HashSet[Name] + override def lookupEntry(name: Name): ScopeEntry = syncLockSynchronized { + def lookupExisting: Option[ScopeEntry] = { + val e = super.lookupEntry(name) + if (e != null) + Some(e) + else if (isInvalidClassName(name) || (negatives contains name)) + Some(null) // TODO: omg + else + None + } + def materialize: ScopeEntry = { val path = if (pkgClass.isEmptyPackageClass) name.toString else pkgClass.fullName + "." + name @@ -122,6 +146,7 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => null } } + lookupExisting getOrElse materialize } } diff --git a/src/reflect/scala/reflect/runtime/SymbolTable.scala b/src/reflect/scala/reflect/runtime/SymbolTable.scala index 5c08e9a508..d317d6a12b 100644 --- a/src/reflect/scala/reflect/runtime/SymbolTable.scala +++ b/src/reflect/scala/reflect/runtime/SymbolTable.scala @@ -8,7 +8,7 @@ import scala.reflect.internal.Flags._ * It can be used either from a reflexive universe (class scala.reflect.runtime.JavaUniverse), or else from * a runtime compiler that uses reflection to get a class information (class scala.tools.reflect.ReflectGlobal) */ -private[scala] trait SymbolTable extends internal.SymbolTable with JavaMirrors with SymbolLoaders with SynchronizedOps { +private[scala] trait SymbolTable extends internal.SymbolTable with JavaMirrors with SymbolLoaders with SynchronizedOps with Gil { def info(msg: => String) = if (settings.verbose.value) println("[reflect-compiler] "+msg) diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala index 7b280e59b9..b674fc380f 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala @@ -8,6 +8,9 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable // Names + // this lock isn't subsumed by the reflection GIL + // because there's no way newXXXName methods are going to call anything reflective + // therefore we don't have a danger of a deadlock from having a fine-grained lock for name creation private lazy val nameLock = new Object override def newTermName(s: String): TermName = nameLock.synchronized { super.newTermName(s) } @@ -16,20 +19,25 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable // BaseTypeSeqs override protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) = - new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq + // only need to synchronize BaseTypeSeqs if they contain refined types + if (elems.filter(_.isInstanceOf[RefinedType]).nonEmpty) new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq + else new BaseTypeSeq(parents, elems) trait SynchronizedBaseTypeSeq extends BaseTypeSeq { - override def apply(i: Int): Type = synchronized { super.apply(i) } - override def rawElem(i: Int) = synchronized { super.rawElem(i) } - override def typeSymbol(i: Int): Symbol = synchronized { super.typeSymbol(i) } - override def toList: List[Type] = synchronized { super.toList } - override def copy(head: Type, offset: Int): BaseTypeSeq = synchronized { super.copy(head, offset) } - override def map(f: Type => Type): BaseTypeSeq = synchronized { super.map(f) } - override def exists(p: Type => Boolean): Boolean = synchronized { super.exists(p) } - override lazy val maxDepth = synchronized { maxDepthOfElems } - override def toString = synchronized { super.toString } - - override def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq + override def apply(i: Int): Type = gilSynchronized { super.apply(i) } + override def rawElem(i: Int) = gilSynchronized { super.rawElem(i) } + override def typeSymbol(i: Int): Symbol = gilSynchronized { super.typeSymbol(i) } + override def toList: List[Type] = gilSynchronized { super.toList } + override def copy(head: Type, offset: Int): BaseTypeSeq = gilSynchronized { super.copy(head, offset) } + override def map(f: Type => Type): BaseTypeSeq = gilSynchronized { super.map(f) } + override def exists(p: Type => Boolean): Boolean = gilSynchronized { super.exists(p) } + override lazy val maxDepth = gilSynchronized { maxDepthOfElems } + override def toString = gilSynchronized { super.toString } + + override def lateMap(f: Type => Type): BaseTypeSeq = + // only need to synchronize BaseTypeSeqs if they contain refined types + if (map(f).toList.filter(_.isInstanceOf[RefinedType]).nonEmpty) new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq + else new MappedBaseTypeSeq(this, f) } // Scopes @@ -38,15 +46,19 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable override def newNestedScope(outer: Scope): Scope = new Scope(outer) with SynchronizedScope trait SynchronizedScope extends Scope { - override def isEmpty: Boolean = synchronized { super.isEmpty } - override def size: Int = synchronized { super.size } - override def enter[T <: Symbol](sym: T): T = synchronized { super.enter(sym) } - override def rehash(sym: Symbol, newname: Name) = synchronized { super.rehash(sym, newname) } - override def unlink(e: ScopeEntry) = synchronized { super.unlink(e) } - override def unlink(sym: Symbol) = synchronized { super.unlink(sym) } - override def lookupAll(name: Name) = synchronized { super.lookupAll(name) } - override def lookupEntry(name: Name) = synchronized { super.lookupEntry(name) } - override def lookupNextEntry(entry: ScopeEntry) = synchronized { super.lookupNextEntry(entry) } - override def toList: List[Symbol] = synchronized { super.toList } + // we can keep this lock fine-grained, because methods of Scope don't do anything extraordinary, which makes deadlocks impossible + // fancy subclasses of internal.Scopes#Scope should do synchronization themselves (e.g. see PackageScope for an example) + private lazy val syncLock = new Object + def syncLockSynchronized[T](body: => T): T = syncLock.synchronized { body } + override def isEmpty: Boolean = syncLockSynchronized { super.isEmpty } + override def size: Int = syncLockSynchronized { super.size } + override def enter[T <: Symbol](sym: T): T = syncLockSynchronized { super.enter(sym) } + override def rehash(sym: Symbol, newname: Name) = syncLockSynchronized { super.rehash(sym, newname) } + override def unlink(e: ScopeEntry) = syncLockSynchronized { super.unlink(e) } + override def unlink(sym: Symbol) = syncLockSynchronized { super.unlink(sym) } + override def lookupAll(name: Name) = syncLockSynchronized { super.lookupAll(name) } + override def lookupEntry(name: Name) = syncLockSynchronized { super.lookupEntry(name) } + override def lookupNextEntry(entry: ScopeEntry) = syncLockSynchronized { super.lookupNextEntry(entry) } + override def toList: List[Symbol] = syncLockSynchronized { super.toList } } } diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index cf4a3bc7e2..3b5029a263 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -5,14 +5,18 @@ import scala.reflect.io.AbstractFile private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => - override protected def nextId() = synchronized { super.nextId() } + // we can keep this lock fine-grained, because nextId is just a simple increment, which makes deadlocks impossible + private lazy val nextIdLock = new Object + override protected def nextId() = nextIdLock.synchronized { super.nextId() } + // we can keep this lock fine-grained, because freshExistentialName is just a simple increment, which makes deadlocks impossible + private lazy val freshExistentialNameLock = new Object override protected def freshExistentialName(suffix: String) = - synchronized { super.freshExistentialName(suffix) } + freshExistentialNameLock.synchronized { super.freshExistentialName(suffix) } // Set the fields which point companions at one another. Returns the module. override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = - synchronized { super.connectModuleToClass(m, moduleClass) } + gilSynchronized { super.connectModuleToClass(m, moduleClass) } override def newFreeTermSymbol(name: TermName, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = new FreeTermSymbol(name, value, origin) with SynchronizedTermSymbol initFlags flags @@ -24,27 +28,27 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb trait SynchronizedSymbol extends Symbol { - override def rawflags = synchronized { super.rawflags } - override def rawflags_=(x: Long) = synchronized { super.rawflags_=(x) } + override def rawflags = gilSynchronized { super.rawflags } + override def rawflags_=(x: Long) = gilSynchronized { super.rawflags_=(x) } - override def rawowner = synchronized { super.rawowner } - override def owner_=(owner: Symbol) = synchronized { super.owner_=(owner) } + override def rawowner = gilSynchronized { super.rawowner } + override def owner_=(owner: Symbol) = gilSynchronized { super.owner_=(owner) } - override def validTo = synchronized { super.validTo } - override def validTo_=(x: Period) = synchronized { super.validTo_=(x) } + override def validTo = gilSynchronized { super.validTo } + override def validTo_=(x: Period) = gilSynchronized { super.validTo_=(x) } - override def pos = synchronized { super.pos } - override def setPos(pos: Position): this.type = { synchronized { super.setPos(pos) }; this } + override def pos = gilSynchronized { super.pos } + override def setPos(pos: Position): this.type = { gilSynchronized { super.setPos(pos) }; this } - override def privateWithin = synchronized { super.privateWithin } - override def privateWithin_=(sym: Symbol) = synchronized { super.privateWithin_=(sym) } + override def privateWithin = gilSynchronized { super.privateWithin } + override def privateWithin_=(sym: Symbol) = gilSynchronized { super.privateWithin_=(sym) } - override def info = synchronized { super.info } - override def info_=(info: Type) = synchronized { super.info_=(info) } - override def updateInfo(info: Type): Symbol = synchronized { super.updateInfo(info) } - override def rawInfo: Type = synchronized { super.rawInfo } + override def info = gilSynchronized { super.info } + override def info_=(info: Type) = gilSynchronized { super.info_=(info) } + override def updateInfo(info: Type): Symbol = gilSynchronized { super.updateInfo(info) } + override def rawInfo: Type = gilSynchronized { super.rawInfo } - override def typeParams: List[Symbol] = synchronized { + override def typeParams: List[Symbol] = gilSynchronized { if (isCompilerUniverse) super.typeParams else { if (isMonomorphicType) Nil @@ -60,7 +64,7 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb } } } - override def unsafeTypeParams: List[Symbol] = synchronized { + override def unsafeTypeParams: List[Symbol] = gilSynchronized { if (isCompilerUniverse) super.unsafeTypeParams else { if (isMonomorphicType) Nil @@ -68,12 +72,12 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb } } - override def reset(completer: Type): this.type = synchronized { super.reset(completer) } + override def reset(completer: Type): this.type = gilSynchronized { super.reset(completer) } - override def infosString: String = synchronized { super.infosString } + override def infosString: String = gilSynchronized { super.infosString } - override def annotations: List[AnnotationInfo] = synchronized { super.annotations } - override def setAnnotations(annots: List[AnnotationInfo]): this.type = { synchronized { super.setAnnotations(annots) }; this } + override def annotations: List[AnnotationInfo] = gilSynchronized { super.annotations } + override def setAnnotations(annots: List[AnnotationInfo]): this.type = { gilSynchronized { super.setAnnotations(annots) }; this } // ------ creators ------------------------------------------------------------------- @@ -127,39 +131,39 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb // ------- subclasses --------------------------------------------------------------------- trait SynchronizedTermSymbol extends TermSymbol with SynchronizedSymbol { - override def name_=(x: Name) = synchronized { super.name_=(x) } - override def rawname = synchronized { super.rawname } - override def referenced: Symbol = synchronized { super.referenced } - override def referenced_=(x: Symbol) = synchronized { super.referenced_=(x) } + override def name_=(x: Name) = gilSynchronized { super.name_=(x) } + override def rawname = gilSynchronized { super.rawname } + override def referenced: Symbol = gilSynchronized { super.referenced } + override def referenced_=(x: Symbol) = gilSynchronized { super.referenced_=(x) } } trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol { - override def typeAsMemberOf(pre: Type): Type = synchronized { super.typeAsMemberOf(pre) } - override def paramss: List[List[Symbol]] = synchronized { super.paramss } - override def returnType: Type = synchronized { super.returnType } + override def typeAsMemberOf(pre: Type): Type = gilSynchronized { super.typeAsMemberOf(pre) } + override def paramss: List[List[Symbol]] = gilSynchronized { super.paramss } + override def returnType: Type = gilSynchronized { super.returnType } } trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol { - override def name_=(x: Name) = synchronized { super.name_=(x) } - override def rawname = synchronized { super.rawname } - override def typeConstructor: Type = synchronized { super.typeConstructor } - override def tpe: Type = synchronized { super.tpe } + override def name_=(x: Name) = gilSynchronized { super.name_=(x) } + override def rawname = gilSynchronized { super.rawname } + override def typeConstructor: Type = gilSynchronized { super.typeConstructor } + override def tpe: Type = gilSynchronized { super.tpe } } trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol { - override def associatedFile = synchronized { super.associatedFile } - override def associatedFile_=(f: AbstractFile) = synchronized { super.associatedFile_=(f) } - override def thisSym: Symbol = synchronized { super.thisSym } - override def thisType: Type = synchronized { super.thisType } - override def typeOfThis: Type = synchronized { super.typeOfThis } - override def typeOfThis_=(tp: Type) = synchronized { super.typeOfThis_=(tp) } - override def children = synchronized { super.children } - override def addChild(sym: Symbol) = synchronized { super.addChild(sym) } + override def associatedFile = gilSynchronized { super.associatedFile } + override def associatedFile_=(f: AbstractFile) = gilSynchronized { super.associatedFile_=(f) } + override def thisSym: Symbol = gilSynchronized { super.thisSym } + override def thisType: Type = gilSynchronized { super.thisType } + override def typeOfThis: Type = gilSynchronized { super.typeOfThis } + override def typeOfThis_=(tp: Type) = gilSynchronized { super.typeOfThis_=(tp) } + override def children = gilSynchronized { super.children } + override def addChild(sym: Symbol) = gilSynchronized { super.addChild(sym) } } trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol { - override def sourceModule = synchronized { super.sourceModule } - override def implicitMembers: Scope = synchronized { super.implicitMembers } + override def sourceModule = gilSynchronized { super.sourceModule } + override def implicitMembers: Scope = gilSynchronized { super.implicitMembers } } } diff --git a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala index a3e7c28ca4..939363f8b4 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala @@ -12,8 +12,9 @@ private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTa // No sharing of map objects: override protected def commonOwnerMap = new CommonOwnerMap - private object uniqueLock - + // we can keep this lock fine-grained, because super.unique just updates the cache + // and, in particular, doesn't call any reflection APIs which makes deadlocks impossible + private lazy val uniqueLock = new Object private val uniques = WeakHashMap[Type, WeakReference[Type]]() override def unique[T <: Type](tp: T): T = uniqueLock.synchronized { // we need to have weak uniques for runtime reflection @@ -37,46 +38,35 @@ private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTa } class SynchronizedUndoLog extends UndoLog { - private val actualLock = new java.util.concurrent.locks.ReentrantLock - - final override def lock(): Unit = actualLock.lock() - final override def unlock(): Unit = actualLock.unlock() + final override def lock(): Unit = gil.lock() + final override def unlock(): Unit = gil.unlock() } override protected def newUndoLog = new SynchronizedUndoLog override protected def baseTypeOfNonClassTypeRef(tpe: NonClassTypeRef, clazz: Symbol) = - synchronized { super.baseTypeOfNonClassTypeRef(tpe, clazz) } - - private object subsametypeLock + gilSynchronized { super.baseTypeOfNonClassTypeRef(tpe, clazz) } override def isSameType(tp1: Type, tp2: Type): Boolean = - subsametypeLock.synchronized { super.isSameType(tp1, tp2) } + gilSynchronized { super.isSameType(tp1, tp2) } override def isDifferentType(tp1: Type, tp2: Type): Boolean = - subsametypeLock.synchronized { super.isDifferentType(tp1, tp2) } + gilSynchronized { super.isDifferentType(tp1, tp2) } override def isSubType(tp1: Type, tp2: Type, depth: Int): Boolean = - subsametypeLock.synchronized { super.isSubType(tp1, tp2, depth) } - - private object lubglbLock + gilSynchronized { super.isSubType(tp1, tp2, depth) } override def glb(ts: List[Type]): Type = - lubglbLock.synchronized { super.glb(ts) } + gilSynchronized { super.glb(ts) } override def lub(ts: List[Type]): Type = - lubglbLock.synchronized { super.lub(ts) } - - private object indentLock - - override protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = { - indentLock.synchronized { super.explain(op, p, tp1, arg2) } - } + gilSynchronized { super.lub(ts) } - private object toStringLock + override protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = + gilSynchronized { super.explain(op, p, tp1, arg2) } override protected def typeToString(tpe: Type): String = - toStringLock.synchronized(super.typeToString(tpe)) + gilSynchronized(super.typeToString(tpe)) /* The idea of caches is as follows. * When in reflexive mode, a cache is either null, or one sentinal @@ -89,18 +79,18 @@ private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTa */ override protected def defineUnderlyingOfSingleType(tpe: SingleType) = - tpe.synchronized { super.defineUnderlyingOfSingleType(tpe) } + gilSynchronized { super.defineUnderlyingOfSingleType(tpe) } override protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) = - tpe.synchronized { super.defineBaseTypeSeqOfCompoundType(tpe) } + gilSynchronized { super.defineBaseTypeSeqOfCompoundType(tpe) } override protected def defineBaseClassesOfCompoundType(tpe: CompoundType) = - tpe.synchronized { super.defineBaseClassesOfCompoundType(tpe) } + gilSynchronized { super.defineBaseClassesOfCompoundType(tpe) } override protected def defineParentsOfTypeRef(tpe: TypeRef) = - tpe.synchronized { super.defineParentsOfTypeRef(tpe) } + gilSynchronized { super.defineParentsOfTypeRef(tpe) } override protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) = - tpe.synchronized { super.defineBaseTypeSeqOfTypeRef(tpe) } + gilSynchronized { super.defineBaseTypeSeqOfTypeRef(tpe) } } diff --git a/src/reflect/scala/reflect/runtime/TwoWayCache.scala b/src/reflect/scala/reflect/runtime/TwoWayCache.scala deleted file mode 100644 index 05debcba65..0000000000 --- a/src/reflect/scala/reflect/runtime/TwoWayCache.scala +++ /dev/null @@ -1,66 +0,0 @@ -package scala.reflect -package runtime - -import scala.collection.mutable.WeakHashMap -import java.lang.ref.WeakReference - -/** A cache that maintains a bijection between Java reflection type `J` - * and Scala reflection type `S`. - * - * The cache is two-way weak (i.e. is powered by weak references), - * so that neither Java artifacts prevent Scala artifacts from being garbage collected, - * nor the other way around. - */ -private[runtime] class TwoWayCache[J, S] { - - private val toScalaMap = new WeakHashMap[J, WeakReference[S]] - private val toJavaMap = new WeakHashMap[S, WeakReference[J]] - - def enter(j: J, s: S) = synchronized { - // debugInfo("cached: "+j+"/"+s) - toScalaMap(j) = new WeakReference(s) - toJavaMap(s) = new WeakReference(j) - } - - private object SomeRef { - def unapply[T](optRef: Option[WeakReference[T]]): Option[T] = - if (optRef.nonEmpty) { - val result = optRef.get.get - if (result != null) Some(result) else None - } else None - } - - def toScala(key: J)(body: => S): S = synchronized { - toScalaMap get key match { - case SomeRef(v) => - v - case _ => - val result = body - enter(key, result) - result - } - } - - def toJava(key: S)(body: => J): J = synchronized { - toJavaMap get key match { - case SomeRef(v) => - v - case _ => - val result = body - enter(result, key) - result - } - } - - def toJavaOption(key: S)(body: => Option[J]): Option[J] = synchronized { - toJavaMap get key match { - case SomeRef(v) => - Some(v) - case _ => - val result = body - for (value <- result) enter(value, key) - result - } - } -} - diff --git a/src/reflect/scala/reflect/runtime/TwoWayCaches.scala b/src/reflect/scala/reflect/runtime/TwoWayCaches.scala new file mode 100644 index 0000000000..6e2890e536 --- /dev/null +++ b/src/reflect/scala/reflect/runtime/TwoWayCaches.scala @@ -0,0 +1,68 @@ +package scala.reflect +package runtime + +import scala.collection.mutable.WeakHashMap +import java.lang.ref.WeakReference + +/** A cache that maintains a bijection between Java reflection type `J` + * and Scala reflection type `S`. + * + * The cache is two-way weak (i.e. is powered by weak references), + * so that neither Java artifacts prevent Scala artifacts from being garbage collected, + * nor the other way around. + */ +private[runtime] trait TwoWayCaches { self: SymbolTable => + class TwoWayCache[J, S] { + + private val toScalaMap = new WeakHashMap[J, WeakReference[S]] + private val toJavaMap = new WeakHashMap[S, WeakReference[J]] + + def enter(j: J, s: S) = gilSynchronized { + // debugInfo("cached: "+j+"/"+s) + toScalaMap(j) = new WeakReference(s) + toJavaMap(s) = new WeakReference(j) + } + + private object SomeRef { + def unapply[T](optRef: Option[WeakReference[T]]): Option[T] = + if (optRef.nonEmpty) { + val result = optRef.get.get + if (result != null) Some(result) else None + } else None + } + + def toScala(key: J)(body: => S): S = gilSynchronized { + toScalaMap get key match { + case SomeRef(v) => + v + case _ => + val result = body + enter(key, result) + result + } + } + + def toJava(key: S)(body: => J): J = gilSynchronized { + toJavaMap get key match { + case SomeRef(v) => + v + case _ => + val result = body + enter(result, key) + result + } + } + + def toJavaOption(key: S)(body: => Option[J]): Option[J] = gilSynchronized { + toJavaMap get key match { + case SomeRef(v) => + Some(v) + case _ => + val result = body + for (value <- result) enter(value, key) + result + } + } + } +} + -- cgit v1.2.3 From 735634f1d634d2d6a2f8ed44f2e6185adc46c695 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 7 Feb 2013 14:10:47 +0100 Subject: initializes lazy vals and inner objects in advance As discussed at http://groups.google.com/group/scala-internals/browse_thread/thread/97840ba4fd37b52e, `synchronized(this)` employed by lazy val and inner object initialization is an excellent way to deadlock yourself in the foot. Imagine a thread, which grabs a reflection GIL and then calls one of those lazy vals / objects that reflection exposes (e.g. a companion module of an innocently looking SingleType case class). Then imagine another thread, which calls something else in SymbolTable, grabbing symbol table's monitor, and then tries to get a reflection GIL to do something non-trivial. Hello, we've just arrived at a deadlock. Since, as discussed in the aforementioned thread, there's no easy way to change lazy vals / inner objects in reflection to use GIL instead of synchronizing on this, I bit the bullet and manually initialized all things with deferred initialization defined in reflect.runtime.SymbolTable. The list of all things `$lzycompute` has been mined by a simple Python script, then I copy/pasted that list into `JavaUniverse.scala` and went ahead forcing objects and lazy vals mentioned there. Notably, I've been able to force all lazy vals in Definitions.scala. There are some todos left, but I suggest we move forward without securing them, because the 2.10.1-RC1 release date is very close, so we'd better have a 95% solution instead of keeping reflection thread-unsafe. Though here's the list of todo lazy vals for the reference: * BaseTypeSeq.maxDepth * WeakTypeTag.tpe * AnnotationInfo.forcedInfo For each of those lazy vals we need to make sure that their initializers never call back into themselves. Otherwise, there's a danger of a deadlock. --- .../scala/reflect/internal/Definitions.scala | 2 +- src/reflect/scala/reflect/internal/Symbols.scala | 2 +- src/reflect/scala/reflect/internal/Types.scala | 4 +- .../scala/reflect/runtime/JavaMirrors.scala | 14 +- .../scala/reflect/runtime/JavaUniverse.scala | 1024 ++++++++++++++++++++ 5 files changed, 1041 insertions(+), 5 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 52873dea12..7a3bdff1f8 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1189,7 +1189,7 @@ trait Definitions extends api.StandardDefinitions { /** Is the symbol that of a parent which is added during parsing? */ lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass - private lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass + lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass /** Is symbol a value class? */ def isPrimitiveValueClass(sym: Symbol) = ScalaValueClasses contains sym diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 43832eba7f..0a600432fd 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -108,7 +108,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def setter: Symbol = setter(owner) } - private[Symbols] case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) + case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) /** The class for all symbols */ abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index fb493fabd8..0afbdc56c8 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3930,8 +3930,8 @@ trait Types extends api.Types { self: SymbolTable => /** @PP: Unable to see why these apparently constant types should need vals * in every TypeConstraint, I lifted them out. */ - private lazy val numericLoBound = IntClass.tpe - private lazy val numericHiBound = intersectionType(List(ByteClass.tpe, CharClass.tpe), ScalaPackageClass) + lazy val numericLoBound = IntClass.tpe + lazy val numericHiBound = intersectionType(List(ByteClass.tpe, CharClass.tpe), ScalaPackageClass) /** A class expressing upper and lower bounds constraints of type variables, * as well as their instantiations. diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 48d887b5c6..ac968b8e3f 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -26,7 +26,7 @@ import scala.reflect.internal.util.Collections._ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable => - private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]() + lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]() private def createMirror(owner: Symbol, cl: ClassLoader): Mirror = { val jm = new JavaMirror(owner, cl) @@ -68,6 +68,18 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni override lazy val EmptyPackage = new EmptyPackage with SynchronizedTermSymbol override lazy val EmptyPackageClass = new EmptyPackageClass with SynchronizedModuleClassSymbol + override def init() = { + super.init() + + // see an explanation of this in JavaUniverse.init() + RootPackage + RootClass + EmptyPackage + EmptyPackageClass + unpickler + rootLoader + } + /** The lazy type for root. */ override lazy val rootLoader = new LazyType with FlagAgnosticCompleter { diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index 7321214a65..cee243fb29 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -27,6 +27,1030 @@ class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.S def init() { definitions.init() + + // workaround for http://groups.google.com/group/scala-internals/browse_thread/thread/97840ba4fd37b52e + // constructors are by definition single-threaded, so we initialize all lazy vals (and local object) in advance + // in order to avoid deadlocks later (e.g. one thread holds a global reflection lock and waits for definitions.Something to initialize, + // whereas another thread holds a definitions.Something initialization lock and needs a global reflection lock to complete the initialization) + + // the list of lzycompute methods is mined by a simple python script + // #!/usr/bin/env python + // import os, sys, re, glob, fnmatch + // from subprocess import check_call, check_output + // root = check_output(["git", "rev-parse", "--show-toplevel"]).strip() + // root = os.path.join(root, "build/quick/classes/reflect/scala/reflect") + // classfiles = [] + // for container, dirnames, filenames in os.walk(root): + // for filename in fnmatch.filter(filenames, '*.class'): + // classfiles.append(os.path.join(container, filename)) + // for classfile in classfiles: + // blob = open(classfile).read() + // for found in re.findall(r"[\w\$]+\$lzycompute", blob): + // print found, "in", classfile[len(root) + 1:] + + + // ======== Exprs ======== + // NOFORCE: tree$lzycompute in api/Exprs$ExprImpl.class + // NOFORCE: staticType$lzycompute in api/Exprs$ExprImpl.class + // NOFORCE: value$lzycompute in api/Exprs$ExprImpl.class + // FORCE: Expr$lzycompute in api/Universe.class + // FORCE: FixedMirrorTreeCreator$lzycompute in internal/SymbolTable.class + // probably not used by runtime reflection, but better be safe than sorry + Expr + FixedMirrorTreeCreator + + // ======== Type tags ======== + // FORCE: WeakTypeTag$lzycompute in api/Universe.class + // FORCE: TypeTag$lzycompute in api/Universe.class + // NOFORCE: tpe$lzycompute in api/TypeTags$WeakTypeTagImpl.class + // TODO: validate that scala-reflect never uses TypeTags itself (we have StdTags, but they are in compiler, so it should be okay) + // FORCE: tpe$lzycompute in api/TypeTags$PredefTypeTag.class + // FORCE: FixedMirrorTypeCreator$lzycompute in internal/SymbolTable.class + // probably not used by runtime reflection, but better be safe than sorry + WeakTypeTag + TypeTag + TypeTag.Byte.tpe + TypeTag.Short.tpe + TypeTag.Char.tpe + TypeTag.Int.tpe + TypeTag.Long.tpe + TypeTag.Float.tpe + TypeTag.Double.tpe + TypeTag.Boolean.tpe + TypeTag.Unit.tpe + TypeTag.Any.tpe + TypeTag.AnyVal.tpe + TypeTag.AnyRef.tpe + TypeTag.Object.tpe + TypeTag.Nothing.tpe + TypeTag.Null.tpe + FixedMirrorTypeCreator + + // ======== Annotations ======== + // NOFORCE: isTrivial$lzycompute in internal/AnnotationInfos$AnnotationInfo.class + // looks like isTrivial just calls into Type.isTrivial, which cannot go back to the calling annotationinfo, so we're safe from deadlocks + // NOFORCE: forcedInfo$lzycompute in internal/AnnotationInfos$LazyAnnotationInfo.class + // I can't immediately see that the completer cannot call into one of the methods of the calling AnnotationInfo + // TODO: leaving this as a todo and for now we're at a mercy of chance + // NOFORCE: encodedBytes$lzycompute in internal/AnnotationInfos$ScalaSigBytes.class + // NOFORCE: sevenBitsMayBeZero$lzycompute in internal/AnnotationInfos$ScalaSigBytes.class + // these are just bit/byte twiddling, they don't call into reflection at all + // FORCE: UnmappableAnnotArg$lzycompute in internal/SymbolTable.class + // FORCE: LiteralAnnotArg$lzycompute in internal/SymbolTable.class + // FORCE: ArrayAnnotArg$lzycompute in internal/SymbolTable.class + // FORCE: NestedAnnotArg$lzycompute in internal/SymbolTable.class + // FORCE: ScalaSigBytes$lzycompute in internal/SymbolTable.class + // FORCE: AnnotationInfo$lzycompute in internal/SymbolTable.class + // FORCE: Annotation$lzycompute in internal/SymbolTable.class + // FORCE: UnmappableAnnotation$lzycompute in internal/SymbolTable.class + // FORCE: ThrownException$lzycompute in internal/SymbolTable.class + UnmappableAnnotArg + LiteralAnnotArg + ArrayAnnotArg + NestedAnnotArg + ScalaSigBytes + AnnotationInfo + Annotation + UnmappableAnnotation + ThrownException + + // ======== Importers ======== + // NOFORCE: symMap$lzycompute in internal/Importers$StandardImporter.class + // NOFORCE: tpeMap$lzycompute in internal/Importers$StandardImporter.class + // NOFORCE: fixups$lzycompute in internal/Importers$StandardImporter.class + // NOFORCE: reverse$lzycompute in internal/Importers$StandardImporter.class + // these are simple constructors, which don't call into reflection + // actually the first three of those could be non-lazy + + // ======== Mirrors ======== + // NOFORCE: RootPackage$lzycompute in runtime/JavaMirrors$JavaMirror.class + // NOFORCE: RootClass$lzycompute in runtime/JavaMirrors$JavaMirror.class + // NOFORCE: EmptyPackage$lzycompute in runtime/JavaMirrors$JavaMirror.class + // NOFORCE: EmptyPackageClass$lzycompute in runtime/JavaMirrors$JavaMirror.class + // NOFORCE: RootPackage$lzycompute in internal/Mirrors$Roots.class + // NOFORCE: RootClass$lzycompute in internal/Mirrors$Roots.class + // NOFORCE: EmptyPackage$lzycompute in internal/Mirrors$Roots.class + // NOFORCE: EmptyPackageClass$lzycompute in internal/Mirrors$Roots.class + // NOFORCE: unpickler$lzycompute in runtime/JavaMirrors$JavaMirror.class + // NOFORCE: rootLoader$lzycompute in runtime/JavaMirrors$JavaMirror.class + // these are already forced in JavaMirror.init() + // NOFORCE: universe$lzycompute in runtime/package$.class + // that's the scala.reflect.runtime.universe + // FORCE: 5scala$reflect$runtime$JavaMirrors$$mirrors$lzycompute in runtime/JavaUniverse.class + rootMirror + mirrors + + // ======== Names ======== + // FORCE: tpnme$lzycompute in internal/SymbolTable.class + // FORCE: fulltpnme$lzycompute in internal/SymbolTable.class + // FORCE: binarynme$lzycompute in internal/SymbolTable.class + // FORCE: nme$lzycompute in internal/SymbolTable.class + // FORCE: sn$lzycompute in internal/SymbolTable.class + // FORCE: raw$lzycompute in internal/StdNames$TermNames.class + // FORCE: Ascala$reflect$internal$SymbolTable$$SimpleNameOrdering$lzycompute in internal/SymbolTable.class + // FORCE: 6scala$reflect$internal$StdNames$$compactify$lzycompute in internal/SymbolTable.class + // probably most of these are already initialized by definitions.init() + // but better be safe than sorry + // NOFORCE: GetClassLoader$lzycompute in internal/StdNames$MSILNames.class + // MSIL has been eol'd. probably we shouldn't care anymore + // runtime reflection doesn't support MSIL anyways + tpnme + fulltpnme + binarynme + nme + sn + nme.raw + lowPriorityNameOrdering + nme.flattenedName() + + // ======== Attachments ======== + // FORCE: BackquotedIdentifierAttachment$lzycompute in internal/SymbolTable.class + // FORCE: CompoundTypeTreeOriginalAttachment$lzycompute in internal/SymbolTable.class + // FORCE: MacroExpansionAttachment$lzycompute in internal/SymbolTable.class + // FORCE: SuppressMacroExpansionAttachment$lzycompute in internal/SymbolTable.class + // probably not used by runtime reflection + // but better be safe than sorry + BackquotedIdentifierAttachment + CompoundTypeTreeOriginalAttachment + MacroExpansionAttachment + SuppressMacroExpansionAttachment + + // ======== TreeInfo ======== + // NOFORCE: DynamicUpdate$lzycompute in internal/TreeInfo.class + // NOFORCE: DynamicApplication$lzycompute in internal/TreeInfo.class + // NOFORCE: DynamicApplicationNamed$lzycompute in internal/TreeInfo.class + // NOFORCE: MacroImplReference$lzycompute in internal/TreeInfo.class + // NOFORCE: StripCast$lzycompute in internal/TreeInfo.class + // NOFORCE: Applied$lzycompute in internal/TreeInfo.class + // NOFORCE: IsTrue$lzycompute in internal/TreeInfo.class + // NOFORCE: IsFalse$lzycompute in internal/TreeInfo.class + // NOFORCE: IsIf$lzycompute in internal/TreeInfo.class + // TreeInfo is never instantiated by runtime reflection + + // ======== Miscellaneous ======== + // FORCE: BooleanFlag$lzycompute in api/Universe.class + // FORCE: traceSymbols$lzycompute in internal/SymbolTable.class + // FORCE: perRunCaches$lzycompute in internal/SymbolTable.class + // FORCE: typeDebug$lzycompute in internal/SymbolTable.class + // FORCE: str$lzycompute in internal/TypeDebugging$typeDebug$.class + // FORCE: ConsoleWriter$lzycompute in internal/SymbolTable.class + // FORCE: settings$lzycompute in runtime/JavaUniverse.class + // NOFORCE: Lscala$reflect$internal$util$TraceSymbolActivity$$findErasurePhase$lzycompute in internal/SymbolTable$traceSymbols$.class + // NOFORCE: lineIndices$lzycompute in internal/util/BatchSourceFile.class + // NOFORCE: extension$lzycompute in io/AbstractFile.class + // NOFORCE: in_s$lzycompute in io/File.class + // NOFORCE: out_s$lzycompute in io/File.class + // NOFORCE: in$lzycompute in io/File.class + // NOFORCE: out$lzycompute in io/File.class + // NOFORCE: in$lzycompute in io/Streamable$Bytes$class.class + // noforced guys don't call into reflection, so even when not initialized they don't pose a deadlock threat + // FORCE: Scope$lzycompute in internal/SymbolTable.class + // FORCE: EmptyScope$lzycompute in internal/SymbolTable.class + // FORCE: Flag$lzycompute in internal/SymbolTable.class + // FORCE: KindErrors$lzycompute in internal/SymbolTable.class + BooleanFlag + traceSymbols + perRunCaches + typeDebug + typeDebug.str + ConsoleWriter + settings + Scope + EmptyScope + Flag + KindErrors + + // ======== Transforms ======== + // NOFORCE: ObjectArray$lzycompute in internal/transform/Erasure$ErasureMap.class + // NOFORCE: ErasedObject$lzycompute in internal/transform/Erasure$ErasureMap.class + // too much hassle to force those, and they cannot be called back from reflection => safe from deadlocks + // FORCE: GenericArray$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class + // FORCE: scalaErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class + // FORCE: specialScalaErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class + // FORCE: javaErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class + // FORCE: verifiedJavaErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class + // FORCE: boxingErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class + refChecks + uncurry + erasure + erasure.GenericArray + erasure.scalaErasure + erasure.specialScalaErasure + erasure.javaErasure + erasure.verifiedJavaErasure + erasure.boxingErasure + + // ======== Symbols ======== + // FORCE: NoSymbol$lzycompute in internal/SymbolTable.class + // FORCE: 6scala$reflect$internal$Symbols$$TypeHistory$lzycompute in internal/SymbolTable.class + // FORCE: SymbolKind$lzycompute in internal/Symbols$Symbol.class + NoSymbol + definitions.AnyRefClass.info + SymbolKind + + // ======== Trees ======== + // FORCE: PackageDef$lzycompute in internal/SymbolTable.class + // FORCE: ClassDef$lzycompute in internal/SymbolTable.class + // FORCE: ModuleDef$lzycompute in internal/SymbolTable.class + // FORCE: ValDef$lzycompute in internal/SymbolTable.class + // FORCE: DefDef$lzycompute in internal/SymbolTable.class + // FORCE: TypeDef$lzycompute in internal/SymbolTable.class + // FORCE: LabelDef$lzycompute in internal/SymbolTable.class + // FORCE: ImportSelector$lzycompute in internal/SymbolTable.class + // FORCE: Import$lzycompute in internal/SymbolTable.class + // FORCE: Template$lzycompute in internal/SymbolTable.class + // FORCE: Block$lzycompute in internal/SymbolTable.class + // FORCE: CaseDef$lzycompute in internal/SymbolTable.class + // FORCE: Alternative$lzycompute in internal/SymbolTable.class + // FORCE: Star$lzycompute in internal/SymbolTable.class + // FORCE: Bind$lzycompute in internal/SymbolTable.class + // FORCE: UnApply$lzycompute in internal/SymbolTable.class + // FORCE: ArrayValue$lzycompute in internal/SymbolTable.class + // FORCE: Function$lzycompute in internal/SymbolTable.class + // FORCE: Assign$lzycompute in internal/SymbolTable.class + // FORCE: AssignOrNamedArg$lzycompute in internal/SymbolTable.class + // FORCE: If$lzycompute in internal/SymbolTable.class + // FORCE: Match$lzycompute in internal/SymbolTable.class + // FORCE: Return$lzycompute in internal/SymbolTable.class + // FORCE: Try$lzycompute in internal/SymbolTable.class + // FORCE: Throw$lzycompute in internal/SymbolTable.class + // FORCE: New$lzycompute in internal/SymbolTable.class + // FORCE: Typed$lzycompute in internal/SymbolTable.class + // FORCE: TypeApply$lzycompute in internal/SymbolTable.class + // FORCE: Apply$lzycompute in internal/SymbolTable.class + // FORCE: ApplyDynamic$lzycompute in internal/SymbolTable.class + // FORCE: Super$lzycompute in internal/SymbolTable.class + // FORCE: This$lzycompute in internal/SymbolTable.class + // FORCE: Select$lzycompute in internal/SymbolTable.class + // FORCE: Ident$lzycompute in internal/SymbolTable.class + // FORCE: ReferenceToBoxed$lzycompute in internal/SymbolTable.class + // FORCE: Literal$lzycompute in internal/SymbolTable.class + // FORCE: Annotated$lzycompute in internal/SymbolTable.class + // FORCE: SingletonTypeTree$lzycompute in internal/SymbolTable.class + // FORCE: SelectFromTypeTree$lzycompute in internal/SymbolTable.class + // FORCE: CompoundTypeTree$lzycompute in internal/SymbolTable.class + // FORCE: AppliedTypeTree$lzycompute in internal/SymbolTable.class + // FORCE: TypeBoundsTree$lzycompute in internal/SymbolTable.class + // FORCE: ExistentialTypeTree$lzycompute in internal/SymbolTable.class + // FORCE: TypeTree$lzycompute in internal/SymbolTable.class + // FORCE: Modifiers$lzycompute in internal/SymbolTable.class + // FORCE: Constant$lzycompute in internal/SymbolTable.class + // FORCE: treeBuild$lzycompute in internal/SymbolTable.class + // FORCE: posAssigner$lzycompute in internal/SymbolTable.class + // FORCE: NoMods$lzycompute in api/Universe.class + // FORCE: EmptyTree$lzycompute in internal/SymbolTable.class + // FORCE: emptyValDef$lzycompute in internal/SymbolTable.class + // FORCE: EmptyTreeTypeSubstituter$lzycompute in internal/SymbolTable.class + // FORCE: 3scala$reflect$internal$Trees$$duplicator$lzycompute in internal/SymbolTable.class + PackageDef + ClassDef + ModuleDef + ValDef + DefDef + TypeDef + LabelDef + ImportSelector + Import + Template + Block + CaseDef + Alternative + Star + Bind + UnApply + ArrayValue + Function + Assign + AssignOrNamedArg + If + Match + Return + Try + Throw + New + Typed + TypeApply + Apply + ApplyDynamic + Super + This + Select + Ident + ReferenceToBoxed + Literal + Annotated + SingletonTypeTree + SelectFromTypeTree + CompoundTypeTree + AppliedTypeTree + TypeBoundsTree + ExistentialTypeTree + TypeTree + Modifiers + Constant + treeBuild + posAssigner + NoMods + EmptyTree + emptyValDef + EmptyTreeTypeSubstituter + Literal(Constant(42)).duplicate + + // ======== Types ======== + // FORCE: undoLog$lzycompute in internal/SymbolTable.class + // FORCE: UnmappableTree$lzycompute in internal/SymbolTable.class + // FORCE: NotNullType$lzycompute in internal/SymbolTable.class + // FORCE: ErrorType$lzycompute in internal/SymbolTable.class + // FORCE: WildcardType$lzycompute in internal/SymbolTable.class + // FORCE: BoundedWildcardType$lzycompute in internal/SymbolTable.class + // FORCE: NoType$lzycompute in internal/SymbolTable.class + // FORCE: NoPrefix$lzycompute in internal/SymbolTable.class + // FORCE: ThisType$lzycompute in internal/SymbolTable.class + // FORCE: SingleType$lzycompute in internal/SymbolTable.class + // FORCE: SuperType$lzycompute in internal/SymbolTable.class + // FORCE: TypeBounds$lzycompute in internal/SymbolTable.class + // NOFORCE: annotationArgRewriter$1$lzycompute in internal/Types$AsSeenFromMap.class + // local object => not a problem + // FORCE: RefinedType$lzycompute in internal/SymbolTable.class + // FORCE: ClassInfoType$lzycompute in internal/SymbolTable.class + // FORCE: ConstantType$lzycompute in internal/SymbolTable.class + // FORCE: TypeRef$lzycompute in internal/SymbolTable.class + // FORCE: MethodType$lzycompute in internal/SymbolTable.class + // FORCE: NullaryMethodType$lzycompute in internal/SymbolTable.class + // FORCE: PolyType$lzycompute in internal/SymbolTable.class + // FORCE: ExistentialType$lzycompute in internal/SymbolTable.class + // FORCE: OverloadedType$lzycompute in internal/SymbolTable.class + // FORCE: AntiPolyType$lzycompute in internal/SymbolTable.class + // FORCE: HasTypeMember$lzycompute in internal/SymbolTable.class + // FORCE: HasTypeParams$lzycompute in internal/SymbolTable.class + // FORCE: TypeVar$lzycompute in internal/SymbolTable.class + // FORCE: AnnotatedType$lzycompute in internal/SymbolTable.class + // FORCE: NamedType$lzycompute in internal/SymbolTable.class + // FORCE: DeBruijnIndex$lzycompute in internal/SymbolTable.class + // FORCE: DeBruijnBinder$lzycompute in internal/SymbolTable.class + // FORCE: ErasedValueType$lzycompute in internal/SymbolTable.class + // FORCE: GenPolyType$lzycompute in internal/SymbolTable.class + // FORCE: normalizeAliases$lzycompute in internal/SymbolTable.class + // FORCE: dropSingletonType$lzycompute in internal/SymbolTable.class + // FORCE: dropAllRefinements$lzycompute in internal/SymbolTable.class + // FORCE: dropRepeatedParamType$lzycompute in internal/SymbolTable.class + // FORCE: toDeBruijn$lzycompute in internal/SymbolTable.class + // FORCE: numericLoBound$lzycompute in internal/SymbolTable.class + // FORCE: numericHiBound$lzycompute in internal/SymbolTable.class + // FORCE: TypeConstraint$lzycompute in internal/SymbolTable.class + // FORCE: unwrapToClass$lzycompute in internal/SymbolTable.class + // FORCE: unwrapToStableClass$lzycompute in internal/SymbolTable.class + // FORCE: unwrapWrapperTypes$lzycompute in internal/SymbolTable.class + // FORCE: IsDependentCollector$lzycompute in internal/SymbolTable.class + // FORCE: ApproximateDependentMap$lzycompute in internal/SymbolTable.class + // FORCE: StripAnnotationsMap$lzycompute in internal/SymbolTable.class + // FORCE: wildcardToTypeVarMap$lzycompute in internal/SymbolTable.class + // FORCE: typeVarToOriginMap$lzycompute in internal/SymbolTable.class + // FORCE: ErroneousCollector$lzycompute in internal/SymbolTable.class + // NOFORCE: scala$reflect$internal$Types$$commonOwnerMapObj$lzycompute in internal/SymbolTable.class + // not used in runtime reflection, overridden to provide thread-safety + // FORCE: RecoverableCyclicReference$lzycompute in internal/SymbolTable.class + // FORCE: CyclicReference$lzycompute in internal/SymbolTable.class + // NOFORCE: scala$reflect$internal$Types$ClassInfoType$$enterRefs$lzycompute in internal/Types$ClassInfoType.class + // not used in runtime reflection, only called by typer + // NOFORCE: Jscala$reflect$internal$Types$InstantiateDependentMap$$StableArg$lzycompute in internal/Types$InstantiateDependentMap.class + // NOFORCE: Dscala$reflect$internal$Types$InstantiateDependentMap$$Arg$lzycompute in internal/Types$InstantiateDependentMap.class + // don't call into reflection + // NOFORCE: trans$1$lzycompute in internal/Types$SubstSymMap.class + // NOFORCE: trans$2$lzycompute in internal/Types$SubstTypeMap.class + // NOFORCE: treeTrans$1$lzycompute in internal/Types$InstantiateDependentMap.class + // local objects => we're fine + // FORCE: adaptToNewRunMap$lzycompute in internal/SymbolTable.class + // NOFORCE?! maxDepth$lzycompute in internal/BaseTypeSeqs$BaseTypeSeq.class + // NOFORCE?! maxDepth$lzycompute in runtime/SynchronizedOps$$anon$4.class + // NOFORCE?! maxDepth$lzycompute in runtime/SynchronizedOps$SynchronizedBaseTypeSeq$$anon$3.class + // it's totally not obvious whether typeDepth, which is called by maxDepth, + // can or cannot indirectly call into one of the methods of the calling BaseTypeSeq + // TODO: leaving this for further investigation risking to get a deadlock for now + undoLog + UnmappableTree + NotNullType + ErrorType + WildcardType + BoundedWildcardType + NoType + NoPrefix + ThisType + SingleType + SuperType + TypeBounds + RefinedType + ClassInfoType + ConstantType + TypeRef + MethodType + NullaryMethodType + PolyType + ExistentialType + OverloadedType + AntiPolyType + HasTypeMember + HasTypeParams + TypeVar + AnnotatedType + NamedType + DeBruijnIndex + DeBruijnBinder + ErasedValueType + GenPolyType + normalizeAliases + dropSingletonType + dropAllRefinements + dropRepeatedParamType + toDeBruijn + numericLoBound + numericHiBound + TypeConstraint + unwrapToClass + unwrapToStableClass + unwrapWrapperTypes + IsDependentCollector + ApproximateDependentMap + StripAnnotationsMap + wildcardToTypeVarMap + typeVarToOriginMap + ErroneousCollector + RecoverableCyclicReference + CyclicReference + adaptToNewRunMap + + // ======== JavaMirrors ======== + // NOFORCE: assocs$lzycompute in runtime/JavaMirrors$JavaMirror$JavaAnnotationProxy.class + // NOFORCE: jconstr$lzycompute in runtime/JavaMirrors$JavaMirror$JavaConstructorMirror.class + // NOFORCE: jfield$lzycompute in runtime/JavaMirrors$JavaMirror$JavaFieldMirror.class + // NOFORCE: jmeth$lzycompute in runtime/JavaMirrors$JavaMirror$JavaMethodMirror.class + // NOFORCE: signature$lzycompute in runtime/JavaMirrors$JavaMirror$JavaTemplateMirror.class + // NOFORCE: PrimitiveClass$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class + // NOFORCE: EnumClass$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class + // NOFORCE: ArrayClass$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class + // NOFORCE: AnnotationClass$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class + // NOFORCE: ConstantArg$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class + // NOFORCE: Cscala$reflect$runtime$JavaMirrors$JavaMirror$$toAnnotArg$lzycompute in runtime/JavaMirrors$JavaMirror.class + // NOFORCE: Lscala$reflect$runtime$JavaMirrors$JavaMirror$$JavaAnnotationProxy$lzycompute in runtime/JavaMirrors$JavaMirror.class + // NOFORCE: Bscala$reflect$runtime$TwoWayCaches$TwoWayCache$$SomeRef$lzycompute in runtime/TwoWayCaches$TwoWayCache.class + // NOFORCE: bytecodelessMethodOwners$lzycompute in runtime/JavaMirrors$JavaMirror.class + // NOFORCE: bytecodefulObjectMethods$lzycompute in runtime/JavaMirrors$JavaMirror.class + // functionality from JavaMirrors cannot be called from reflect.internal, so there's no danger of deadlock + + // ======== Locks ======== + // locks in runtime reflection look like `lazy val XXXlock = new Object` + // since initializers don't call into reflection, there's no problem in not forcing those lazy vals here + + // ======== Definitions ======== + // FORCE: definitions$lzycompute in internal/SymbolTable.class + // FORCE: JavaLangPackage$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: JavaLangPackageClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaPackage$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaPackageClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RuntimePackage$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RuntimePackageClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: JavaLangEnumClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: anyparam$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: anyvalparam$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: anyrefparam$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnyClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnyRefClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ObjectClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnyTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnyRefTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ObjectTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnyRefModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnyValClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnyValTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RuntimeNothingClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RuntimeNullClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NothingClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NullClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NothingTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NullTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ClassCastExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: IndexOutOfBoundsExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: InvocationTargetExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MatchErrorClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NonLocalReturnControlClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: $NullPointerExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ThrowableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: UninitializedErrorClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: PartialFunctionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AbstractPartialFunctionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SymbolClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: StringClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: StringModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ClassClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: DynamicClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SysPackage$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: UnqualifiedModules$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: UnqualifiedOwners$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: PredefModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: PredefModuleClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SpecializableModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: GroupOfSpecializable$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ConsoleModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaRunTimeModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SymbolModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Symbol_apply$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: StringAddClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ArrowAssocClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: StringAdd_$plus$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NotNullClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaNumberClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TraitSetterAnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: DelayedInitClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TypeConstraintClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SingletonClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SerializableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: JavaSerializableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ComparableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: CloneableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: JavaCloneableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: JavaNumberClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RemoteInterfaceClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RemoteExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ByNameParamClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: EqualsPatternClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: JavaRepeatedParamClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RepeatedParamClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MatchingStrategyClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ConsClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: IterableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: IteratorClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ListClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SeqClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: StringBuilderClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TraversableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ListModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: List_apply$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NilModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SeqModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: IteratorModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Iterator_apply$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ArrayModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ArrayModule_overloadedApply$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ArrayClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Array_apply$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Array_update$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Array_length$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Array_clone$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SoftReferenceClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: WeakReferenceClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MethodClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: EmptyMethodCacheClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MethodCacheClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ReflectPackage$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ReflectApiPackage$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ReflectRuntimePackage$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: PartialManifestClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: PartialManifestModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: FullManifestClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: FullManifestModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: OptManifestClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NoManifest$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ExprsClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ExprClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ExprModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ClassTagModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ClassTagClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TypeTagsClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: WeakTypeTagClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: WeakTypeTagModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TypeTagClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TypeTagModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ApiUniverseClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: JavaUniverseClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MirrorClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TypeCreatorClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TreeCreatorClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MacroContextClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MacroImplAnnotation$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: StringContextClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaSignatureAnnotation$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaLongSignatureAnnotation$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: OptionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: OptionModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Option_apply$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SomeClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NoneModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SomeModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ProductClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TupleClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: FunctionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AbstractFunctionClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ProductRootClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ObjectArray$lzycompute in internal/Definitions$DefinitionsClass.class + // NOFORCE: ComparatorClass$lzycompute in internal/Definitions$DefinitionsClass.class + // NOFORCE: ValueTypeClass$lzycompute in internal/Definitions$DefinitionsClass.class + // NOFORCE: DelegateClass$lzycompute in internal/Definitions$DefinitionsClass.class + // NOFORCE: Delegate_scalaCallerTargets$lzycompute in internal/Definitions$DefinitionsClass.class + // MSIL has been eol'd. probably we shouldn't care anymore + // runtime reflection doesn't support MSIL anyways + // FORCE: Any_$eq$eq$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Any_$bang$eq$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Any_equals$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Any_hashCode$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Any_toString$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Any_$hash$hash$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Any_getClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Any_isInstanceOf$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Any_asInstanceOf$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Object_$hash$hash$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Object_$eq$eq$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Object_$bang$eq$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Object_eq$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Object_ne$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Object_isInstanceOf$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Object_asInstanceOf$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Object_synchronized$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: String_$plus$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ObjectRefClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: VolatileObjectRefClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RuntimeStaticsModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxesRunTimeModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxesRunTimeClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedNumberClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedCharacterClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedBooleanClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedByteClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedShortClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedIntClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedLongClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedFloatClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedDoubleClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Boxes_isNumberOrBool$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Boxes_isNumber$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedUnitClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BoxedUnitModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ClassfileAnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: StaticAnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BridgeClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ElidableMethodClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ImplicitNotFoundClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MigrationAnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaStrictFPAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SerializableAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SwitchClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TailrecClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: VarargsClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: uncheckedStableClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: uncheckedVarianceClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BeanPropertyAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BooleanBeanPropertyAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: CloneableAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: CompileTimeOnlyAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: DeprecatedAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: DeprecatedNameAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: $DeprecatedInheritanceAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: DeprecatedOverridingAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: NativeAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: RemoteAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaInlineClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaNoInlineClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SerialVersionUIDAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SpecializedClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ThrowsClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: TransientAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: UncheckedClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: UnspecializedClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: VolatileAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BeanGetterTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BeanSetterTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: FieldTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: GetterTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ParamTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: SetterTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ClassTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ObjectTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MethodTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: LanguageFeatureAnnot$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: languageFeatureModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: experimentalModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: MacrosFeature$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: DynamicsFeature$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: PostfixOpsFeature$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ReflectiveCallsFeature$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ImplicitConversionsFeature$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: HigherKindsFeature$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ExistentialsFeature$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: metaAnnotations$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: AnnotationDefaultAttr$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: boxedClassValues$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: isUnbox$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: isBox$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: isPhantomClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: syntheticCoreClasses$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: syntheticCoreMethods$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: hijackedCoreClasses$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: symbolsNotPresentInBytecode$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: $isPossibleSyntheticParent$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: boxedValueClassesSet$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: abbrvTag$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: numericWeight$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: boxedModule$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: boxedClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: refClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: volatileRefClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: boxMethod$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: unboxMethod$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: UnitClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ByteClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ShortClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: CharClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: IntClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: LongClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: FloatClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: DoubleClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BooleanClass$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Boolean_and$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Boolean_or$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: Boolean_not$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: UnitTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ByteTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ShortTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: CharTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: IntTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: LongTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: FloatTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: DoubleTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: BooleanTpe$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaNumericValueClasses$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaValueClassesNoUnit$lzycompute in internal/Definitions$DefinitionsClass.class + // FORCE: ScalaValueClasses$lzycompute in internal/Definitions$DefinitionsClass.class + definitions.JavaLangPackage + definitions.JavaLangPackageClass + definitions.ScalaPackage + definitions.ScalaPackageClass + definitions.RuntimePackage + definitions.RuntimePackageClass + definitions.JavaLangEnumClass + definitions.anyparam + definitions.anyvalparam + definitions.anyrefparam + definitions.AnyClass + definitions.AnyRefClass + definitions.ObjectClass + definitions.AnyTpe + definitions.AnyRefTpe + definitions.ObjectTpe + // FIXME: definitions.AnyRefModule + definitions.AnyValClass + definitions.AnyValTpe + definitions.RuntimeNothingClass + definitions.RuntimeNullClass + definitions.NothingClass + definitions.NullClass + definitions.NothingTpe + definitions.NullTpe + definitions.ClassCastExceptionClass + definitions.IndexOutOfBoundsExceptionClass + definitions.InvocationTargetExceptionClass + definitions.MatchErrorClass + definitions.NonLocalReturnControlClass + definitions.NullPointerExceptionClass + definitions.ThrowableClass + definitions.UninitializedErrorClass + definitions.PartialFunctionClass + definitions.AbstractPartialFunctionClass + definitions.SymbolClass + definitions.StringClass + definitions.StringModule + definitions.ClassClass + definitions.DynamicClass + definitions.SysPackage + definitions.UnqualifiedModules + definitions.UnqualifiedOwners + definitions.PredefModule + definitions.PredefModuleClass + definitions.SpecializableModule + definitions.GroupOfSpecializable + definitions.ConsoleModule + definitions.ScalaRunTimeModule + definitions.SymbolModule + definitions.Symbol_apply + definitions.StringAddClass + definitions.ArrowAssocClass + definitions.StringAdd_$plus + definitions.NotNullClass + definitions.ScalaNumberClass + definitions.TraitSetterAnnotationClass + definitions.DelayedInitClass + definitions.TypeConstraintClass + definitions.SingletonClass + definitions.SerializableClass + definitions.JavaSerializableClass + definitions.ComparableClass + definitions.CloneableClass + definitions.JavaCloneableClass + definitions.JavaNumberClass + definitions.RemoteInterfaceClass + definitions.RemoteExceptionClass + definitions.ByNameParamClass + definitions.EqualsPatternClass + definitions.JavaRepeatedParamClass + definitions.RepeatedParamClass + // FIXME: definitions.MatchingStrategyClass + definitions.ConsClass + definitions.IterableClass + definitions.IteratorClass + definitions.ListClass + definitions.SeqClass + definitions.StringBuilderClass + definitions.TraversableClass + definitions.ListModule + definitions.List_apply + definitions.NilModule + definitions.SeqModule + definitions.IteratorModule + definitions.Iterator_apply + definitions.ArrayModule + definitions.ArrayModule_overloadedApply + definitions.ArrayClass + definitions.Array_apply + definitions.Array_update + definitions.Array_length + definitions.Array_clone + definitions.SoftReferenceClass + definitions.WeakReferenceClass + definitions.MethodClass + definitions.EmptyMethodCacheClass + definitions.MethodCacheClass + definitions.ReflectPackage + definitions.ReflectApiPackage + definitions.ReflectRuntimePackage + definitions.PartialManifestClass + definitions.PartialManifestModule + definitions.FullManifestClass + definitions.FullManifestModule + definitions.OptManifestClass + definitions.NoManifest + definitions.ExprsClass + definitions.ExprClass + definitions.ExprModule + definitions.ClassTagModule + definitions.ClassTagClass + definitions.TypeTagsClass + definitions.WeakTypeTagClass + definitions.WeakTypeTagModule + definitions.TypeTagClass + definitions.TypeTagModule + definitions.ApiUniverseClass + definitions.JavaUniverseClass + definitions.MirrorClass + definitions.TypeCreatorClass + definitions.TreeCreatorClass + definitions.MacroContextClass + definitions.MacroImplAnnotation + definitions.StringContextClass + definitions.ScalaSignatureAnnotation + definitions.ScalaLongSignatureAnnotation + definitions.OptionClass + definitions.OptionModule + definitions.Option_apply + definitions.SomeClass + definitions.NoneModule + definitions.SomeModule + definitions.ProductClass + definitions.TupleClass + definitions.FunctionClass + definitions.AbstractFunctionClass + definitions.ProductRootClass + definitions.ObjectArray + definitions.Any_$eq$eq + definitions.Any_$bang$eq + definitions.Any_equals + definitions.Any_hashCode + definitions.Any_toString + definitions.Any_$hash$hash + definitions.Any_getClass + definitions.Any_isInstanceOf + definitions.Any_asInstanceOf + definitions.Object_$hash$hash + definitions.Object_$eq$eq + definitions.Object_$bang$eq + definitions.Object_eq + definitions.Object_ne + definitions.Object_isInstanceOf + definitions.Object_asInstanceOf + definitions.Object_synchronized + definitions.String_$plus + definitions.ObjectRefClass + definitions.VolatileObjectRefClass + definitions.RuntimeStaticsModule + definitions.BoxesRunTimeModule + definitions.BoxesRunTimeClass + definitions.BoxedNumberClass + definitions.BoxedCharacterClass + definitions.BoxedBooleanClass + definitions.BoxedByteClass + definitions.BoxedShortClass + definitions.BoxedIntClass + definitions.BoxedLongClass + definitions.BoxedFloatClass + definitions.BoxedDoubleClass + definitions.Boxes_isNumberOrBool + definitions.Boxes_isNumber + definitions.BoxedUnitClass + definitions.BoxedUnitModule + definitions.AnnotationClass + definitions.ClassfileAnnotationClass + definitions.StaticAnnotationClass + definitions.BridgeClass + definitions.ElidableMethodClass + definitions.ImplicitNotFoundClass + definitions.MigrationAnnotationClass + definitions.ScalaStrictFPAttr + definitions.SerializableAttr + definitions.SwitchClass + definitions.TailrecClass + definitions.VarargsClass + definitions.uncheckedStableClass + definitions.uncheckedVarianceClass + definitions.BeanPropertyAttr + definitions.BooleanBeanPropertyAttr + definitions.CloneableAttr + definitions.CompileTimeOnlyAttr + definitions.DeprecatedAttr + definitions.DeprecatedNameAttr + definitions.DeprecatedInheritanceAttr + definitions.DeprecatedOverridingAttr + definitions.NativeAttr + definitions.RemoteAttr + definitions.ScalaInlineClass + definitions.ScalaNoInlineClass + definitions.SerialVersionUIDAttr + definitions.SpecializedClass + definitions.ThrowsClass + definitions.TransientAttr + definitions.UncheckedClass + definitions.UnspecializedClass + definitions.VolatileAttr + definitions.BeanGetterTargetClass + definitions.BeanSetterTargetClass + definitions.FieldTargetClass + definitions.GetterTargetClass + definitions.ParamTargetClass + definitions.SetterTargetClass + definitions.ClassTargetClass + definitions.ObjectTargetClass + definitions.MethodTargetClass + definitions.LanguageFeatureAnnot + definitions.languageFeatureModule + definitions.experimentalModule + definitions.MacrosFeature + definitions.DynamicsFeature + definitions.PostfixOpsFeature + definitions.ReflectiveCallsFeature + definitions.ImplicitConversionsFeature + definitions.HigherKindsFeature + definitions.ExistentialsFeature + definitions.metaAnnotations + definitions.AnnotationDefaultAttr + definitions.boxedClassValues + definitions.isUnbox + definitions.isBox + definitions.isPhantomClass + definitions.syntheticCoreClasses + definitions.syntheticCoreMethods + definitions.hijackedCoreClasses + definitions.symbolsNotPresentInBytecode + definitions.isPossibleSyntheticParent + definitions.boxedValueClassesSet + definitions.abbrvTag + definitions.numericWeight + definitions.boxedModule + definitions.boxedClass + definitions.refClass + definitions.volatileRefClass + definitions.boxMethod + definitions.unboxMethod + definitions.UnitClass + definitions.ByteClass + definitions.ShortClass + definitions.CharClass + definitions.IntClass + definitions.LongClass + definitions.FloatClass + definitions.DoubleClass + definitions.BooleanClass + definitions.Boolean_and + definitions.Boolean_or + definitions.Boolean_not + definitions.UnitTpe + definitions.ByteTpe + definitions.ShortTpe + definitions.CharTpe + definitions.IntTpe + definitions.LongTpe + definitions.FloatTpe + definitions.DoubleTpe + definitions.BooleanTpe + definitions.ScalaNumericValueClasses + definitions.ScalaValueClassesNoUnit + definitions.ScalaValueClasses } } -- cgit v1.2.3 From bebd62d5665b9166c1a44b3bcdc01287220a30b7 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 2 Feb 2013 00:27:38 +0100 Subject: optimizes Scala reflection GIL First of all, GIL should only apply to runtime reflection, because noone is going to run toolboxes in multiple threads: a) that's impossible, b/c the compiler isn't thread safe, b) ToolBox api prevents that. Secondly, the only things in symbols which require synchronization are: 1) info/validTo (completers aren't thread-safe), 2) rawInfo and its dependencies (it shares a mutable field with info) 3) non-trivial caches like in typeAsMemberOfLock If you think about it, other things like sourceModule or associatedFile don't need synchronization, because they are either set up when a symbol is created or cloned or when it's completed. The former is obviously safe, while the latter is safe as well, because before acquiring init-dependent state of symbols, the compiler calls `initialize`, which is synchronized. We can say that symbols can be in four possible states: 1) being created, 2) created, but not yet initialized, 3) initializing, 4) initialized. in runtime reflection can undergo is init. #3 is dangerous and needs protection --- src/reflect/scala/reflect/internal/Symbols.scala | 13 +++- src/reflect/scala/reflect/runtime/Gil.scala | 13 ++-- .../scala/reflect/runtime/SynchronizedOps.scala | 2 +- .../reflect/runtime/SynchronizedSymbols.scala | 77 +++++++--------------- 4 files changed, 41 insertions(+), 64 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 0a600432fd..004f7d176a 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -895,6 +895,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isInitialized: Boolean = validTo != NoPeriod + /** Some completers call sym.setInfo when still in-flight and then proceed with initialization (e.g. see LazyPackageType) + * setInfo sets _validTo to current period, which means that after a call to setInfo isInitialized will start returning true. + * Unfortunately, this doesn't mean that info becomes ready to be used, because subsequent initialization might change the info. + * Therefore we need this method to distinguish between initialized and really initialized symbol states. + */ + final def isFullyInitialized: Boolean = _validTo != NoPeriod && (flags & LOCKED) == 0 + /** Can this symbol be loaded by a reflective mirror? * * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. @@ -3008,8 +3015,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def thisType: Type = { val period = thisTypePeriod if (period != currentPeriod) { - thisTypePeriod = currentPeriod if (!isValid(period)) thisTypeCache = ThisType(this) + thisTypePeriod = currentPeriod } thisTypeCache } @@ -3085,9 +3092,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def typeOfThis = { val period = typeOfThisPeriod if (period != currentPeriod) { - typeOfThisPeriod = currentPeriod if (!isValid(period)) typeOfThisCache = singleType(owner.thisType, sourceModule) + typeOfThisPeriod = currentPeriod } typeOfThisCache } @@ -3098,9 +3105,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => // Skip a package object class, because the members are also in // the package and we wish to avoid spurious ambiguities as in pos/t3999. if (!isPackageObjectClass) { + implicitMembersCacheValue = tp.implicitMembers implicitMembersCacheKey1 = tp implicitMembersCacheKey2 = tp.decls.elems - implicitMembersCacheValue = tp.implicitMembers } } implicitMembersCacheValue diff --git a/src/reflect/scala/reflect/runtime/Gil.scala b/src/reflect/scala/reflect/runtime/Gil.scala index 8a8bfebf8c..cf6f1431d7 100644 --- a/src/reflect/scala/reflect/runtime/Gil.scala +++ b/src/reflect/scala/reflect/runtime/Gil.scala @@ -12,11 +12,14 @@ private[reflect] trait Gil { lazy val gil = new java.util.concurrent.locks.ReentrantLock @inline final def gilSynchronized[T](body: => T): T = { - try { - gil.lock() - body - } finally { - gil.unlock() + if (isCompilerUniverse) body + else { + try { + gil.lock() + body + } finally { + gil.unlock() + } } } } diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala index b674fc380f..d022bf66ba 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala @@ -49,7 +49,7 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable // we can keep this lock fine-grained, because methods of Scope don't do anything extraordinary, which makes deadlocks impossible // fancy subclasses of internal.Scopes#Scope should do synchronization themselves (e.g. see PackageScope for an example) private lazy val syncLock = new Object - def syncLockSynchronized[T](body: => T): T = syncLock.synchronized { body } + def syncLockSynchronized[T](body: => T): T = if (isCompilerUniverse) body else syncLock.synchronized { body } override def isEmpty: Boolean = syncLockSynchronized { super.isEmpty } override def size: Int = syncLockSynchronized { super.size } override def enter[T <: Symbol](sym: T): T = syncLockSynchronized { super.enter(sym) } diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 3b5029a263..85bd9ff8b6 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -28,27 +28,16 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb trait SynchronizedSymbol extends Symbol { - override def rawflags = gilSynchronized { super.rawflags } - override def rawflags_=(x: Long) = gilSynchronized { super.rawflags_=(x) } - - override def rawowner = gilSynchronized { super.rawowner } - override def owner_=(owner: Symbol) = gilSynchronized { super.owner_=(owner) } - - override def validTo = gilSynchronized { super.validTo } - override def validTo_=(x: Period) = gilSynchronized { super.validTo_=(x) } - - override def pos = gilSynchronized { super.pos } - override def setPos(pos: Position): this.type = { gilSynchronized { super.setPos(pos) }; this } - - override def privateWithin = gilSynchronized { super.privateWithin } - override def privateWithin_=(sym: Symbol) = gilSynchronized { super.privateWithin_=(sym) } + def gilSynchronizedIfNotInited[T](body: => T): T = { + if (isFullyInitialized) body + else gilSynchronized { body } + } - override def info = gilSynchronized { super.info } - override def info_=(info: Type) = gilSynchronized { super.info_=(info) } - override def updateInfo(info: Type): Symbol = gilSynchronized { super.updateInfo(info) } - override def rawInfo: Type = gilSynchronized { super.rawInfo } + override def validTo = gilSynchronizedIfNotInited { super.validTo } + override def info = gilSynchronizedIfNotInited { super.info } + override def rawInfo: Type = gilSynchronizedIfNotInited { super.rawInfo } - override def typeParams: List[Symbol] = gilSynchronized { + override def typeParams: List[Symbol] = gilSynchronizedIfNotInited { if (isCompilerUniverse) super.typeParams else { if (isMonomorphicType) Nil @@ -64,7 +53,7 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb } } } - override def unsafeTypeParams: List[Symbol] = gilSynchronized { + override def unsafeTypeParams: List[Symbol] = gilSynchronizedIfNotInited { if (isCompilerUniverse) super.unsafeTypeParams else { if (isMonomorphicType) Nil @@ -72,14 +61,6 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb } } - override def reset(completer: Type): this.type = gilSynchronized { super.reset(completer) } - - override def infosString: String = gilSynchronized { super.infosString } - - override def annotations: List[AnnotationInfo] = gilSynchronized { super.annotations } - override def setAnnotations(annots: List[AnnotationInfo]): this.type = { gilSynchronized { super.setAnnotations(annots) }; this } - - // ------ creators ------------------------------------------------------------------- override protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol = @@ -130,40 +111,26 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb // ------- subclasses --------------------------------------------------------------------- - trait SynchronizedTermSymbol extends TermSymbol with SynchronizedSymbol { - override def name_=(x: Name) = gilSynchronized { super.name_=(x) } - override def rawname = gilSynchronized { super.rawname } - override def referenced: Symbol = gilSynchronized { super.referenced } - override def referenced_=(x: Symbol) = gilSynchronized { super.referenced_=(x) } - } + trait SynchronizedTermSymbol extends SynchronizedSymbol trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol { - override def typeAsMemberOf(pre: Type): Type = gilSynchronized { super.typeAsMemberOf(pre) } - override def paramss: List[List[Symbol]] = gilSynchronized { super.paramss } - override def returnType: Type = gilSynchronized { super.returnType } + // we can keep this lock fine-grained, because it's just a cache over asSeenFrom, which makes deadlocks impossible + // unfortunately we cannot elide this lock, because the cache depends on `pre` + private lazy val typeAsMemberOfLock = new Object + override def typeAsMemberOf(pre: Type): Type = gilSynchronizedIfNotInited { typeAsMemberOfLock.synchronized { super.typeAsMemberOf(pre) } } } + trait SynchronizedModuleSymbol extends ModuleSymbol with SynchronizedTermSymbol + trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol { - override def name_=(x: Name) = gilSynchronized { super.name_=(x) } - override def rawname = gilSynchronized { super.rawname } - override def typeConstructor: Type = gilSynchronized { super.typeConstructor } - override def tpe: Type = gilSynchronized { super.tpe } + // unlike with typeConstructor, a lock is necessary here, because tpe calculation relies on + // temporarily assigning NoType to tpeCache to detect cyclic reference errors + private lazy val tpeLock = new Object + override def tpe: Type = gilSynchronizedIfNotInited { tpeLock.synchronized { super.tpe } } } - trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol { - override def associatedFile = gilSynchronized { super.associatedFile } - override def associatedFile_=(f: AbstractFile) = gilSynchronized { super.associatedFile_=(f) } - override def thisSym: Symbol = gilSynchronized { super.thisSym } - override def thisType: Type = gilSynchronized { super.thisType } - override def typeOfThis: Type = gilSynchronized { super.typeOfThis } - override def typeOfThis_=(tp: Type) = gilSynchronized { super.typeOfThis_=(tp) } - override def children = gilSynchronized { super.children } - override def addChild(sym: Symbol) = gilSynchronized { super.addChild(sym) } - } + trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol - trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol { - override def sourceModule = gilSynchronized { super.sourceModule } - override def implicitMembers: Scope = gilSynchronized { super.implicitMembers } - } + trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol } -- cgit v1.2.3 From 07bcb6176ac7836e81ec7c849e1140126bb6b327 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 7 Feb 2013 09:14:42 +0100 Subject: SI-7045 reflection now auto-initializes selfType selfType joins the happy family of flags, annotations and privateWithin, which automatically trigger initialization, when used within runtime reflection. --- src/reflect/scala/reflect/internal/Symbols.scala | 6 +++++- test/files/run/t7045.check | 2 ++ test/files/run/t7045.scala | 12 ++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t7045.check create mode 100644 test/files/run/t7045.scala diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 004f7d176a..df17e3b751 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -91,10 +91,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => children } + def selfType = { + if (!isCompilerUniverse && needsInitialize(isFlagRelated = false, mask = 0)) initialize + typeOfThis + } + def baseClasses = info.baseClasses def module = sourceModule def thisPrefix: Type = thisType - def selfType: Type = typeOfThis def typeSignature: Type = { fullyInitializeSymbol(this); info } def typeSignatureIn(site: Type): Type = { fullyInitializeSymbol(this); site memberInfo this } diff --git a/test/files/run/t7045.check b/test/files/run/t7045.check new file mode 100644 index 0000000000..28134535c8 --- /dev/null +++ b/test/files/run/t7045.check @@ -0,0 +1,2 @@ +D with C +D with C diff --git a/test/files/run/t7045.scala b/test/files/run/t7045.scala new file mode 100644 index 0000000000..f41baca05e --- /dev/null +++ b/test/files/run/t7045.scala @@ -0,0 +1,12 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} + +class C +class D { self: C => } + +object Test extends App { + val d = cm.staticClass("D") + println(d.selfType) + d.typeSignature + println(d.selfType) +} \ No newline at end of file -- cgit v1.2.3 From 4cbb9357c5b0a9bfd58fcb99f76ca320df7a3d5c Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 26 Jan 2013 17:11:13 +0100 Subject: synchronizes toolboxes We don't guarantee thread-safety of the front end, but everything else looks good now. --- .../scala/tools/reflect/ToolBoxFactory.scala | 52 ++++++++++++---------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index c05c59d5ff..93fafda463 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -352,15 +352,19 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => lazy val importer = compiler.mkImporter(u) lazy val exporter = importer.reverse - def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = compiler.withCleanupCaches { - if (compiler.settings.verbose.value) println("importing "+tree+", expectedType = "+expectedType) - var ctree: compiler.Tree = importer.importTree(tree) - var cexpectedType: compiler.Type = importer.importType(expectedType) - - if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType) - val ttree: compiler.Tree = compiler.typeCheck(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) - val uttree = exporter.importTree(ttree) - uttree + private[this] val toolBoxLock = new Object + + def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = toolBoxLock.synchronized { + compiler.withCleanupCaches { + if (compiler.settings.verbose.value) println("importing "+tree+", expectedType = "+expectedType) + var ctree: compiler.Tree = importer.importTree(tree) + var cexpectedType: compiler.Type = importer.importType(expectedType) + + if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType) + val ttree: compiler.Tree = compiler.typeCheck(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) + val uttree = exporter.importTree(ttree) + uttree + } } def inferImplicitValue(pt: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree = { @@ -372,26 +376,28 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) } - private def inferImplicit(tree: u.Tree, pt: u.Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: u.Position): u.Tree = compiler.withCleanupCaches { - if (compiler.settings.verbose.value) println("importing "+pt, ", tree = "+tree+", pos = "+pos) - var ctree: compiler.Tree = importer.importTree(tree) - var cpt: compiler.Type = importer.importType(pt) - var cpos: compiler.Position = importer.importPosition(pos) - - if (compiler.settings.verbose.value) println("inferring implicit %s of type %s, macros = %s".format(if (isView) "view" else "value", pt, !withMacrosDisabled)) - val itree: compiler.Tree = compiler.inferImplicit(ctree, cpt, isView = isView, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = cpos) - val uitree = exporter.importTree(itree) - uitree + private def inferImplicit(tree: u.Tree, pt: u.Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: u.Position): u.Tree = toolBoxLock.synchronized { + compiler.withCleanupCaches { + if (compiler.settings.verbose.value) println("importing "+pt, ", tree = "+tree+", pos = "+pos) + var ctree: compiler.Tree = importer.importTree(tree) + var cpt: compiler.Type = importer.importType(pt) + var cpos: compiler.Position = importer.importPosition(pos) + + if (compiler.settings.verbose.value) println("inferring implicit %s of type %s, macros = %s".format(if (isView) "view" else "value", pt, !withMacrosDisabled)) + val itree: compiler.Tree = compiler.inferImplicit(ctree, cpt, isView = isView, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = cpos) + val uitree = exporter.importTree(itree) + uitree + } } - def resetAllAttrs(tree: u.Tree): u.Tree = { + def resetAllAttrs(tree: u.Tree): u.Tree = toolBoxLock.synchronized { val ctree: compiler.Tree = importer.importTree(tree) val ttree: compiler.Tree = compiler.resetAllAttrs(ctree) val uttree = exporter.importTree(ttree) uttree } - def resetLocalAttrs(tree: u.Tree): u.Tree = { + def resetLocalAttrs(tree: u.Tree): u.Tree = toolBoxLock.synchronized { val ctree: compiler.Tree = importer.importTree(tree) val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree) val uttree = exporter.importTree(ttree) @@ -401,14 +407,14 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => def showAttributed(tree: u.Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = compiler.showAttributed(importer.importTree(tree), printTypes, printIds, printKinds) - def parse(code: String): u.Tree = { + def parse(code: String): u.Tree = toolBoxLock.synchronized { if (compiler.settings.verbose.value) println("parsing "+code) val ctree: compiler.Tree = compiler.parse(code) val utree = exporter.importTree(ctree) utree } - def compile(tree: u.Tree): () => Any = { + def compile(tree: u.Tree): () => Any = toolBoxLock.synchronized { if (compiler.settings.verbose.value) println("importing "+tree) var ctree: compiler.Tree = importer.importTree(tree) -- cgit v1.2.3 From dd148de5a875dd8d691ffdd983b7f2b978a148df Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 4 Feb 2013 11:08:21 +0100 Subject: synchronizes pendingVolatiles Called from isVolatile, which is called from isStable, which is a part of the public reflection API. --- src/reflect/scala/reflect/internal/Types.scala | 4 ---- src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 0afbdc56c8..6d91948d66 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2066,10 +2066,6 @@ trait Types extends api.Types { self: SymbolTable => def apply(value: Constant) = unique(new UniqueConstantType(value)) } - /* Syncnote: The `volatile` var and `pendingVolatiles` mutable set need not be protected - * with synchronized, because they are accessed only from isVolatile, which is called only from - * Typer. - */ private var volatileRecursions: Int = 0 private val pendingVolatiles = new mutable.HashSet[Symbol] diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 85bd9ff8b6..5a0ac01ac4 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -61,6 +61,8 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb } } + override def isStable: Boolean = gilSynchronized { super.isStable } + // ------ creators ------------------------------------------------------------------- override protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol = -- cgit v1.2.3 From f4dd56ca5d5adb2a9183991a7ecebc2b6a1f1fc5 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 5 Feb 2013 20:59:42 +0100 Subject: synchronizes names Previously we didn't have all possible name creation facilities covered with locks, so some of them silently misbehaved and caused much grief: http://groups.google.com/group/scala-internals/browse_thread/thread/ec1d3e2c4bcb000a. This patch gets all the name factories under control. Unfortunately it comes at a performance cost, which has to be evaluated. --- src/reflect/scala/reflect/internal/Names.scala | 54 ++++++++++++---------- .../scala/reflect/runtime/SynchronizedOps.scala | 8 +++- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala index c78ba72dfb..01ad18d3a0 100644 --- a/src/reflect/scala/reflect/internal/Names.scala +++ b/src/reflect/scala/reflect/internal/Names.scala @@ -21,7 +21,7 @@ trait LowPriorityNames { * @author Martin Odersky * @version 1.0, 05/02/2005 */ -trait Names extends api.Names with LowPriorityNames { +trait Names extends api.Names with LowPriorityNames { self => implicit def promoteTermNamesAsNecessary(name: Name): TermName = name.toTermName // Operations ------------------------------------------------------------- @@ -109,6 +109,26 @@ trait Names extends api.Names with LowPriorityNames { protected def newTypeName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TypeName = newTermName(cs, offset, len, cachedString).toTypeName + protected def toTypeName(termName: TermName): TypeName = { + val h = hashValue(chrs, termName.index, termName.len) & HASH_MASK + var n = typeHashtable(h) + while ((n ne null) && n.start != termName.index) + n = n.next + + if (n ne null) n + else termName.createCompanionName(h) + } + + protected def toTermName(typeName: TypeName): TermName = { + val h = hashValue(chrs, typeName.index, typeName.len) & HASH_MASK + var n = termHashtable(h) + while ((n ne null) && n.start != typeName.index) + n = n.next + + if (n ne null) n + else typeName.createCompanionName(h) + } + /** Create a term name from string. */ def newTermName(s: String): TermName = newTermName(s.toCharArray(), 0, s.length(), null) @@ -145,7 +165,7 @@ trait Names extends api.Names with LowPriorityNames { * or Strings as Names. Give names the key functions the absence of which * make people want Strings all the time. */ - sealed abstract class Name(protected val index: Int, protected val len: Int) extends NameApi { + sealed abstract class Name(protected[Names] val index: Int, protected[Names] val len: Int) extends NameApi { type ThisNameType >: Null <: Name protected[this] def thisName: ThisNameType @@ -463,21 +483,21 @@ trait Names extends api.Names with LowPriorityNames { * TermName_R and TypeName_R recreate it each time toString is called. */ private class TermName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TermName(index0, len0, hash) { - protected def createCompanionName(h: Int): TypeName = new TypeName_S(index, len, h, toString) + @inline final def createCompanionName(h: Int): TypeName = new TypeName_S(index, len, h, toString) override def newName(str: String): TermName = newTermNameCached(str) } private class TypeName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TypeName(index0, len0, hash) { - protected def createCompanionName(h: Int): TermName = new TermName_S(index, len, h, toString) + @inline final def createCompanionName(h: Int): TermName = new TermName_S(index, len, h, toString) override def newName(str: String): TypeName = newTypeNameCached(str) } private class TermName_R(index0: Int, len0: Int, hash: Int) extends TermName(index0, len0, hash) { - protected def createCompanionName(h: Int): TypeName = new TypeName_R(index, len, h) + @inline final def createCompanionName(h: Int): TypeName = new TypeName_R(index, len, h) override def toString = new String(chrs, index, len) } private class TypeName_R(index0: Int, len0: Int, hash: Int) extends TypeName(index0, len0, hash) { - protected def createCompanionName(h: Int): TermName = new TermName_R(index, len, h) + @inline final def createCompanionName(h: Int): TermName = new TermName_R(index, len, h) override def toString = new String(chrs, index, len) } @@ -490,22 +510,14 @@ trait Names extends api.Names with LowPriorityNames { def isTermName: Boolean = true def isTypeName: Boolean = false def toTermName: TermName = this - def toTypeName: TypeName = { - val h = hashValue(chrs, index, len) & HASH_MASK - var n = typeHashtable(h) - while ((n ne null) && n.start != index) - n = n.next - - if (n ne null) n - else createCompanionName(h) - } + def toTypeName: TypeName = self.toTypeName(this) def newName(str: String): TermName = newTermName(str) def companionName: TypeName = toTypeName def subName(from: Int, to: Int): TermName = newTermName(chrs, start + from, to - from) def nameKind = "term" - protected def createCompanionName(h: Int): TypeName + def createCompanionName(h: Int): TypeName } implicit val TermNameTag = ClassTag[TermName](classOf[TermName]) @@ -518,15 +530,7 @@ trait Names extends api.Names with LowPriorityNames { typeHashtable(hash) = this def isTermName: Boolean = false def isTypeName: Boolean = true - def toTermName: TermName = { - val h = hashValue(chrs, index, len) & HASH_MASK - var n = termHashtable(h) - while ((n ne null) && n.start != index) - n = n.next - - if (n ne null) n - else createCompanionName(h) - } + def toTermName: TermName = self.toTermName(this) def toTypeName: TypeName = this def newName(str: String): TypeName = newTypeName(str) def companionName: TermName = toTermName diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala index d022bf66ba..f9f4a26b42 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala @@ -13,8 +13,12 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable // therefore we don't have a danger of a deadlock from having a fine-grained lock for name creation private lazy val nameLock = new Object - override def newTermName(s: String): TermName = nameLock.synchronized { super.newTermName(s) } - override def newTypeName(s: String): TypeName = nameLock.synchronized { super.newTypeName(s) } + // these three methods are the only gateways into name hashtable manipulations + // we need to protected them with a lock, because they are by far not atomic + override protected def newTermName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TermName = + nameLock.synchronized { super.newTermName(cs, offset, len, cachedString) } + override protected def toTypeName(termName: TermName): TypeName = nameLock.synchronized { super.toTypeName(termName) } + override protected def toTermName(typeName: TypeName): TermName = nameLock.synchronized { super.toTermName(typeName) } // BaseTypeSeqs -- cgit v1.2.3 From 73d079fb383f82e825c2a40b397b64288e218fe9 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 29 Jan 2013 20:36:55 +0100 Subject: removes the assertion in missingHook In the current synchronization scheme multiple threads can enter the missingHook trying to materialize a package, which hasn't been created. That's fine, because makeScalaPackage, which creates and enters package symbols is synchronized and checks whether the creation is necessary before commencing. Therefore even if makeScalaPackage is called multiple times in rapid succession, the calls will be serialized and all calls except the first one won't do anything. --- src/reflect/scala/reflect/runtime/JavaMirrors.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index ac968b8e3f..58ade961a7 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -1264,8 +1264,6 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni override def missingHook(owner: Symbol, name: Name): Symbol = { if (owner.hasPackageFlag) { val mirror = mirrorThatLoaded(owner) - // todo. this makes toolbox tests pass, but it's a mere workaround for SI-5865 -// assert((owner.info decl name) == NoSymbol, s"already exists: $owner . $name") if (owner.isRootSymbol && mirror.tryJavaClass(name.toString).isDefined) return mirror.EmptyPackageClass.info decl name if (name.isTermName && !owner.isEmptyPackageClass) -- cgit v1.2.3 From 387b2590db6c4f16183ea309b7451ed1fe8365ab Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 26 Jan 2013 21:39:53 +0100 Subject: runtime reflection: death from thousand threads not anymore --- test/files/run/reflection-sync-potpourri.check | 1000 ++++++++++++++++++++++++ test/files/run/reflection-sync-potpourri.scala | 31 + test/files/run/reflection-sync-subtypes.check | 1000 ++++++++++++++++++++++++ test/files/run/reflection-sync-subtypes.scala | 20 + 4 files changed, 2051 insertions(+) create mode 100644 test/files/run/reflection-sync-potpourri.check create mode 100644 test/files/run/reflection-sync-potpourri.scala create mode 100644 test/files/run/reflection-sync-subtypes.check create mode 100644 test/files/run/reflection-sync-subtypes.scala diff --git a/test/files/run/reflection-sync-potpourri.check b/test/files/run/reflection-sync-potpourri.check new file mode 100644 index 0000000000..fa83c149a6 --- /dev/null +++ b/test/files/run/reflection-sync-potpourri.check @@ -0,0 +1,1000 @@ +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec +s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec diff --git a/test/files/run/reflection-sync-potpourri.scala b/test/files/run/reflection-sync-potpourri.scala new file mode 100644 index 0000000000..06dcea9209 --- /dev/null +++ b/test/files/run/reflection-sync-potpourri.scala @@ -0,0 +1,31 @@ +import scala.reflect.runtime.universe._ + +// this test checks that under heavily multithreaded conditions: +// 1) scala.reflect.runtime.universe, its rootMirror and definitions are initialized correctly +// 2) symbols are correctly materialized into PackageScopes (no dupes) +// 3) unpickling works okay even we unpickle the same symbol a lot of times + +object Test extends App { + def foo[T: TypeTag](x: T) = typeOf[T].toString + val n = 1000 + val rng = new scala.util.Random() + val types = List( + () => typeOf[java.lang.reflect.Method], + () => typeOf[java.lang.annotation.Annotation], + () => typeOf[scala.io.BufferedSource], + () => typeOf[scala.io.Codec]) + val perms = types.permutations.toList + def force(lazytpe: () => Type): String = { + lazytpe().typeSymbol.typeSignature + lazytpe().toString + } + val diceRolls = List.fill(n)(rng.nextInt(perms.length)) + val threads = (1 to n) map (i => new Thread(s"Reflector-$i") { + override def run(): Unit = { + val s1 = foo("42") + val s2 = perms(diceRolls(i - 1)).map(x => force(x)).sorted.mkString(", ") + println(s"s1 = $s1, s2 = $s2") + } + }) + threads foreach (_.start) +} \ No newline at end of file diff --git a/test/files/run/reflection-sync-subtypes.check b/test/files/run/reflection-sync-subtypes.check new file mode 100644 index 0000000000..f223c7ae2a --- /dev/null +++ b/test/files/run/reflection-sync-subtypes.check @@ -0,0 +1,1000 @@ +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true +false, false, true, true diff --git a/test/files/run/reflection-sync-subtypes.scala b/test/files/run/reflection-sync-subtypes.scala new file mode 100644 index 0000000000..659a7c0cdb --- /dev/null +++ b/test/files/run/reflection-sync-subtypes.scala @@ -0,0 +1,20 @@ +import scala.reflect.runtime.universe._ + +object Test extends App { + val n = 1000 + val rng = new scala.util.Random() + val tasks = List( + () => typeOf[List[Int]] <:< typeOf[List[T] forSome { type T }], + () => typeOf[List[T] forSome { type T }] <:< typeOf[List[Any]], + () => typeOf[Map[Int, Object]] <:< typeOf[Iterable[(Int, String)]], + () => typeOf[Expr[Any] { val mirror: rootMirror.type }] <:< typeOf[Expr[List[List[List[Int]]]]{ val mirror: rootMirror.type }]) + val perms = tasks.permutations.toList + val diceRolls = List.fill(n)(rng.nextInt(perms.length)) + val threads = (1 to n) map (i => new Thread(s"Reflector-$i") { + override def run(): Unit = { + val result = perms(diceRolls(i - 1)).map(_()) + println(result.sorted.mkString(", ")) + } + }) + threads foreach (_.start) +} \ No newline at end of file -- cgit v1.2.3 From 53c499bec28ccbc7695c79f56e40f98e7732aeb7 Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Tue, 19 Feb 2013 21:29:30 +0400 Subject: SI-7109 SI-7153 Generalize the API to get docComments: allow to force docTrees for given fragments. Don't type-check when forcing doc comments, but rather do it directly. Test the new functionality as well as better tests for the old one. --- src/compiler/scala/tools/nsc/ast/DocComments.scala | 5 + .../tools/nsc/interactive/CompilerControl.scala | 31 +++--- .../scala/tools/nsc/interactive/Global.scala | 83 +++++++-------- .../scala/tools/nsc/interactive/Picklers.scala | 4 +- .../scala/tools/nsc/typechecker/Typers.scala | 3 +- test/files/presentation/doc.check | 50 +-------- test/files/presentation/doc/doc.scala | 118 +++++++++++++++------ test/files/presentation/doc/src/Class.scala | 1 + test/files/presentation/doc/src/Test.scala | 1 - test/files/presentation/doc/src/p/Base.scala | 11 ++ test/files/presentation/doc/src/p/Derived.scala | 9 ++ 11 files changed, 171 insertions(+), 145 deletions(-) create mode 100755 test/files/presentation/doc/src/Class.scala delete mode 100755 test/files/presentation/doc/src/Test.scala create mode 100755 test/files/presentation/doc/src/p/Base.scala create mode 100755 test/files/presentation/doc/src/p/Derived.scala diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index e635c5e87d..6e39fc9aa1 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -56,6 +56,11 @@ trait DocComments { self: Global => else sym.owner.ancestors map (sym overriddenSymbol _) filter (_ != NoSymbol) } + def fillDocComment(sym: Symbol, comment: DocComment) { + docComments(sym) = comment + comment.defineVariables(sym) + } + /** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by * missing sections of an inherited doc comment. * If a symbol does not have a doc comment but some overridden version of it does, diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala index 73738ebd21..af82957a2e 100644 --- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala +++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala @@ -164,17 +164,22 @@ trait CompilerControl { self: Global => /** Sets sync var `response` to doc comment information for a given symbol. * - * @param sym The symbol whose doc comment should be retrieved (might come from a classfile) - * @param site The place where sym is observed. - * @param source The source file that's supposed to contain the definition - * @param response A response that will be set to the following: - * If `source` contains a definition of a given symbol that has a doc comment, - * the (expanded, raw, position) triplet for a comment, otherwise ("", "", NoPosition). - * Note: This operation does not automatically load `source`. If `source` - * is unloaded, it stays that way. + * @param sym The symbol whose doc comment should be retrieved (might come from a classfile) + * @param source The source file that's supposed to contain the definition + * @param site The symbol where 'sym' is observed + * @param fragments All symbols that can contribute to the generated documentation + * together with their source files. + * @param response A response that will be set to the following: + * If `source` contains a definition of a given symbol that has a doc comment, + * the (expanded, raw, position) triplet for a comment, otherwise ("", "", NoPosition). + * Note: This operation does not automatically load sources that are not yet loaded. */ - def askDocComment(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]) = - postWorkItem(new AskDocCommentItem(sym, site, source, response)) + def askDocComment(sym: Symbol, source: SourceFile, site: Symbol, fragments: List[(Symbol,SourceFile)], response: Response[(String, String, Position)]): Unit = + postWorkItem(new AskDocCommentItem(sym, source, site, fragments, response)) + + @deprecated("Use method that accepts fragments", "2.10.2") + def askDocComment(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]): Unit = + askDocComment(sym, source, site, (sym,source)::Nil, response) /** Sets sync var `response` to list of members that are visible * as members of the tree enclosing `pos`, possibly reachable by an implicit. @@ -390,9 +395,9 @@ trait CompilerControl { self: Global => response raise new MissingResponse } - case class AskDocCommentItem(val sym: Symbol, val site: Symbol, val source: SourceFile, response: Response[(String, String, Position)]) extends WorkItem { - def apply() = self.getDocComment(sym, site, source, response) - override def toString = "doc comment "+sym+" in "+source + case class AskDocCommentItem(val sym: Symbol, val source: SourceFile, val site: Symbol, val fragments: List[(Symbol,SourceFile)], response: Response[(String, String, Position)]) extends WorkItem { + def apply() = self.getDocComment(sym, source, site, fragments, response) + override def toString = "doc comment "+sym+" in "+source+" with fragments:"+fragments.mkString("(", ",", ")") def raiseMissing() = response raise new MissingResponse diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 4c2c3e35f8..1f2245abb5 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -704,8 +704,8 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") * If we do just removeUnit, some problems with default parameters can ensue. * Calls to this method could probably be replaced by removeUnit once default parameters are handled more robustly. */ - private def afterRunRemoveUnitOf(source: SourceFile) { - toBeRemovedAfterRun += source.file + private def afterRunRemoveUnitsOf(sources: List[SourceFile]) { + toBeRemovedAfterRun ++= sources map (_.file) } /** A fully attributed tree located at position `pos` */ @@ -713,7 +713,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") case None => reloadSources(List(pos.source)) try typedTreeAt(pos) - finally afterRunRemoveUnitOf(pos.source) + finally afterRunRemoveUnitsOf(List(pos.source)) case Some(unit) => informIDE("typedTreeAt " + pos) parseAndEnter(unit) @@ -763,14 +763,23 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") respond(response)(typedTree(source, forceReload)) } + private def withTempUnits[T](sources: List[SourceFile])(f: (SourceFile => RichCompilationUnit) => T): T = { + val unitOfSrc: SourceFile => RichCompilationUnit = src => unitOfFile(src.file) + sources filterNot (getUnit(_).isDefined) match { + case Nil => + f(unitOfSrc) + case unknown => + reloadSources(unknown) + try { + f(unitOfSrc) + } finally + afterRunRemoveUnitsOf(unknown) + } + } + private def withTempUnit[T](source: SourceFile)(f: RichCompilationUnit => T): T = - getUnit(source) match { - case None => - reloadSources(List(source)) - try f(getUnit(source).get) - finally afterRunRemoveUnitOf(source) - case Some(unit) => - f(unit) + withTempUnits(List(source)){ srcToUnit => + f(srcToUnit(source)) } /** Find a 'mirror' of symbol `sym` in unit `unit`. Pre: `unit is loaded. */ @@ -834,50 +843,36 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") } } + private def forceDocComment(sym: Symbol, unit: RichCompilationUnit) { + unit.body foreachPartial { + case DocDef(comment, defn) if defn.symbol == sym => + fillDocComment(defn.symbol, comment) + EmptyTree + case _: ValOrDefDef => + EmptyTree + } + } + /** Implements CompilerControl.askDocComment */ - private[interactive] def getDocComment(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]) { - informIDE("getDocComment "+sym+" "+source) + private[interactive] def getDocComment(sym: Symbol, source: SourceFile, site: Symbol, fragments: List[(Symbol,SourceFile)], + response: Response[(String, String, Position)]) { + informIDE(s"getDocComment $sym at $source site $site") respond(response) { - withTempUnit(source){ u => - val mirror = findMirrorSymbol(sym, u) + withTempUnits(fragments.toList.unzip._2){ units => + for((sym, src) <- fragments) { + val mirror = findMirrorSymbol(sym, units(src)) + if (mirror ne NoSymbol) forceDocComment(mirror, units(src)) + } + val mirror = findMirrorSymbol(sym, units(source)) if (mirror eq NoSymbol) ("", "", NoPosition) else { - forceDocComment(mirror, u) - (expandedDocComment(mirror), rawDocComment(mirror), docCommentPos(mirror)) + (expandedDocComment(mirror, site), rawDocComment(mirror), docCommentPos(mirror)) } } } } - private def forceDocComment(sym: Symbol, unit: RichCompilationUnit) { - // Either typer has been run and we don't find DocDef, - // or we force the targeted typecheck here. - // In both cases doc comment maps should be filled for the subject symbol. - val docTree = - unit.body find { - case DocDef(_, defn) if defn.symbol eq sym => true - case _ => false - } - - for (t <- docTree) { - debugLog("Found DocDef tree for "+sym) - // Cannot get a typed tree at position since DocDef range is transparent. - val prevPos = unit.targetPos - val prevInterruptsEnabled = interruptsEnabled - try { - unit.targetPos = t.pos - interruptsEnabled = true - typeCheck(unit) - } catch { - case _: TyperResult => // ignore since we are after the side effect. - } finally { - unit.targetPos = prevPos - interruptsEnabled = prevInterruptsEnabled - } - } - } - def stabilizedType(tree: Tree): Type = tree match { case Ident(_) if tree.symbol.isStable => singleType(NoPrefix, tree.symbol) diff --git a/src/compiler/scala/tools/nsc/interactive/Picklers.scala b/src/compiler/scala/tools/nsc/interactive/Picklers.scala index 84cb03c140..2b389158c3 100644 --- a/src/compiler/scala/tools/nsc/interactive/Picklers.scala +++ b/src/compiler/scala/tools/nsc/interactive/Picklers.scala @@ -166,8 +166,8 @@ trait Picklers { self: Global => .asClass (classOf[AskLinkPosItem]) implicit def askDocCommentItem: CondPickler[AskDocCommentItem] = - (pkl[Symbol] ~ pkl[Symbol] ~ pkl[SourceFile]) - .wrapped { case sym ~ site ~ source => new AskDocCommentItem(sym, site, source, new Response) } { item => item.sym ~ item.site ~ item.source } + (pkl[Symbol] ~ pkl[SourceFile] ~ pkl[Symbol] ~ pkl[List[(Symbol,SourceFile)]]) + .wrapped { case sym ~ source ~ site ~ fragments => new AskDocCommentItem(sym, source, site, fragments, new Response) } { item => item.sym ~ item.source ~ item.site ~ item.fragments } .asClass (classOf[AskDocCommentItem]) implicit def askLoadedTypedItem: CondPickler[AskLoadedTypedItem] = diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f97582f45c..24857e4ab0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5289,8 +5289,7 @@ trait Typers extends Modes with Adaptations with Tags { def typedDocDef(docdef: DocDef) = { if (forScaladoc && (sym ne null) && (sym ne NoSymbol)) { val comment = docdef.comment - docComments(sym) = comment - comment.defineVariables(sym) + fillDocComment(sym, comment) val typer1 = newTyper(context.makeNewScope(tree, context.owner)) for (useCase <- comment.useCases) { typer1.silent(_.typedUseCase(useCase)) match { diff --git a/test/files/presentation/doc.check b/test/files/presentation/doc.check index e33756773d..5a3ff13151 100644 --- a/test/files/presentation/doc.check +++ b/test/files/presentation/doc.check @@ -1,49 +1 @@ -reload: Test.scala -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version: -@since: -@todo: -@note: -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since: -@todo: -@note: -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10)))))) -@todo: -@note: -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10)))))) -@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe))))))) -@note: -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10)))))) -@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe))))))) -@note:Body(List(Paragraph(Chain(List(Summary(Text(Don't inherit!))))))) -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10)))))) -@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe))))))) -@note:Body(List(Paragraph(Chain(List(Summary(Text(Don't inherit!))))))) -@see:Body(List(Paragraph(Chain(List(Summary(Text(some other method))))))) +reload: Base.scala, Class.scala, Derived.scala diff --git a/test/files/presentation/doc/doc.scala b/test/files/presentation/doc/doc.scala index 5855f488b8..371b825026 100755 --- a/test/files/presentation/doc/doc.scala +++ b/test/files/presentation/doc/doc.scala @@ -4,27 +4,40 @@ import scala.tools.nsc.doc.base.comment._ import scala.tools.nsc.interactive._ import scala.tools.nsc.interactive.tests._ import scala.tools.nsc.util._ -import scala.tools.nsc.io._ object Test extends InteractiveTest { val tags = Seq( "@example `\"abb\".permutations = Iterator(abb, bab, bba)`", "@version 1.0, 09/07/2012", "@since 2.10", - "@todo this method is unsafe", + "@todo this is unsafe!", "@note Don't inherit!", - "@see some other method" + "@see something else" ) - val comment = "This is a test comment." - val caret = "" + val names = Seq("Class", "Def", "Val", "Var", "AbstracType", "TypeAlias", "Trait", "InnerClass") + val bareText = + """abstract class %s { + | def %s = "" + | val %s = "" + | var %s: String = _ + | type %s + | type %s = String + | class %s + |} + |trait %s""".stripMargin.format(names: _*) + + def docComment(nTags: Int) = "/**\n%s*/".format(tags.take(nTags).mkString("\n")) + + def text(name: String, nTags: Int) = { + val nameIndex = bareText.indexOf(name) + val (pre, post) = bareText.splitAt(nameIndex) + val crIndex = pre.lastIndexOf("\n") + val (prepre, prepost) = pre.splitAt(crIndex) + prepre + docComment(nTags) + prepost + post + } + - def text(nTags: Int) = - """|/** %s - | - | * %s */ - |trait Commented {} - |class User(c: %sCommented)""".stripMargin.format(comment, tags take nTags mkString "\n", caret) override lazy val compiler = { prepareSettings(settings) @@ -38,9 +51,9 @@ object Test extends InteractiveTest { override def forScaladoc = true - def getComment(sym: Symbol, source: SourceFile) = { + def getComment(sym: Symbol, source: SourceFile, fragments: List[(Symbol,SourceFile)]): Option[Comment] = { val docResponse = new Response[(String, String, Position)] - askDocComment(sym, sym.owner, source, docResponse) + askDocComment(sym, source, sym.owner, fragments, docResponse) docResponse.get.left.toOption flatMap { case (expanded, raw, pos) => if (expanded.isEmpty) @@ -53,37 +66,74 @@ object Test extends InteractiveTest { } override def runDefaultTests() { - for (i <- 1 to tags.length) { - val markedText = text(i) - val idx = markedText.indexOf(caret) - val fileText = markedText.substring(0, idx) + markedText.substring(idx + caret.length) - val source = sourceFiles(0) - val batch = new BatchSourceFile(source.file, fileText.toCharArray) + import compiler._ + def findSource(name: String) = sourceFiles.find(_.file.name == name).get + + val className = names.head + for (name <- names; + i <- 1 to tags.length) { + val newText = text(name, i) + val source = findSource("Class.scala") + val batch = new BatchSourceFile(source.file, newText.toCharArray) val reloadResponse = new Response[Unit] compiler.askReload(List(batch), reloadResponse) reloadResponse.get.left.toOption match { case None => - reporter.println("Couldn't reload") + println("Couldn't reload") case Some(_) => - val treeResponse = new compiler.Response[compiler.Tree] - val pos = compiler.rangePos(batch, idx, idx, idx) - compiler.askTypeAt(pos, treeResponse) - treeResponse.get.left.toOption match { - case Some(tree) => - val sym = tree.tpe.typeSymbol - compiler.getComment(sym, batch) match { - case None => println("Got no doc comment") + val parseResponse = new Response[Tree] + askParsedEntered(batch, true, parseResponse) + parseResponse.get.left.toOption match { + case None => + println("Couldn't parse") + case Some(_) => + val sym = compiler.ask { () => + val toplevel = definitions.EmptyPackage.info.decl(newTypeName(name)) + if (toplevel eq NoSymbol) { + val clazz = definitions.EmptyPackage.info.decl(newTypeName(className)) + + val term = clazz.info.decl(newTermName(name)) + if (term eq NoSymbol) clazz.info.decl(newTypeName(name)) else + if (term.isAccessor) term.accessed else term + } else toplevel + } + + getComment(sym, batch, (sym,batch)::Nil) match { + case None => println(s"Got no doc comment for $name") case Some(comment) => import comment._ - val tags: List[(String, Iterable[Body])] = - List(("@example", example), ("@version", version), ("@since", since.toList), ("@todo", todo), ("@note", note), ("@see", see)) - val str = ("body:" + body + "\n") + - tags.map{ case (name, bodies) => name + ":" + bodies.mkString("\n") }.mkString("\n") - println(str) + def cnt(bodies: Iterable[Body]) = bodies.size + val actual = cnt(example) + cnt(version) + cnt(since) + cnt(todo) + cnt(note) + cnt(see) + if (actual != i) + println(s"Got docComment with $actual tags instead of $i, file text:\n$newText") } - case None => println("Couldn't find a typedTree") } } } + + // Check inter-classes documentation one-time retrieved ok. + val baseSource = findSource("Base.scala") + val derivedSource = findSource("Derived.scala") + def existsText(where: Any, text: String): Boolean = where match { + case `text` => true + case s: Seq[_] => s exists (existsText(_, text)) + case p: Product => p.productIterator exists (existsText(_, text)) + } + val (derived, base) = compiler.ask { () => + val derived = definitions.RootPackage.info.decl(newTermName("p")).info.decl(newTypeName("Derived")) + (derived, derived.ancestors(0)) + } + val cmt1 = getComment(derived, derivedSource, (base, baseSource)::(derived, derivedSource)::Nil) + if (!existsText(cmt1, "Derived comment.")) + println("Unexpected Derived class comment:"+cmt1) + + val (fooDerived, fooBase) = compiler.ask { () => + val decl = derived.tpe.decl(newTermName("foo")) + (decl, decl.allOverriddenSymbols(0)) + } + + val cmt2 = getComment(fooDerived, derivedSource, (fooBase, baseSource)::(fooDerived, derivedSource)::Nil) + if (!existsText(cmt2, "Base method has documentation.")) + println("Unexpected foo method comment:"+cmt2) } } diff --git a/test/files/presentation/doc/src/Class.scala b/test/files/presentation/doc/src/Class.scala new file mode 100755 index 0000000000..a974bd6f5c --- /dev/null +++ b/test/files/presentation/doc/src/Class.scala @@ -0,0 +1 @@ +object Class \ No newline at end of file diff --git a/test/files/presentation/doc/src/Test.scala b/test/files/presentation/doc/src/Test.scala deleted file mode 100755 index fcc1554994..0000000000 --- a/test/files/presentation/doc/src/Test.scala +++ /dev/null @@ -1 +0,0 @@ -object Test \ No newline at end of file diff --git a/test/files/presentation/doc/src/p/Base.scala b/test/files/presentation/doc/src/p/Base.scala new file mode 100755 index 0000000000..9031de3e3e --- /dev/null +++ b/test/files/presentation/doc/src/p/Base.scala @@ -0,0 +1,11 @@ +package p + +/** + * @define BaseComment $BaseVar comment. + */ +trait Base { + /** + * Base method has documentation. + */ + def foo: String +} diff --git a/test/files/presentation/doc/src/p/Derived.scala b/test/files/presentation/doc/src/p/Derived.scala new file mode 100755 index 0000000000..1a9c9a26d1 --- /dev/null +++ b/test/files/presentation/doc/src/p/Derived.scala @@ -0,0 +1,9 @@ +package p + +/** + * $BaseComment + * @define BaseVar Derived + */ +class Derived extends Base { + def foo = "" +} -- cgit v1.2.3 From 696dcdfcdb40ee3dbd2ba63f8281b87cde787a00 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 25 Feb 2013 17:58:11 +0100 Subject: SI-7126 Account for the alias types that don't dealias. After this change: qbin/scalac -Ydebug test/files/pos/t7126.scala 2>&1 | grep warning warning: dropExistential did not progress dealiasing Test.this.T[Test.this.T], see SI-7126 one warning found T[T]? Really? The true bug lies somewhere else; the comments of the ticket illuminate the general areas of concern. --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 9 +++++++-- test/files/pos/t7126.scala | 11 +++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 test/files/pos/t7126.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index cff3f4f0fa..4fb68fc2a9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -222,8 +222,13 @@ trait Typers extends Modes with Adaptations with Tags { new SubstWildcardMap(tparams).apply(tp) case TypeRef(_, sym, _) if sym.isAliasType => val tp0 = tp.dealias - val tp1 = dropExistential(tp0) - if (tp1 eq tp0) tp else tp1 + if (tp eq tp0) { + debugwarn(s"dropExistential did not progress dealiasing $tp, see SI-7126") + tp + } else { + val tp1 = dropExistential(tp0) + if (tp1 eq tp0) tp else tp1 + } case _ => tp } diff --git a/test/files/pos/t7126.scala b/test/files/pos/t7126.scala new file mode 100644 index 0000000000..6720511e08 --- /dev/null +++ b/test/files/pos/t7126.scala @@ -0,0 +1,11 @@ +import language._ + +object Test { + type T = Any + boom(???): Option[T] // SOE + def boom[CC[U]](t : CC[T]): Option[CC[T]] = None + + // okay + foo(???): Option[Any] + def foo[CC[U]](t : CC[Any]): Option[CC[Any]] = None +} \ No newline at end of file -- cgit v1.2.3 From 0303e64efa8ee223c0767d7be8d2875a62b88aea Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 25 Feb 2013 21:54:09 +0100 Subject: SI-7183 Disable unreachability for withFilter matches. This avoids spurious unreachable warnings on code that the user didn't write. The parser desugars for-comprehensions such as: for (A(a) <- List(new A)) yield a To: List(new A()).withFilter(((check$ifrefutable$2) => check$ifrefutable$2: @scala.unhecked match { case A((a @ _)) => true case _ => false }) ) But, if `A.unapply` returns `Some[_]`, the last case is dead code. (Matching against a regular case class *would* fall through in the caes of a null scrutinee.) In SI-6902, we enabled unreachability warnings, even if the scrutinee was annotated as @unchecked. That was consistent with the 2.9.2 behaviour, it was only disabled temporarily (actually, accidentally) in 2.10.0. But, the old pattern matcher didn't warn about this code. This commit makes the pattern matcher recognise the special scrutinee based on its name and disables both exhaustivity *and* unreachability analysis. To do so, the we generalize the boolean flag `unchecked` to the class `Suppression`. --- .../tools/nsc/typechecker/PatternMatching.scala | 42 ++++++++++++++-------- test/files/pos/t7183.flags | 1 + test/files/pos/t7183.scala | 13 +++++++ 3 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 test/files/pos/t7183.flags create mode 100644 test/files/pos/t7183.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index f7579ad249..87fe3fb3f6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -936,7 +936,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // the making of the trees /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// trait TreeMakers extends TypedSubstitution { self: CodegenCore => - def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) = + def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, supression: Suppression): (List[List[TreeMaker]], List[Tree]) = (cases, Nil) def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type, matchFailGenOverride: Option[Tree => Tree], unchecked: Boolean): Option[Tree] = @@ -1408,18 +1408,24 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def matchFailGen = (matchFailGenOverride orElse Some(CODE.MATCHERROR(_: Tree))) patmatDebug("combining cases: "+ (casesNoSubstOnly.map(_.mkString(" >> ")).mkString("{", "\n", "}"))) - val (unchecked, requireSwitch) = - if (settings.XnoPatmatAnalysis.value) (true, false) + val (suppression, requireSwitch): (Suppression, Boolean) = + if (settings.XnoPatmatAnalysis.value) (Suppression.NoSuppresion, false) else scrut match { - case Typed(_, tpt) => - (tpt.tpe hasAnnotation UncheckedClass, - // matches with two or fewer cases need not apply for switchiness (if-then-else will do) - treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0) + case Typed(tree, tpt) => + val suppressExhaustive = tpt.tpe hasAnnotation UncheckedClass + val supressUnreachable = tree match { + case Ident(name) if name startsWith nme.CHECK_IF_REFUTABLE_STRING => true // SI-7183 don't warn for withFilter's that turn out to be irrefutable. + case _ => false + } + val suppression = Suppression(suppressExhaustive, supressUnreachable) + // matches with two or fewer cases need not apply for switchiness (if-then-else will do) + val requireSwitch = treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0 + (suppression, requireSwitch) case _ => - (false, false) + (Suppression.NoSuppresion, false) } - emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, unchecked).getOrElse{ + emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, suppression.exhaustive).getOrElse{ if (requireSwitch) typer.context.unit.warning(scrut.pos, "could not emit switch for @switch annotated match") if (casesNoSubstOnly nonEmpty) { @@ -1436,7 +1442,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL }) None else matchFailGen - val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt, unchecked) + val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt, suppression) val matchRes = codegen.matcher(scrut, scrutSym, pt)(cases map combineExtractors, synthCatchAll) @@ -3831,11 +3837,13 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL with OptimizedCodegen with SymbolicMatchAnalysis with DPLLSolver { self: TreeMakers => - override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) = { - unreachableCase(prevBinder, cases, pt) foreach { caseIndex => - reportUnreachable(cases(caseIndex).last.pos) + override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): (List[List[TreeMaker]], List[Tree]) = { + if (!suppression.unreachable) { + unreachableCase(prevBinder, cases, pt) foreach { caseIndex => + reportUnreachable(cases(caseIndex).last.pos) + } } - if (!unchecked) { + if (!suppression.exhaustive) { val counterExamples = exhaustive(prevBinder, cases, pt) if (counterExamples.nonEmpty) reportMissingCases(prevBinder.pos, counterExamples) @@ -3860,3 +3868,9 @@ object PatternMatchingStats { val patmatAnaExhaust = Statistics.newSubTimer (" of which in exhaustivity", patmatNanos) val patmatAnaReach = Statistics.newSubTimer (" of which in unreachability", patmatNanos) } + +final case class Suppression(exhaustive: Boolean, unreachable: Boolean) + +object Suppression { + val NoSuppresion = Suppression(false, false) +} \ No newline at end of file diff --git a/test/files/pos/t7183.flags b/test/files/pos/t7183.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t7183.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/pos/t7183.scala b/test/files/pos/t7183.scala new file mode 100644 index 0000000000..7647c1634b --- /dev/null +++ b/test/files/pos/t7183.scala @@ -0,0 +1,13 @@ +class A +object A { + def unapply(a: A): Some[A] = Some(a) // Change return type to Option[A] and the warning is gone +} + +object Test { + for (A(a) <- List(new A)) yield a // spurious dead code warning. +} + +// List(new A()).withFilter(((check$ifrefutable$2) => check$ifrefutable$2: @scala.unchecked match { +// case A((a @ _)) => true +// case _ => false // this is dead code, but it's compiler generated. +// })) -- cgit v1.2.3 From 204b2b45a83cf057b6ece7a25ea4f15ec38b4a3f Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 26 Feb 2013 17:11:43 +0100 Subject: SI-7126 Eliminate a source of malformed types. The kind-polymorphic nature of Nothing and Any in concert with type argument inference could lead to types like `T[T]` (where `type T=Any`). Compensatory action is taken later on to recover; see the usages of `TypeRef#typeParamsMatchArgs`. But this these types have a nasty property, they can dealias to themselves. Callers recursing through types who fail to account for this hit an infinite recursion, as was reported in SI-7126. This commit simply dealiases `T` when registering the type bound in `unifySimple`. We should try to weed out additional sources of these types. --- src/reflect/scala/reflect/internal/Types.scala | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index fb493fabd8..7299b439f8 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3183,12 +3183,19 @@ trait Types extends api.Types { self: SymbolTable => * ?TC[?T] <: Any * }}} */ - def unifySimple = ( - (params.isEmpty || tp.typeSymbol == NothingClass || tp.typeSymbol == AnyClass) && { + def unifySimple = { + val sym = tp.typeSymbol + if (sym == NothingClass || sym == AnyClass) { // kind-polymorphic + // SI-7126 if we register some type alias `T=Any`, we can later end + // with malformed types like `T[T]` during type inference in + // `handlePolymorphicCall`. No such problem if we register `Any`. + addBound(sym.tpe) + true + } else if (params.isEmpty) { addBound(tp) true - } - ) + } else false + } /** Full case: involving a check of the form * {{{ -- cgit v1.2.3 From 1117be8418525ce20af847bdcfdbbe66b9cf3d4d Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 27 Feb 2013 16:27:10 +0100 Subject: SI-7190 macros no longer give rise to bridges Amazingly enough, this got through all the testing we performed. But now erasure knows that it shouldn't generate bridges for macro methods. --- .../scala/tools/nsc/transform/Erasure.scala | 1 + test/files/pos/t7190.scala | 26 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 test/files/pos/t7190.scala diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 889d309ba9..cb5268c422 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -477,6 +477,7 @@ abstract class Erasure extends AddInterfaces def checkPair(member: Symbol, other: Symbol) { val otpe = specialErasure(root)(other.tpe) val bridgeNeeded = afterErasure ( + !member.isMacro && !(other.tpe =:= member.tpe) && !(deconstMap(other.tpe) =:= deconstMap(member.tpe)) && { var e = bridgesScope.lookupEntry(member.name) diff --git a/test/files/pos/t7190.scala b/test/files/pos/t7190.scala new file mode 100644 index 0000000000..f7ccded1b4 --- /dev/null +++ b/test/files/pos/t7190.scala @@ -0,0 +1,26 @@ +import scala.language.experimental.macros +import scala.reflect.macros._ + +trait A[T] { + def min[U >: T](implicit ord: Numeric[U]): T = macro A.min[T, U] +} + +object A { + def min[T: c.WeakTypeTag, U >: T: c.WeakTypeTag](c: Context)(ord: c.Expr[Numeric[U]]): c.Expr[T] = { + c.universe.reify { + ord.splice.zero.asInstanceOf[T] + } + } +} + +class B extends A[Int] { + override def min[U >: Int](implicit ord: Numeric[U]): Int = macro B.min[U] +} + +object B { + def min[U >: Int: c.WeakTypeTag](c: Context)(ord: c.Expr[Numeric[U]]): c.Expr[Int] = { + c.universe.reify { + ord.splice.zero.asInstanceOf[Int] + } + } +} \ No newline at end of file -- cgit v1.2.3 From c46bc25d94138befcd36ce1fdaf6c677bc33fae8 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Fri, 1 Mar 2013 00:11:17 +0100 Subject: Tone down a soft-warning to only show under -Ydebug. SI-6191 remains open and can lead to incomplete debug scope information. In 2.10.0, the backend detected when this happend, and warned the user. But there is little the user can do about the warning. We have a few test cases for the problem now, so we should not pollute the compile output. --- src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 0abbe44b02..9b16327ffc 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -2143,8 +2143,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { val start = st.pop() seen ::= LocVarEntry(lv, start, end) case _ => - // TODO SI-6049 - getCurrentCUnit().warning(iPos, "Visited SCOPE_EXIT before visiting corresponding SCOPE_ENTER. SI-6049") + // TODO SI-6049 track down the cause for these. + debugwarn(s"$iPos: Visited SCOPE_EXIT before visiting corresponding SCOPE_ENTER. SI-6191") } } -- cgit v1.2.3 From 0420b2d056f6a69f5d944482ba83d4fbee72cfab Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 1 Mar 2013 09:33:55 -0800 Subject: Revert SI-6240 synchronization for runtime reflection This commit reverts #2083: - 387b2590db runtime reflection: death from thousand threads - 73d079fb38 removes the assertion in missingHook - f4dd56ca5d synchronizes names - dd148de5a8 synchronizes pendingVolatiles - 4cbb9357c5 synchronizes toolboxes - 07bcb6176a SI-7045 reflection now auto-initializes selfType - bebd62d566 optimizes Scala reflection GIL - 735634f1d6 initializes lazy vals and inner objects in advance - 5b37cfb19a introduces GIL to Scala reflection - 981da8edfc cleans up initialization of runtime reflection - b2c2493b22 reflection no longer uses atPhase and friends - a9dca512d8 synchronizes symbols - 0262941b3c removes the crazy extraneous log - 21d5d3820b moves Symbol#SymbolKind to Symbols --- .../scala/tools/reflect/ToolBoxFactory.scala | 52 +- .../scala/reflect/internal/BaseTypeSeqs.scala | 2 +- .../scala/reflect/internal/Definitions.scala | 20 +- src/reflect/scala/reflect/internal/Mirrors.scala | 48 +- src/reflect/scala/reflect/internal/Names.scala | 54 +- src/reflect/scala/reflect/internal/StdNames.scala | 2 - .../scala/reflect/internal/SymbolTable.scala | 5 - src/reflect/scala/reflect/internal/Symbols.scala | 31 +- src/reflect/scala/reflect/internal/Types.scala | 8 +- .../reflect/internal/pickling/UnPickler.scala | 4 +- src/reflect/scala/reflect/runtime/Gil.scala | 25 - .../scala/reflect/runtime/JavaMirrors.scala | 68 +- .../scala/reflect/runtime/JavaUniverse.scala | 1030 +------------------- .../scala/reflect/runtime/SymbolLoaders.scala | 78 +- .../scala/reflect/runtime/SymbolTable.scala | 2 +- .../scala/reflect/runtime/SynchronizedOps.scala | 64 +- .../reflect/runtime/SynchronizedSymbols.scala | 124 +-- .../scala/reflect/runtime/SynchronizedTypes.scala | 48 +- .../scala/reflect/runtime/TwoWayCache.scala | 66 ++ .../scala/reflect/runtime/TwoWayCaches.scala | 68 -- test/files/run/reflection-crazy-logs.check | 1 - test/files/run/reflection-crazy-logs.scala | 5 - test/files/run/reflection-sync-potpourri.check | 1000 ------------------- test/files/run/reflection-sync-potpourri.scala | 31 - test/files/run/reflection-sync-subtypes.check | 1000 ------------------- test/files/run/reflection-sync-subtypes.scala | 20 - test/files/run/t7045.check | 2 - test/files/run/t7045.scala | 12 - 28 files changed, 331 insertions(+), 3539 deletions(-) delete mode 100644 src/reflect/scala/reflect/runtime/Gil.scala create mode 100644 src/reflect/scala/reflect/runtime/TwoWayCache.scala delete mode 100644 src/reflect/scala/reflect/runtime/TwoWayCaches.scala delete mode 100644 test/files/run/reflection-crazy-logs.check delete mode 100644 test/files/run/reflection-crazy-logs.scala delete mode 100644 test/files/run/reflection-sync-potpourri.check delete mode 100644 test/files/run/reflection-sync-potpourri.scala delete mode 100644 test/files/run/reflection-sync-subtypes.check delete mode 100644 test/files/run/reflection-sync-subtypes.scala delete mode 100644 test/files/run/t7045.check delete mode 100644 test/files/run/t7045.scala diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 93fafda463..c05c59d5ff 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -352,19 +352,15 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => lazy val importer = compiler.mkImporter(u) lazy val exporter = importer.reverse - private[this] val toolBoxLock = new Object - - def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = toolBoxLock.synchronized { - compiler.withCleanupCaches { - if (compiler.settings.verbose.value) println("importing "+tree+", expectedType = "+expectedType) - var ctree: compiler.Tree = importer.importTree(tree) - var cexpectedType: compiler.Type = importer.importType(expectedType) - - if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType) - val ttree: compiler.Tree = compiler.typeCheck(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) - val uttree = exporter.importTree(ttree) - uttree - } + def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = compiler.withCleanupCaches { + if (compiler.settings.verbose.value) println("importing "+tree+", expectedType = "+expectedType) + var ctree: compiler.Tree = importer.importTree(tree) + var cexpectedType: compiler.Type = importer.importType(expectedType) + + if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType) + val ttree: compiler.Tree = compiler.typeCheck(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) + val uttree = exporter.importTree(ttree) + uttree } def inferImplicitValue(pt: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree = { @@ -376,28 +372,26 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) } - private def inferImplicit(tree: u.Tree, pt: u.Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: u.Position): u.Tree = toolBoxLock.synchronized { - compiler.withCleanupCaches { - if (compiler.settings.verbose.value) println("importing "+pt, ", tree = "+tree+", pos = "+pos) - var ctree: compiler.Tree = importer.importTree(tree) - var cpt: compiler.Type = importer.importType(pt) - var cpos: compiler.Position = importer.importPosition(pos) - - if (compiler.settings.verbose.value) println("inferring implicit %s of type %s, macros = %s".format(if (isView) "view" else "value", pt, !withMacrosDisabled)) - val itree: compiler.Tree = compiler.inferImplicit(ctree, cpt, isView = isView, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = cpos) - val uitree = exporter.importTree(itree) - uitree - } + private def inferImplicit(tree: u.Tree, pt: u.Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: u.Position): u.Tree = compiler.withCleanupCaches { + if (compiler.settings.verbose.value) println("importing "+pt, ", tree = "+tree+", pos = "+pos) + var ctree: compiler.Tree = importer.importTree(tree) + var cpt: compiler.Type = importer.importType(pt) + var cpos: compiler.Position = importer.importPosition(pos) + + if (compiler.settings.verbose.value) println("inferring implicit %s of type %s, macros = %s".format(if (isView) "view" else "value", pt, !withMacrosDisabled)) + val itree: compiler.Tree = compiler.inferImplicit(ctree, cpt, isView = isView, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = cpos) + val uitree = exporter.importTree(itree) + uitree } - def resetAllAttrs(tree: u.Tree): u.Tree = toolBoxLock.synchronized { + def resetAllAttrs(tree: u.Tree): u.Tree = { val ctree: compiler.Tree = importer.importTree(tree) val ttree: compiler.Tree = compiler.resetAllAttrs(ctree) val uttree = exporter.importTree(ttree) uttree } - def resetLocalAttrs(tree: u.Tree): u.Tree = toolBoxLock.synchronized { + def resetLocalAttrs(tree: u.Tree): u.Tree = { val ctree: compiler.Tree = importer.importTree(tree) val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree) val uttree = exporter.importTree(ttree) @@ -407,14 +401,14 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => def showAttributed(tree: u.Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = compiler.showAttributed(importer.importTree(tree), printTypes, printIds, printKinds) - def parse(code: String): u.Tree = toolBoxLock.synchronized { + def parse(code: String): u.Tree = { if (compiler.settings.verbose.value) println("parsing "+code) val ctree: compiler.Tree = compiler.parse(code) val utree = exporter.importTree(ctree) utree } - def compile(tree: u.Tree): () => Any = toolBoxLock.synchronized { + def compile(tree: u.Tree): () => Any = { if (compiler.settings.verbose.value) println("importing "+tree) var ctree: compiler.Tree = importer.importTree(tree) diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala index 768ebb055b..3c2b128c52 100644 --- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala +++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala @@ -37,7 +37,7 @@ trait BaseTypeSeqs { * This is necessary because when run from reflection every base type sequence needs to have a * SynchronizedBaseTypeSeq as mixin. */ - class BaseTypeSeq protected[reflect] (private[BaseTypeSeqs] val parents: List[Type], private[BaseTypeSeqs] val elems: Array[Type]) { + class BaseTypeSeq protected[BaseTypeSeqs] (private[BaseTypeSeqs] val parents: List[Type], private[BaseTypeSeqs] val elems: Array[Type]) { self => if (Statistics.canEnable) Statistics.incCounter(baseTypeSeqCount) if (Statistics.canEnable) Statistics.incCounter(baseTypeSeqLenTotal, elems.length) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 7a3bdff1f8..6e4ca76382 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1189,7 +1189,7 @@ trait Definitions extends api.StandardDefinitions { /** Is the symbol that of a parent which is added during parsing? */ lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass - lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass + private lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass /** Is symbol a value class? */ def isPrimitiveValueClass(sym: Symbol) = ScalaValueClasses contains sym @@ -1248,24 +1248,8 @@ trait Definitions extends api.StandardDefinitions { def init() { if (isInitialized) return - // forcing ScalaPackageClass first thing during startup is important, because syntheticCoreClasses such as AnyRefClass - // need to be entered into ScalaPackageClass, which entails calling ScalaPackageClass.info.decls.enter - // if ScalaPackageClass isn't initialized by that moment, the following will happen for runtime reflection: - // 1) initialization of ScalaPackageClass will trigger unpickling - // 2) unpickling will need to load some auxiliary types such as, for example, String - // 3) to load String, runtime reflection will call mirrorDefining(classOf[String]) - // 4) this, in turn, will call runtimeMirror(classOf[String].getClassLoader) - // 5) for some classloader configurations, the resulting mirror will be different from rootMirror - // 6) in that case, initialization of the resulting mirror will try to import definitions.syntheticCoreClasses into the mirror - // 7) this will force all the lazy vals corresponding to syntheticCoreClasses - // 8) by that time, the completer of ScalaPackageClass will have already called setInfo on ScalaPackageClass, so there won't be any stack overflow - // so far so good, but there's a subtle detail. if forcing of ScalaPackageClass was called by a syntheticCoreClasses lazy val, - // then this lazy val will be entered twice: once during step 7 and once when returning from the original call - // to avoid this we need to initialize ScalaPackageClass first and only then synthesize the core classes - ScalaPackageClass.initialize // force initialization of every symbol that is synthesized or hijacked by the compiler - val forced1 = symbolsNotPresentInBytecode - val forced2 = NoSymbol + val forced = symbolsNotPresentInBytecode isInitialized = true } //init diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 80c05666af..0beb8e368f 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -239,19 +239,6 @@ trait Mirrors extends api.Mirrors { RootClass.info.decls enter EmptyPackage RootClass.info.decls enter RootPackage - - if (rootOwner != NoSymbol) { - // synthetic core classes are only present in root mirrors - // because Definitions.scala, which initializes and enters them, only affects rootMirror - // therefore we need to enter them manually for non-root mirrors - definitions.syntheticCoreClasses foreach (theirSym => { - val theirOwner = theirSym.owner - assert(theirOwner.isPackageClass, s"theirSym = $theirSym, theirOwner = $theirOwner") - val ourOwner = staticPackage(theirOwner.fullName) - val ourSym = theirSym // just copy the symbol into our branch of the symbol table - ourOwner.info.decls enter ourSym - }) - } } } @@ -275,45 +262,34 @@ trait Mirrors extends api.Mirrors { def mirror = thisMirror.asInstanceOf[Mirror] } - class RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol { + // This is the package _root_. The actual root cannot be referenced at + // the source level, but _root_ is essentially a function => . + final object RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol { this setInfo NullaryMethodType(RootClass.tpe) RootClass.sourceModule = this override def isRootPackage = true } - - // This is the package _root_. The actual root cannot be referenced at - // the source level, but _root_ is essentially a function => . - lazy val RootPackage = new RootPackage - - class RootClass extends PackageClassSymbol(rootOwner, NoPosition, tpnme.ROOT) with RootSymbol { - this setInfo rootLoader - - override def isRoot = true - override def isEffectiveRoot = true - override def isNestedClass = false - } - // This is , the actual root of everything except the package _root_. // and _root_ (RootPackage and RootClass) should be the only "well known" // symbols owned by NoSymbol. All owner chains should go through RootClass, // although it is probable that some symbols are created as direct children // of NoSymbol to ensure they will not be stumbled upon. (We should designate // a better encapsulated place for that.) - lazy val RootClass = new RootClass + final object RootClass extends PackageClassSymbol(rootOwner, NoPosition, tpnme.ROOT) with RootSymbol { + this setInfo rootLoader - class EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { - override def isEmptyPackage = true + override def isRoot = true + override def isEffectiveRoot = true + override def isNestedClass = false } - // The empty package, which holds all top level types without given packages. - lazy val EmptyPackage = new EmptyPackage - - class EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { + final object EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { + override def isEmptyPackage = true + } + final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { override def isEffectiveRoot = true override def isEmptyPackageClass = true } - - lazy val EmptyPackageClass = new EmptyPackageClass } } diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala index 01ad18d3a0..c78ba72dfb 100644 --- a/src/reflect/scala/reflect/internal/Names.scala +++ b/src/reflect/scala/reflect/internal/Names.scala @@ -21,7 +21,7 @@ trait LowPriorityNames { * @author Martin Odersky * @version 1.0, 05/02/2005 */ -trait Names extends api.Names with LowPriorityNames { self => +trait Names extends api.Names with LowPriorityNames { implicit def promoteTermNamesAsNecessary(name: Name): TermName = name.toTermName // Operations ------------------------------------------------------------- @@ -109,26 +109,6 @@ trait Names extends api.Names with LowPriorityNames { self => protected def newTypeName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TypeName = newTermName(cs, offset, len, cachedString).toTypeName - protected def toTypeName(termName: TermName): TypeName = { - val h = hashValue(chrs, termName.index, termName.len) & HASH_MASK - var n = typeHashtable(h) - while ((n ne null) && n.start != termName.index) - n = n.next - - if (n ne null) n - else termName.createCompanionName(h) - } - - protected def toTermName(typeName: TypeName): TermName = { - val h = hashValue(chrs, typeName.index, typeName.len) & HASH_MASK - var n = termHashtable(h) - while ((n ne null) && n.start != typeName.index) - n = n.next - - if (n ne null) n - else typeName.createCompanionName(h) - } - /** Create a term name from string. */ def newTermName(s: String): TermName = newTermName(s.toCharArray(), 0, s.length(), null) @@ -165,7 +145,7 @@ trait Names extends api.Names with LowPriorityNames { self => * or Strings as Names. Give names the key functions the absence of which * make people want Strings all the time. */ - sealed abstract class Name(protected[Names] val index: Int, protected[Names] val len: Int) extends NameApi { + sealed abstract class Name(protected val index: Int, protected val len: Int) extends NameApi { type ThisNameType >: Null <: Name protected[this] def thisName: ThisNameType @@ -483,21 +463,21 @@ trait Names extends api.Names with LowPriorityNames { self => * TermName_R and TypeName_R recreate it each time toString is called. */ private class TermName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TermName(index0, len0, hash) { - @inline final def createCompanionName(h: Int): TypeName = new TypeName_S(index, len, h, toString) + protected def createCompanionName(h: Int): TypeName = new TypeName_S(index, len, h, toString) override def newName(str: String): TermName = newTermNameCached(str) } private class TypeName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TypeName(index0, len0, hash) { - @inline final def createCompanionName(h: Int): TermName = new TermName_S(index, len, h, toString) + protected def createCompanionName(h: Int): TermName = new TermName_S(index, len, h, toString) override def newName(str: String): TypeName = newTypeNameCached(str) } private class TermName_R(index0: Int, len0: Int, hash: Int) extends TermName(index0, len0, hash) { - @inline final def createCompanionName(h: Int): TypeName = new TypeName_R(index, len, h) + protected def createCompanionName(h: Int): TypeName = new TypeName_R(index, len, h) override def toString = new String(chrs, index, len) } private class TypeName_R(index0: Int, len0: Int, hash: Int) extends TypeName(index0, len0, hash) { - @inline final def createCompanionName(h: Int): TermName = new TermName_R(index, len, h) + protected def createCompanionName(h: Int): TermName = new TermName_R(index, len, h) override def toString = new String(chrs, index, len) } @@ -510,14 +490,22 @@ trait Names extends api.Names with LowPriorityNames { self => def isTermName: Boolean = true def isTypeName: Boolean = false def toTermName: TermName = this - def toTypeName: TypeName = self.toTypeName(this) + def toTypeName: TypeName = { + val h = hashValue(chrs, index, len) & HASH_MASK + var n = typeHashtable(h) + while ((n ne null) && n.start != index) + n = n.next + + if (n ne null) n + else createCompanionName(h) + } def newName(str: String): TermName = newTermName(str) def companionName: TypeName = toTypeName def subName(from: Int, to: Int): TermName = newTermName(chrs, start + from, to - from) def nameKind = "term" - def createCompanionName(h: Int): TypeName + protected def createCompanionName(h: Int): TypeName } implicit val TermNameTag = ClassTag[TermName](classOf[TermName]) @@ -530,7 +518,15 @@ trait Names extends api.Names with LowPriorityNames { self => typeHashtable(hash) = this def isTermName: Boolean = false def isTypeName: Boolean = true - def toTermName: TermName = self.toTermName(this) + def toTermName: TermName = { + val h = hashValue(chrs, index, len) & HASH_MASK + var n = termHashtable(h) + while ((n ne null) && n.start != index) + n = n.next + + if (n ne null) n + else createCompanionName(h) + } def toTypeName: TypeName = this def newName(str: String): TypeName = newTypeName(str) def companionName: TermName = toTermName diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 09d1e649d9..bcda2bc1ae 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -265,8 +265,6 @@ trait StdNames { final val SourceFileATTR: NameType = "SourceFile" final val SyntheticATTR: NameType = "Synthetic" - final val scala_ : NameType = "scala" - def dropSingletonName(name: Name): TypeName = (name dropRight SINGLETON_SUFFIX.length).toTypeName def singletonName(name: Name): TypeName = (name append SINGLETON_SUFFIX).toTypeName def implClassName(name: Name): TypeName = (name append IMPL_CLASS_SUFFIX).toTypeName diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index e096bac990..f75855f1ec 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -209,8 +209,6 @@ abstract class SymbolTable extends macros.Universe finally popPhase(saved) } - def slowButSafeAtPhase[T](ph: Phase)(op: => T): T = - if (isCompilerUniverse) atPhase(ph)(op) else op /** Since when it is to be "at" a phase is inherently ambiguous, * a couple unambiguously named methods. @@ -223,9 +221,6 @@ abstract class SymbolTable extends macros.Universe @inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = if (isAtPhaseAfter(target)) atPhase(target)(op) else op - def slowButSafeAtPhaseNotLaterThan[T](target: Phase)(op: => T): T = - if (isCompilerUniverse) atPhaseNotLaterThan(target)(op) else op - final def isValid(period: Period): Boolean = period != 0 && runId(period) == currentRunId && { val pid = phaseId(period) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index df17e3b751..d9eb48ff2d 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -91,14 +91,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => children } - def selfType = { - if (!isCompilerUniverse && needsInitialize(isFlagRelated = false, mask = 0)) initialize - typeOfThis - } - def baseClasses = info.baseClasses def module = sourceModule def thisPrefix: Type = thisType + def selfType: Type = typeOfThis def typeSignature: Type = { fullyInitializeSymbol(this); info } def typeSignatureIn(site: Type): Type = { fullyInitializeSymbol(this); site memberInfo this } @@ -112,8 +108,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def setter: Symbol = setter(owner) } - case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) - /** The class for all symbols */ abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name) extends SymbolContextApiImpl @@ -899,13 +893,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isInitialized: Boolean = validTo != NoPeriod - /** Some completers call sym.setInfo when still in-flight and then proceed with initialization (e.g. see LazyPackageType) - * setInfo sets _validTo to current period, which means that after a call to setInfo isInitialized will start returning true. - * Unfortunately, this doesn't mean that info becomes ready to be used, because subsequent initialization might change the info. - * Therefore we need this method to distinguish between initialized and really initialized symbol states. - */ - final def isFullyInitialized: Boolean = _validTo != NoPeriod && (flags & LOCKED) == 0 - /** Can this symbol be loaded by a reflective mirror? * * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. @@ -2261,6 +2248,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (isTerm && (!isParameter || isParamAccessor)) "val" else "" + private case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) private def symbolKind: SymbolKind = { var kind = if (isTermMacro) ("macro method", "macro method", "MAC") @@ -3019,8 +3007,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def thisType: Type = { val period = thisTypePeriod if (period != currentPeriod) { - if (!isValid(period)) thisTypeCache = ThisType(this) thisTypePeriod = currentPeriod + if (!isValid(period)) thisTypeCache = ThisType(this) } thisTypeCache } @@ -3096,9 +3084,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def typeOfThis = { val period = typeOfThisPeriod if (period != currentPeriod) { + typeOfThisPeriod = currentPeriod if (!isValid(period)) typeOfThisCache = singleType(owner.thisType, sourceModule) - typeOfThisPeriod = currentPeriod } typeOfThisCache } @@ -3109,9 +3097,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => // Skip a package object class, because the members are also in // the package and we wish to avoid spurious ambiguities as in pos/t3999. if (!isPackageObjectClass) { - implicitMembersCacheValue = tp.implicitMembers implicitMembersCacheKey1 = tp implicitMembersCacheKey2 = tp.decls.elems + implicitMembersCacheValue = tp.implicitMembers } } implicitMembersCacheValue @@ -3219,11 +3207,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => def name = nme.NO_NAME override def name_=(n: Name) = abort("Cannot set NoSymbol's name to " + n) - // Syncnote: no need to synchronize this, because NoSymbol's initialization is triggered by JavaUniverse.init - // which is called in universe's constructor - something that's inherently single-threaded - setInfo(NoType) - privateWithin = this - + synchronized { + setInfo(NoType) + privateWithin = this + } override def info_=(info: Type) = { infos = TypeHistory(1, NoType, null) unlock() diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 76d6ec80be..546df8a207 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2066,6 +2066,10 @@ trait Types extends api.Types { self: SymbolTable => def apply(value: Constant) = unique(new UniqueConstantType(value)) } + /* Syncnote: The `volatile` var and `pendingVolatiles` mutable set need not be protected + * with synchronized, because they are accessed only from isVolatile, which is called only from + * Typer. + */ private var volatileRecursions: Int = 0 private val pendingVolatiles = new mutable.HashSet[Symbol] @@ -3926,8 +3930,8 @@ trait Types extends api.Types { self: SymbolTable => /** @PP: Unable to see why these apparently constant types should need vals * in every TypeConstraint, I lifted them out. */ - lazy val numericLoBound = IntClass.tpe - lazy val numericHiBound = intersectionType(List(ByteClass.tpe, CharClass.tpe), ScalaPackageClass) + private lazy val numericLoBound = IntClass.tpe + private lazy val numericHiBound = intersectionType(List(ByteClass.tpe, CharClass.tpe), ScalaPackageClass) /** A class expressing upper and lower bounds constraints of type variables, * as well as their instantiations. diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index 4d61e4178a..603fff4f1c 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -853,7 +853,7 @@ abstract class UnPickler { private val p = phase override def complete(sym: Symbol) : Unit = try { val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType` - slowButSafeAtPhase(p)(sym setInfo tp) + atPhase(p) (sym setInfo tp) if (currentRunId != definedAtRunId) sym.setInfo(adaptToNewRunMap(tp)) } @@ -871,7 +871,7 @@ abstract class UnPickler { super.complete(sym) var alias = at(j, readSymbol) if (alias.isOverloaded) - alias = slowButSafeAtPhase(picklerPhase)((alias suchThat (alt => sym.tpe =:= sym.owner.thisType.memberType(alt)))) + alias = atPhase(picklerPhase)((alias suchThat (alt => sym.tpe =:= sym.owner.thisType.memberType(alt)))) sym.asInstanceOf[TermSymbol].setAlias(alias) } diff --git a/src/reflect/scala/reflect/runtime/Gil.scala b/src/reflect/scala/reflect/runtime/Gil.scala deleted file mode 100644 index cf6f1431d7..0000000000 --- a/src/reflect/scala/reflect/runtime/Gil.scala +++ /dev/null @@ -1,25 +0,0 @@ -package scala.reflect -package runtime - -private[reflect] trait Gil { - self: SymbolTable => - - // fixme... please... - // there are the following avenues of optimization we discussed with Roland: - // 1) replace PackageScope locks with ConcurrentHashMap, because PackageScope materializers seem to be idempotent - // 2) unlock unpickling completers by verifying that they are idempotent or moving non-idempotent parts - // 3) remove the necessity in global state for isSubType - lazy val gil = new java.util.concurrent.locks.ReentrantLock - - @inline final def gilSynchronized[T](body: => T): T = { - if (isCompilerUniverse) body - else { - try { - gil.lock() - body - } finally { - gil.unlock() - } - } - } -} diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 58ade961a7..778c826dc0 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -24,9 +24,9 @@ import scala.language.existentials import scala.runtime.{ScalaRunTime, BoxesRunTime} import scala.reflect.internal.util.Collections._ -private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable => +private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUniverse: SymbolTable => - lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]() + private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]() private def createMirror(owner: Symbol, cl: ClassLoader): Mirror = { val jm = new JavaMirror(owner, cl) @@ -46,11 +46,19 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni trait JavaClassCompleter extends FlagAssigningCompleter - def runtimeMirror(cl: ClassLoader): Mirror = gilSynchronized { - mirrors get cl match { - case Some(WeakReference(m)) => m - case _ => createMirror(rootMirror.RootClass, cl) - } + def init() = { + definitions.AnyValClass // force it. + + // establish root association to avoid cyclic dependency errors later + rootMirror.classToScala(classOf[java.lang.Object]).initialize + + // println("initializing definitions") + definitions.init() + } + + def runtimeMirror(cl: ClassLoader): Mirror = mirrors get cl match { + case Some(WeakReference(m)) => m + case _ => createMirror(rootMirror.RootClass, cl) } /** The API of a mirror for a reflective universe */ @@ -63,23 +71,6 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni import definitions._ - override lazy val RootPackage = new RootPackage with SynchronizedTermSymbol - override lazy val RootClass = new RootClass with SynchronizedModuleClassSymbol - override lazy val EmptyPackage = new EmptyPackage with SynchronizedTermSymbol - override lazy val EmptyPackageClass = new EmptyPackageClass with SynchronizedModuleClassSymbol - - override def init() = { - super.init() - - // see an explanation of this in JavaUniverse.init() - RootPackage - RootClass - EmptyPackage - EmptyPackageClass - unpickler - rootLoader - } - /** The lazy type for root. */ override lazy val rootLoader = new LazyType with FlagAgnosticCompleter { @@ -676,7 +667,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni completeRest() } - def completeRest(): Unit = gilSynchronized { + def completeRest(): Unit = thisUniverse.synchronized { val tparams = clazz.rawInfo.typeParams val parents = try { @@ -892,7 +883,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni * The Scala package with given fully qualified name. Unlike `packageNameToScala`, * this one bypasses the cache. */ - private[JavaMirrors] def makeScalaPackage(fullname: String): ModuleSymbol = gilSynchronized { + private[JavaMirrors] def makeScalaPackage(fullname: String): ModuleSymbol = { val split = fullname lastIndexOf '.' val ownerModule: ModuleSymbol = if (split > 0) packageNameToScala(fullname take split) else this.RootPackage @@ -1255,6 +1246,11 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni case _ => abort(s"${sym}.enclosingRootClass = ${sym.enclosingRootClass}, which is not a RootSymbol") } + private lazy val syntheticCoreClasses: Map[(String, Name), Symbol] = { + def mapEntry(sym: Symbol): ((String, Name), Symbol) = (sym.owner.fullName, sym.name) -> sym + Map() ++ (definitions.syntheticCoreClasses map mapEntry) + } + /** 1. If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package * ., otherwise return NoSymbol. * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead @@ -1264,20 +1260,22 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni override def missingHook(owner: Symbol, name: Name): Symbol = { if (owner.hasPackageFlag) { val mirror = mirrorThatLoaded(owner) + // todo. this makes toolbox tests pass, but it's a mere workaround for SI-5865 +// assert((owner.info decl name) == NoSymbol, s"already exists: $owner . $name") if (owner.isRootSymbol && mirror.tryJavaClass(name.toString).isDefined) return mirror.EmptyPackageClass.info decl name if (name.isTermName && !owner.isEmptyPackageClass) return mirror.makeScalaPackage( if (owner.isRootSymbol) name.toString else owner.fullName+"."+name) - if (name == tpnme.AnyRef && owner.owner.isRoot && owner.name == tpnme.scala_) - // when we synthesize the scala.AnyRef symbol, we need to add it to the scope of the scala package - // the problem is that adding to the scope implies doing something like `owner.info.decls enter anyRef` - // which entails running a completer for the scala package - // which will try to unpickle the stuff in scala/package.class - // which will transitively load scala.AnyRef - // which doesn't exist yet, because it hasn't been added to the scope yet - // this missing hook ties the knot without introducing synchronization problems like before - return definitions.AnyRefClass + syntheticCoreClasses get (owner.fullName, name) match { + case Some(tsym) => + // synthetic core classes are only present in root mirrors + // because Definitions.scala, which initializes and enters them, only affects rootMirror + // therefore we need to enter them manually for non-root mirrors + if (mirror ne thisUniverse.rootMirror) owner.info.decls enter tsym + return tsym + case None => + } } info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) super.missingHook(owner, name) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index cee243fb29..e18435d5b0 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -17,1040 +17,12 @@ class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.S def forInteractive = false def forScaladoc = false - def log(msg: => AnyRef): Unit = if (settings.debug.value) println(" [] "+msg) + def log(msg: => AnyRef): Unit = println(" [] "+msg) type TreeCopier = InternalTreeCopierOps def newStrictTreeCopier: TreeCopier = new StrictTreeCopier def newLazyTreeCopier: TreeCopier = new LazyTreeCopier init() - - def init() { - definitions.init() - - // workaround for http://groups.google.com/group/scala-internals/browse_thread/thread/97840ba4fd37b52e - // constructors are by definition single-threaded, so we initialize all lazy vals (and local object) in advance - // in order to avoid deadlocks later (e.g. one thread holds a global reflection lock and waits for definitions.Something to initialize, - // whereas another thread holds a definitions.Something initialization lock and needs a global reflection lock to complete the initialization) - - // the list of lzycompute methods is mined by a simple python script - // #!/usr/bin/env python - // import os, sys, re, glob, fnmatch - // from subprocess import check_call, check_output - // root = check_output(["git", "rev-parse", "--show-toplevel"]).strip() - // root = os.path.join(root, "build/quick/classes/reflect/scala/reflect") - // classfiles = [] - // for container, dirnames, filenames in os.walk(root): - // for filename in fnmatch.filter(filenames, '*.class'): - // classfiles.append(os.path.join(container, filename)) - // for classfile in classfiles: - // blob = open(classfile).read() - // for found in re.findall(r"[\w\$]+\$lzycompute", blob): - // print found, "in", classfile[len(root) + 1:] - - - // ======== Exprs ======== - // NOFORCE: tree$lzycompute in api/Exprs$ExprImpl.class - // NOFORCE: staticType$lzycompute in api/Exprs$ExprImpl.class - // NOFORCE: value$lzycompute in api/Exprs$ExprImpl.class - // FORCE: Expr$lzycompute in api/Universe.class - // FORCE: FixedMirrorTreeCreator$lzycompute in internal/SymbolTable.class - // probably not used by runtime reflection, but better be safe than sorry - Expr - FixedMirrorTreeCreator - - // ======== Type tags ======== - // FORCE: WeakTypeTag$lzycompute in api/Universe.class - // FORCE: TypeTag$lzycompute in api/Universe.class - // NOFORCE: tpe$lzycompute in api/TypeTags$WeakTypeTagImpl.class - // TODO: validate that scala-reflect never uses TypeTags itself (we have StdTags, but they are in compiler, so it should be okay) - // FORCE: tpe$lzycompute in api/TypeTags$PredefTypeTag.class - // FORCE: FixedMirrorTypeCreator$lzycompute in internal/SymbolTable.class - // probably not used by runtime reflection, but better be safe than sorry - WeakTypeTag - TypeTag - TypeTag.Byte.tpe - TypeTag.Short.tpe - TypeTag.Char.tpe - TypeTag.Int.tpe - TypeTag.Long.tpe - TypeTag.Float.tpe - TypeTag.Double.tpe - TypeTag.Boolean.tpe - TypeTag.Unit.tpe - TypeTag.Any.tpe - TypeTag.AnyVal.tpe - TypeTag.AnyRef.tpe - TypeTag.Object.tpe - TypeTag.Nothing.tpe - TypeTag.Null.tpe - FixedMirrorTypeCreator - - // ======== Annotations ======== - // NOFORCE: isTrivial$lzycompute in internal/AnnotationInfos$AnnotationInfo.class - // looks like isTrivial just calls into Type.isTrivial, which cannot go back to the calling annotationinfo, so we're safe from deadlocks - // NOFORCE: forcedInfo$lzycompute in internal/AnnotationInfos$LazyAnnotationInfo.class - // I can't immediately see that the completer cannot call into one of the methods of the calling AnnotationInfo - // TODO: leaving this as a todo and for now we're at a mercy of chance - // NOFORCE: encodedBytes$lzycompute in internal/AnnotationInfos$ScalaSigBytes.class - // NOFORCE: sevenBitsMayBeZero$lzycompute in internal/AnnotationInfos$ScalaSigBytes.class - // these are just bit/byte twiddling, they don't call into reflection at all - // FORCE: UnmappableAnnotArg$lzycompute in internal/SymbolTable.class - // FORCE: LiteralAnnotArg$lzycompute in internal/SymbolTable.class - // FORCE: ArrayAnnotArg$lzycompute in internal/SymbolTable.class - // FORCE: NestedAnnotArg$lzycompute in internal/SymbolTable.class - // FORCE: ScalaSigBytes$lzycompute in internal/SymbolTable.class - // FORCE: AnnotationInfo$lzycompute in internal/SymbolTable.class - // FORCE: Annotation$lzycompute in internal/SymbolTable.class - // FORCE: UnmappableAnnotation$lzycompute in internal/SymbolTable.class - // FORCE: ThrownException$lzycompute in internal/SymbolTable.class - UnmappableAnnotArg - LiteralAnnotArg - ArrayAnnotArg - NestedAnnotArg - ScalaSigBytes - AnnotationInfo - Annotation - UnmappableAnnotation - ThrownException - - // ======== Importers ======== - // NOFORCE: symMap$lzycompute in internal/Importers$StandardImporter.class - // NOFORCE: tpeMap$lzycompute in internal/Importers$StandardImporter.class - // NOFORCE: fixups$lzycompute in internal/Importers$StandardImporter.class - // NOFORCE: reverse$lzycompute in internal/Importers$StandardImporter.class - // these are simple constructors, which don't call into reflection - // actually the first three of those could be non-lazy - - // ======== Mirrors ======== - // NOFORCE: RootPackage$lzycompute in runtime/JavaMirrors$JavaMirror.class - // NOFORCE: RootClass$lzycompute in runtime/JavaMirrors$JavaMirror.class - // NOFORCE: EmptyPackage$lzycompute in runtime/JavaMirrors$JavaMirror.class - // NOFORCE: EmptyPackageClass$lzycompute in runtime/JavaMirrors$JavaMirror.class - // NOFORCE: RootPackage$lzycompute in internal/Mirrors$Roots.class - // NOFORCE: RootClass$lzycompute in internal/Mirrors$Roots.class - // NOFORCE: EmptyPackage$lzycompute in internal/Mirrors$Roots.class - // NOFORCE: EmptyPackageClass$lzycompute in internal/Mirrors$Roots.class - // NOFORCE: unpickler$lzycompute in runtime/JavaMirrors$JavaMirror.class - // NOFORCE: rootLoader$lzycompute in runtime/JavaMirrors$JavaMirror.class - // these are already forced in JavaMirror.init() - // NOFORCE: universe$lzycompute in runtime/package$.class - // that's the scala.reflect.runtime.universe - // FORCE: 5scala$reflect$runtime$JavaMirrors$$mirrors$lzycompute in runtime/JavaUniverse.class - rootMirror - mirrors - - // ======== Names ======== - // FORCE: tpnme$lzycompute in internal/SymbolTable.class - // FORCE: fulltpnme$lzycompute in internal/SymbolTable.class - // FORCE: binarynme$lzycompute in internal/SymbolTable.class - // FORCE: nme$lzycompute in internal/SymbolTable.class - // FORCE: sn$lzycompute in internal/SymbolTable.class - // FORCE: raw$lzycompute in internal/StdNames$TermNames.class - // FORCE: Ascala$reflect$internal$SymbolTable$$SimpleNameOrdering$lzycompute in internal/SymbolTable.class - // FORCE: 6scala$reflect$internal$StdNames$$compactify$lzycompute in internal/SymbolTable.class - // probably most of these are already initialized by definitions.init() - // but better be safe than sorry - // NOFORCE: GetClassLoader$lzycompute in internal/StdNames$MSILNames.class - // MSIL has been eol'd. probably we shouldn't care anymore - // runtime reflection doesn't support MSIL anyways - tpnme - fulltpnme - binarynme - nme - sn - nme.raw - lowPriorityNameOrdering - nme.flattenedName() - - // ======== Attachments ======== - // FORCE: BackquotedIdentifierAttachment$lzycompute in internal/SymbolTable.class - // FORCE: CompoundTypeTreeOriginalAttachment$lzycompute in internal/SymbolTable.class - // FORCE: MacroExpansionAttachment$lzycompute in internal/SymbolTable.class - // FORCE: SuppressMacroExpansionAttachment$lzycompute in internal/SymbolTable.class - // probably not used by runtime reflection - // but better be safe than sorry - BackquotedIdentifierAttachment - CompoundTypeTreeOriginalAttachment - MacroExpansionAttachment - SuppressMacroExpansionAttachment - - // ======== TreeInfo ======== - // NOFORCE: DynamicUpdate$lzycompute in internal/TreeInfo.class - // NOFORCE: DynamicApplication$lzycompute in internal/TreeInfo.class - // NOFORCE: DynamicApplicationNamed$lzycompute in internal/TreeInfo.class - // NOFORCE: MacroImplReference$lzycompute in internal/TreeInfo.class - // NOFORCE: StripCast$lzycompute in internal/TreeInfo.class - // NOFORCE: Applied$lzycompute in internal/TreeInfo.class - // NOFORCE: IsTrue$lzycompute in internal/TreeInfo.class - // NOFORCE: IsFalse$lzycompute in internal/TreeInfo.class - // NOFORCE: IsIf$lzycompute in internal/TreeInfo.class - // TreeInfo is never instantiated by runtime reflection - - // ======== Miscellaneous ======== - // FORCE: BooleanFlag$lzycompute in api/Universe.class - // FORCE: traceSymbols$lzycompute in internal/SymbolTable.class - // FORCE: perRunCaches$lzycompute in internal/SymbolTable.class - // FORCE: typeDebug$lzycompute in internal/SymbolTable.class - // FORCE: str$lzycompute in internal/TypeDebugging$typeDebug$.class - // FORCE: ConsoleWriter$lzycompute in internal/SymbolTable.class - // FORCE: settings$lzycompute in runtime/JavaUniverse.class - // NOFORCE: Lscala$reflect$internal$util$TraceSymbolActivity$$findErasurePhase$lzycompute in internal/SymbolTable$traceSymbols$.class - // NOFORCE: lineIndices$lzycompute in internal/util/BatchSourceFile.class - // NOFORCE: extension$lzycompute in io/AbstractFile.class - // NOFORCE: in_s$lzycompute in io/File.class - // NOFORCE: out_s$lzycompute in io/File.class - // NOFORCE: in$lzycompute in io/File.class - // NOFORCE: out$lzycompute in io/File.class - // NOFORCE: in$lzycompute in io/Streamable$Bytes$class.class - // noforced guys don't call into reflection, so even when not initialized they don't pose a deadlock threat - // FORCE: Scope$lzycompute in internal/SymbolTable.class - // FORCE: EmptyScope$lzycompute in internal/SymbolTable.class - // FORCE: Flag$lzycompute in internal/SymbolTable.class - // FORCE: KindErrors$lzycompute in internal/SymbolTable.class - BooleanFlag - traceSymbols - perRunCaches - typeDebug - typeDebug.str - ConsoleWriter - settings - Scope - EmptyScope - Flag - KindErrors - - // ======== Transforms ======== - // NOFORCE: ObjectArray$lzycompute in internal/transform/Erasure$ErasureMap.class - // NOFORCE: ErasedObject$lzycompute in internal/transform/Erasure$ErasureMap.class - // too much hassle to force those, and they cannot be called back from reflection => safe from deadlocks - // FORCE: GenericArray$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class - // FORCE: scalaErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class - // FORCE: specialScalaErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class - // FORCE: javaErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class - // FORCE: verifiedJavaErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class - // FORCE: boxingErasure$lzycompute in internal/transform/Transforms$$anonfun$3$$anon$1.class - refChecks - uncurry - erasure - erasure.GenericArray - erasure.scalaErasure - erasure.specialScalaErasure - erasure.javaErasure - erasure.verifiedJavaErasure - erasure.boxingErasure - - // ======== Symbols ======== - // FORCE: NoSymbol$lzycompute in internal/SymbolTable.class - // FORCE: 6scala$reflect$internal$Symbols$$TypeHistory$lzycompute in internal/SymbolTable.class - // FORCE: SymbolKind$lzycompute in internal/Symbols$Symbol.class - NoSymbol - definitions.AnyRefClass.info - SymbolKind - - // ======== Trees ======== - // FORCE: PackageDef$lzycompute in internal/SymbolTable.class - // FORCE: ClassDef$lzycompute in internal/SymbolTable.class - // FORCE: ModuleDef$lzycompute in internal/SymbolTable.class - // FORCE: ValDef$lzycompute in internal/SymbolTable.class - // FORCE: DefDef$lzycompute in internal/SymbolTable.class - // FORCE: TypeDef$lzycompute in internal/SymbolTable.class - // FORCE: LabelDef$lzycompute in internal/SymbolTable.class - // FORCE: ImportSelector$lzycompute in internal/SymbolTable.class - // FORCE: Import$lzycompute in internal/SymbolTable.class - // FORCE: Template$lzycompute in internal/SymbolTable.class - // FORCE: Block$lzycompute in internal/SymbolTable.class - // FORCE: CaseDef$lzycompute in internal/SymbolTable.class - // FORCE: Alternative$lzycompute in internal/SymbolTable.class - // FORCE: Star$lzycompute in internal/SymbolTable.class - // FORCE: Bind$lzycompute in internal/SymbolTable.class - // FORCE: UnApply$lzycompute in internal/SymbolTable.class - // FORCE: ArrayValue$lzycompute in internal/SymbolTable.class - // FORCE: Function$lzycompute in internal/SymbolTable.class - // FORCE: Assign$lzycompute in internal/SymbolTable.class - // FORCE: AssignOrNamedArg$lzycompute in internal/SymbolTable.class - // FORCE: If$lzycompute in internal/SymbolTable.class - // FORCE: Match$lzycompute in internal/SymbolTable.class - // FORCE: Return$lzycompute in internal/SymbolTable.class - // FORCE: Try$lzycompute in internal/SymbolTable.class - // FORCE: Throw$lzycompute in internal/SymbolTable.class - // FORCE: New$lzycompute in internal/SymbolTable.class - // FORCE: Typed$lzycompute in internal/SymbolTable.class - // FORCE: TypeApply$lzycompute in internal/SymbolTable.class - // FORCE: Apply$lzycompute in internal/SymbolTable.class - // FORCE: ApplyDynamic$lzycompute in internal/SymbolTable.class - // FORCE: Super$lzycompute in internal/SymbolTable.class - // FORCE: This$lzycompute in internal/SymbolTable.class - // FORCE: Select$lzycompute in internal/SymbolTable.class - // FORCE: Ident$lzycompute in internal/SymbolTable.class - // FORCE: ReferenceToBoxed$lzycompute in internal/SymbolTable.class - // FORCE: Literal$lzycompute in internal/SymbolTable.class - // FORCE: Annotated$lzycompute in internal/SymbolTable.class - // FORCE: SingletonTypeTree$lzycompute in internal/SymbolTable.class - // FORCE: SelectFromTypeTree$lzycompute in internal/SymbolTable.class - // FORCE: CompoundTypeTree$lzycompute in internal/SymbolTable.class - // FORCE: AppliedTypeTree$lzycompute in internal/SymbolTable.class - // FORCE: TypeBoundsTree$lzycompute in internal/SymbolTable.class - // FORCE: ExistentialTypeTree$lzycompute in internal/SymbolTable.class - // FORCE: TypeTree$lzycompute in internal/SymbolTable.class - // FORCE: Modifiers$lzycompute in internal/SymbolTable.class - // FORCE: Constant$lzycompute in internal/SymbolTable.class - // FORCE: treeBuild$lzycompute in internal/SymbolTable.class - // FORCE: posAssigner$lzycompute in internal/SymbolTable.class - // FORCE: NoMods$lzycompute in api/Universe.class - // FORCE: EmptyTree$lzycompute in internal/SymbolTable.class - // FORCE: emptyValDef$lzycompute in internal/SymbolTable.class - // FORCE: EmptyTreeTypeSubstituter$lzycompute in internal/SymbolTable.class - // FORCE: 3scala$reflect$internal$Trees$$duplicator$lzycompute in internal/SymbolTable.class - PackageDef - ClassDef - ModuleDef - ValDef - DefDef - TypeDef - LabelDef - ImportSelector - Import - Template - Block - CaseDef - Alternative - Star - Bind - UnApply - ArrayValue - Function - Assign - AssignOrNamedArg - If - Match - Return - Try - Throw - New - Typed - TypeApply - Apply - ApplyDynamic - Super - This - Select - Ident - ReferenceToBoxed - Literal - Annotated - SingletonTypeTree - SelectFromTypeTree - CompoundTypeTree - AppliedTypeTree - TypeBoundsTree - ExistentialTypeTree - TypeTree - Modifiers - Constant - treeBuild - posAssigner - NoMods - EmptyTree - emptyValDef - EmptyTreeTypeSubstituter - Literal(Constant(42)).duplicate - - // ======== Types ======== - // FORCE: undoLog$lzycompute in internal/SymbolTable.class - // FORCE: UnmappableTree$lzycompute in internal/SymbolTable.class - // FORCE: NotNullType$lzycompute in internal/SymbolTable.class - // FORCE: ErrorType$lzycompute in internal/SymbolTable.class - // FORCE: WildcardType$lzycompute in internal/SymbolTable.class - // FORCE: BoundedWildcardType$lzycompute in internal/SymbolTable.class - // FORCE: NoType$lzycompute in internal/SymbolTable.class - // FORCE: NoPrefix$lzycompute in internal/SymbolTable.class - // FORCE: ThisType$lzycompute in internal/SymbolTable.class - // FORCE: SingleType$lzycompute in internal/SymbolTable.class - // FORCE: SuperType$lzycompute in internal/SymbolTable.class - // FORCE: TypeBounds$lzycompute in internal/SymbolTable.class - // NOFORCE: annotationArgRewriter$1$lzycompute in internal/Types$AsSeenFromMap.class - // local object => not a problem - // FORCE: RefinedType$lzycompute in internal/SymbolTable.class - // FORCE: ClassInfoType$lzycompute in internal/SymbolTable.class - // FORCE: ConstantType$lzycompute in internal/SymbolTable.class - // FORCE: TypeRef$lzycompute in internal/SymbolTable.class - // FORCE: MethodType$lzycompute in internal/SymbolTable.class - // FORCE: NullaryMethodType$lzycompute in internal/SymbolTable.class - // FORCE: PolyType$lzycompute in internal/SymbolTable.class - // FORCE: ExistentialType$lzycompute in internal/SymbolTable.class - // FORCE: OverloadedType$lzycompute in internal/SymbolTable.class - // FORCE: AntiPolyType$lzycompute in internal/SymbolTable.class - // FORCE: HasTypeMember$lzycompute in internal/SymbolTable.class - // FORCE: HasTypeParams$lzycompute in internal/SymbolTable.class - // FORCE: TypeVar$lzycompute in internal/SymbolTable.class - // FORCE: AnnotatedType$lzycompute in internal/SymbolTable.class - // FORCE: NamedType$lzycompute in internal/SymbolTable.class - // FORCE: DeBruijnIndex$lzycompute in internal/SymbolTable.class - // FORCE: DeBruijnBinder$lzycompute in internal/SymbolTable.class - // FORCE: ErasedValueType$lzycompute in internal/SymbolTable.class - // FORCE: GenPolyType$lzycompute in internal/SymbolTable.class - // FORCE: normalizeAliases$lzycompute in internal/SymbolTable.class - // FORCE: dropSingletonType$lzycompute in internal/SymbolTable.class - // FORCE: dropAllRefinements$lzycompute in internal/SymbolTable.class - // FORCE: dropRepeatedParamType$lzycompute in internal/SymbolTable.class - // FORCE: toDeBruijn$lzycompute in internal/SymbolTable.class - // FORCE: numericLoBound$lzycompute in internal/SymbolTable.class - // FORCE: numericHiBound$lzycompute in internal/SymbolTable.class - // FORCE: TypeConstraint$lzycompute in internal/SymbolTable.class - // FORCE: unwrapToClass$lzycompute in internal/SymbolTable.class - // FORCE: unwrapToStableClass$lzycompute in internal/SymbolTable.class - // FORCE: unwrapWrapperTypes$lzycompute in internal/SymbolTable.class - // FORCE: IsDependentCollector$lzycompute in internal/SymbolTable.class - // FORCE: ApproximateDependentMap$lzycompute in internal/SymbolTable.class - // FORCE: StripAnnotationsMap$lzycompute in internal/SymbolTable.class - // FORCE: wildcardToTypeVarMap$lzycompute in internal/SymbolTable.class - // FORCE: typeVarToOriginMap$lzycompute in internal/SymbolTable.class - // FORCE: ErroneousCollector$lzycompute in internal/SymbolTable.class - // NOFORCE: scala$reflect$internal$Types$$commonOwnerMapObj$lzycompute in internal/SymbolTable.class - // not used in runtime reflection, overridden to provide thread-safety - // FORCE: RecoverableCyclicReference$lzycompute in internal/SymbolTable.class - // FORCE: CyclicReference$lzycompute in internal/SymbolTable.class - // NOFORCE: scala$reflect$internal$Types$ClassInfoType$$enterRefs$lzycompute in internal/Types$ClassInfoType.class - // not used in runtime reflection, only called by typer - // NOFORCE: Jscala$reflect$internal$Types$InstantiateDependentMap$$StableArg$lzycompute in internal/Types$InstantiateDependentMap.class - // NOFORCE: Dscala$reflect$internal$Types$InstantiateDependentMap$$Arg$lzycompute in internal/Types$InstantiateDependentMap.class - // don't call into reflection - // NOFORCE: trans$1$lzycompute in internal/Types$SubstSymMap.class - // NOFORCE: trans$2$lzycompute in internal/Types$SubstTypeMap.class - // NOFORCE: treeTrans$1$lzycompute in internal/Types$InstantiateDependentMap.class - // local objects => we're fine - // FORCE: adaptToNewRunMap$lzycompute in internal/SymbolTable.class - // NOFORCE?! maxDepth$lzycompute in internal/BaseTypeSeqs$BaseTypeSeq.class - // NOFORCE?! maxDepth$lzycompute in runtime/SynchronizedOps$$anon$4.class - // NOFORCE?! maxDepth$lzycompute in runtime/SynchronizedOps$SynchronizedBaseTypeSeq$$anon$3.class - // it's totally not obvious whether typeDepth, which is called by maxDepth, - // can or cannot indirectly call into one of the methods of the calling BaseTypeSeq - // TODO: leaving this for further investigation risking to get a deadlock for now - undoLog - UnmappableTree - NotNullType - ErrorType - WildcardType - BoundedWildcardType - NoType - NoPrefix - ThisType - SingleType - SuperType - TypeBounds - RefinedType - ClassInfoType - ConstantType - TypeRef - MethodType - NullaryMethodType - PolyType - ExistentialType - OverloadedType - AntiPolyType - HasTypeMember - HasTypeParams - TypeVar - AnnotatedType - NamedType - DeBruijnIndex - DeBruijnBinder - ErasedValueType - GenPolyType - normalizeAliases - dropSingletonType - dropAllRefinements - dropRepeatedParamType - toDeBruijn - numericLoBound - numericHiBound - TypeConstraint - unwrapToClass - unwrapToStableClass - unwrapWrapperTypes - IsDependentCollector - ApproximateDependentMap - StripAnnotationsMap - wildcardToTypeVarMap - typeVarToOriginMap - ErroneousCollector - RecoverableCyclicReference - CyclicReference - adaptToNewRunMap - - // ======== JavaMirrors ======== - // NOFORCE: assocs$lzycompute in runtime/JavaMirrors$JavaMirror$JavaAnnotationProxy.class - // NOFORCE: jconstr$lzycompute in runtime/JavaMirrors$JavaMirror$JavaConstructorMirror.class - // NOFORCE: jfield$lzycompute in runtime/JavaMirrors$JavaMirror$JavaFieldMirror.class - // NOFORCE: jmeth$lzycompute in runtime/JavaMirrors$JavaMirror$JavaMethodMirror.class - // NOFORCE: signature$lzycompute in runtime/JavaMirrors$JavaMirror$JavaTemplateMirror.class - // NOFORCE: PrimitiveClass$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class - // NOFORCE: EnumClass$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class - // NOFORCE: ArrayClass$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class - // NOFORCE: AnnotationClass$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class - // NOFORCE: ConstantArg$lzycompute in runtime/JavaMirrors$JavaMirror$toAnnotArg$.class - // NOFORCE: Cscala$reflect$runtime$JavaMirrors$JavaMirror$$toAnnotArg$lzycompute in runtime/JavaMirrors$JavaMirror.class - // NOFORCE: Lscala$reflect$runtime$JavaMirrors$JavaMirror$$JavaAnnotationProxy$lzycompute in runtime/JavaMirrors$JavaMirror.class - // NOFORCE: Bscala$reflect$runtime$TwoWayCaches$TwoWayCache$$SomeRef$lzycompute in runtime/TwoWayCaches$TwoWayCache.class - // NOFORCE: bytecodelessMethodOwners$lzycompute in runtime/JavaMirrors$JavaMirror.class - // NOFORCE: bytecodefulObjectMethods$lzycompute in runtime/JavaMirrors$JavaMirror.class - // functionality from JavaMirrors cannot be called from reflect.internal, so there's no danger of deadlock - - // ======== Locks ======== - // locks in runtime reflection look like `lazy val XXXlock = new Object` - // since initializers don't call into reflection, there's no problem in not forcing those lazy vals here - - // ======== Definitions ======== - // FORCE: definitions$lzycompute in internal/SymbolTable.class - // FORCE: JavaLangPackage$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: JavaLangPackageClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaPackage$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaPackageClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RuntimePackage$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RuntimePackageClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: JavaLangEnumClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: anyparam$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: anyvalparam$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: anyrefparam$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnyClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnyRefClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ObjectClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnyTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnyRefTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ObjectTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnyRefModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnyValClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnyValTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RuntimeNothingClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RuntimeNullClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NothingClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NullClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NothingTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NullTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ClassCastExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: IndexOutOfBoundsExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: InvocationTargetExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MatchErrorClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NonLocalReturnControlClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: $NullPointerExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ThrowableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: UninitializedErrorClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: PartialFunctionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AbstractPartialFunctionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SymbolClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: StringClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: StringModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ClassClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: DynamicClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SysPackage$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: UnqualifiedModules$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: UnqualifiedOwners$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: PredefModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: PredefModuleClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SpecializableModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: GroupOfSpecializable$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ConsoleModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaRunTimeModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SymbolModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Symbol_apply$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: StringAddClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ArrowAssocClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: StringAdd_$plus$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NotNullClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaNumberClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TraitSetterAnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: DelayedInitClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TypeConstraintClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SingletonClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SerializableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: JavaSerializableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ComparableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: CloneableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: JavaCloneableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: JavaNumberClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RemoteInterfaceClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RemoteExceptionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ByNameParamClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: EqualsPatternClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: JavaRepeatedParamClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RepeatedParamClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MatchingStrategyClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ConsClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: IterableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: IteratorClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ListClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SeqClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: StringBuilderClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TraversableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ListModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: List_apply$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NilModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SeqModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: IteratorModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Iterator_apply$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ArrayModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ArrayModule_overloadedApply$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ArrayClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Array_apply$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Array_update$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Array_length$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Array_clone$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SoftReferenceClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: WeakReferenceClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MethodClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: EmptyMethodCacheClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MethodCacheClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ReflectPackage$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ReflectApiPackage$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ReflectRuntimePackage$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: PartialManifestClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: PartialManifestModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: FullManifestClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: FullManifestModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: OptManifestClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NoManifest$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ExprsClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ExprClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ExprModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ClassTagModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ClassTagClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TypeTagsClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: WeakTypeTagClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: WeakTypeTagModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TypeTagClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TypeTagModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ApiUniverseClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: JavaUniverseClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MirrorClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TypeCreatorClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TreeCreatorClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MacroContextClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MacroImplAnnotation$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: StringContextClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaSignatureAnnotation$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaLongSignatureAnnotation$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: OptionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: OptionModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Option_apply$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SomeClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NoneModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SomeModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ProductClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TupleClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: FunctionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AbstractFunctionClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ProductRootClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ObjectArray$lzycompute in internal/Definitions$DefinitionsClass.class - // NOFORCE: ComparatorClass$lzycompute in internal/Definitions$DefinitionsClass.class - // NOFORCE: ValueTypeClass$lzycompute in internal/Definitions$DefinitionsClass.class - // NOFORCE: DelegateClass$lzycompute in internal/Definitions$DefinitionsClass.class - // NOFORCE: Delegate_scalaCallerTargets$lzycompute in internal/Definitions$DefinitionsClass.class - // MSIL has been eol'd. probably we shouldn't care anymore - // runtime reflection doesn't support MSIL anyways - // FORCE: Any_$eq$eq$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Any_$bang$eq$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Any_equals$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Any_hashCode$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Any_toString$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Any_$hash$hash$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Any_getClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Any_isInstanceOf$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Any_asInstanceOf$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Object_$hash$hash$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Object_$eq$eq$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Object_$bang$eq$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Object_eq$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Object_ne$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Object_isInstanceOf$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Object_asInstanceOf$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Object_synchronized$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: String_$plus$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ObjectRefClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: VolatileObjectRefClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RuntimeStaticsModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxesRunTimeModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxesRunTimeClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedNumberClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedCharacterClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedBooleanClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedByteClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedShortClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedIntClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedLongClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedFloatClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedDoubleClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Boxes_isNumberOrBool$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Boxes_isNumber$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedUnitClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BoxedUnitModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ClassfileAnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: StaticAnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BridgeClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ElidableMethodClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ImplicitNotFoundClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MigrationAnnotationClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaStrictFPAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SerializableAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SwitchClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TailrecClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: VarargsClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: uncheckedStableClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: uncheckedVarianceClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BeanPropertyAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BooleanBeanPropertyAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: CloneableAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: CompileTimeOnlyAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: DeprecatedAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: DeprecatedNameAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: $DeprecatedInheritanceAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: DeprecatedOverridingAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: NativeAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: RemoteAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaInlineClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaNoInlineClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SerialVersionUIDAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SpecializedClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ThrowsClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: TransientAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: UncheckedClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: UnspecializedClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: VolatileAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BeanGetterTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BeanSetterTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: FieldTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: GetterTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ParamTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: SetterTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ClassTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ObjectTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MethodTargetClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: LanguageFeatureAnnot$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: languageFeatureModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: experimentalModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: MacrosFeature$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: DynamicsFeature$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: PostfixOpsFeature$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ReflectiveCallsFeature$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ImplicitConversionsFeature$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: HigherKindsFeature$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ExistentialsFeature$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: metaAnnotations$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: AnnotationDefaultAttr$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: boxedClassValues$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: isUnbox$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: isBox$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: isPhantomClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: syntheticCoreClasses$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: syntheticCoreMethods$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: hijackedCoreClasses$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: symbolsNotPresentInBytecode$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: $isPossibleSyntheticParent$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: boxedValueClassesSet$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: abbrvTag$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: numericWeight$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: boxedModule$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: boxedClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: refClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: volatileRefClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: boxMethod$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: unboxMethod$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: UnitClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ByteClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ShortClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: CharClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: IntClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: LongClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: FloatClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: DoubleClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BooleanClass$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Boolean_and$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Boolean_or$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: Boolean_not$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: UnitTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ByteTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ShortTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: CharTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: IntTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: LongTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: FloatTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: DoubleTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: BooleanTpe$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaNumericValueClasses$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaValueClassesNoUnit$lzycompute in internal/Definitions$DefinitionsClass.class - // FORCE: ScalaValueClasses$lzycompute in internal/Definitions$DefinitionsClass.class - definitions.JavaLangPackage - definitions.JavaLangPackageClass - definitions.ScalaPackage - definitions.ScalaPackageClass - definitions.RuntimePackage - definitions.RuntimePackageClass - definitions.JavaLangEnumClass - definitions.anyparam - definitions.anyvalparam - definitions.anyrefparam - definitions.AnyClass - definitions.AnyRefClass - definitions.ObjectClass - definitions.AnyTpe - definitions.AnyRefTpe - definitions.ObjectTpe - // FIXME: definitions.AnyRefModule - definitions.AnyValClass - definitions.AnyValTpe - definitions.RuntimeNothingClass - definitions.RuntimeNullClass - definitions.NothingClass - definitions.NullClass - definitions.NothingTpe - definitions.NullTpe - definitions.ClassCastExceptionClass - definitions.IndexOutOfBoundsExceptionClass - definitions.InvocationTargetExceptionClass - definitions.MatchErrorClass - definitions.NonLocalReturnControlClass - definitions.NullPointerExceptionClass - definitions.ThrowableClass - definitions.UninitializedErrorClass - definitions.PartialFunctionClass - definitions.AbstractPartialFunctionClass - definitions.SymbolClass - definitions.StringClass - definitions.StringModule - definitions.ClassClass - definitions.DynamicClass - definitions.SysPackage - definitions.UnqualifiedModules - definitions.UnqualifiedOwners - definitions.PredefModule - definitions.PredefModuleClass - definitions.SpecializableModule - definitions.GroupOfSpecializable - definitions.ConsoleModule - definitions.ScalaRunTimeModule - definitions.SymbolModule - definitions.Symbol_apply - definitions.StringAddClass - definitions.ArrowAssocClass - definitions.StringAdd_$plus - definitions.NotNullClass - definitions.ScalaNumberClass - definitions.TraitSetterAnnotationClass - definitions.DelayedInitClass - definitions.TypeConstraintClass - definitions.SingletonClass - definitions.SerializableClass - definitions.JavaSerializableClass - definitions.ComparableClass - definitions.CloneableClass - definitions.JavaCloneableClass - definitions.JavaNumberClass - definitions.RemoteInterfaceClass - definitions.RemoteExceptionClass - definitions.ByNameParamClass - definitions.EqualsPatternClass - definitions.JavaRepeatedParamClass - definitions.RepeatedParamClass - // FIXME: definitions.MatchingStrategyClass - definitions.ConsClass - definitions.IterableClass - definitions.IteratorClass - definitions.ListClass - definitions.SeqClass - definitions.StringBuilderClass - definitions.TraversableClass - definitions.ListModule - definitions.List_apply - definitions.NilModule - definitions.SeqModule - definitions.IteratorModule - definitions.Iterator_apply - definitions.ArrayModule - definitions.ArrayModule_overloadedApply - definitions.ArrayClass - definitions.Array_apply - definitions.Array_update - definitions.Array_length - definitions.Array_clone - definitions.SoftReferenceClass - definitions.WeakReferenceClass - definitions.MethodClass - definitions.EmptyMethodCacheClass - definitions.MethodCacheClass - definitions.ReflectPackage - definitions.ReflectApiPackage - definitions.ReflectRuntimePackage - definitions.PartialManifestClass - definitions.PartialManifestModule - definitions.FullManifestClass - definitions.FullManifestModule - definitions.OptManifestClass - definitions.NoManifest - definitions.ExprsClass - definitions.ExprClass - definitions.ExprModule - definitions.ClassTagModule - definitions.ClassTagClass - definitions.TypeTagsClass - definitions.WeakTypeTagClass - definitions.WeakTypeTagModule - definitions.TypeTagClass - definitions.TypeTagModule - definitions.ApiUniverseClass - definitions.JavaUniverseClass - definitions.MirrorClass - definitions.TypeCreatorClass - definitions.TreeCreatorClass - definitions.MacroContextClass - definitions.MacroImplAnnotation - definitions.StringContextClass - definitions.ScalaSignatureAnnotation - definitions.ScalaLongSignatureAnnotation - definitions.OptionClass - definitions.OptionModule - definitions.Option_apply - definitions.SomeClass - definitions.NoneModule - definitions.SomeModule - definitions.ProductClass - definitions.TupleClass - definitions.FunctionClass - definitions.AbstractFunctionClass - definitions.ProductRootClass - definitions.ObjectArray - definitions.Any_$eq$eq - definitions.Any_$bang$eq - definitions.Any_equals - definitions.Any_hashCode - definitions.Any_toString - definitions.Any_$hash$hash - definitions.Any_getClass - definitions.Any_isInstanceOf - definitions.Any_asInstanceOf - definitions.Object_$hash$hash - definitions.Object_$eq$eq - definitions.Object_$bang$eq - definitions.Object_eq - definitions.Object_ne - definitions.Object_isInstanceOf - definitions.Object_asInstanceOf - definitions.Object_synchronized - definitions.String_$plus - definitions.ObjectRefClass - definitions.VolatileObjectRefClass - definitions.RuntimeStaticsModule - definitions.BoxesRunTimeModule - definitions.BoxesRunTimeClass - definitions.BoxedNumberClass - definitions.BoxedCharacterClass - definitions.BoxedBooleanClass - definitions.BoxedByteClass - definitions.BoxedShortClass - definitions.BoxedIntClass - definitions.BoxedLongClass - definitions.BoxedFloatClass - definitions.BoxedDoubleClass - definitions.Boxes_isNumberOrBool - definitions.Boxes_isNumber - definitions.BoxedUnitClass - definitions.BoxedUnitModule - definitions.AnnotationClass - definitions.ClassfileAnnotationClass - definitions.StaticAnnotationClass - definitions.BridgeClass - definitions.ElidableMethodClass - definitions.ImplicitNotFoundClass - definitions.MigrationAnnotationClass - definitions.ScalaStrictFPAttr - definitions.SerializableAttr - definitions.SwitchClass - definitions.TailrecClass - definitions.VarargsClass - definitions.uncheckedStableClass - definitions.uncheckedVarianceClass - definitions.BeanPropertyAttr - definitions.BooleanBeanPropertyAttr - definitions.CloneableAttr - definitions.CompileTimeOnlyAttr - definitions.DeprecatedAttr - definitions.DeprecatedNameAttr - definitions.DeprecatedInheritanceAttr - definitions.DeprecatedOverridingAttr - definitions.NativeAttr - definitions.RemoteAttr - definitions.ScalaInlineClass - definitions.ScalaNoInlineClass - definitions.SerialVersionUIDAttr - definitions.SpecializedClass - definitions.ThrowsClass - definitions.TransientAttr - definitions.UncheckedClass - definitions.UnspecializedClass - definitions.VolatileAttr - definitions.BeanGetterTargetClass - definitions.BeanSetterTargetClass - definitions.FieldTargetClass - definitions.GetterTargetClass - definitions.ParamTargetClass - definitions.SetterTargetClass - definitions.ClassTargetClass - definitions.ObjectTargetClass - definitions.MethodTargetClass - definitions.LanguageFeatureAnnot - definitions.languageFeatureModule - definitions.experimentalModule - definitions.MacrosFeature - definitions.DynamicsFeature - definitions.PostfixOpsFeature - definitions.ReflectiveCallsFeature - definitions.ImplicitConversionsFeature - definitions.HigherKindsFeature - definitions.ExistentialsFeature - definitions.metaAnnotations - definitions.AnnotationDefaultAttr - definitions.boxedClassValues - definitions.isUnbox - definitions.isBox - definitions.isPhantomClass - definitions.syntheticCoreClasses - definitions.syntheticCoreMethods - definitions.hijackedCoreClasses - definitions.symbolsNotPresentInBytecode - definitions.isPossibleSyntheticParent - definitions.boxedValueClassesSet - definitions.abbrvTag - definitions.numericWeight - definitions.boxedModule - definitions.boxedClass - definitions.refClass - definitions.volatileRefClass - definitions.boxMethod - definitions.unboxMethod - definitions.UnitClass - definitions.ByteClass - definitions.ShortClass - definitions.CharClass - definitions.IntClass - definitions.LongClass - definitions.FloatClass - definitions.DoubleClass - definitions.BooleanClass - definitions.Boolean_and - definitions.Boolean_or - definitions.Boolean_not - definitions.UnitTpe - definitions.ByteTpe - definitions.ShortTpe - definitions.CharTpe - definitions.IntTpe - definitions.LongTpe - definitions.FloatTpe - definitions.DoubleTpe - definitions.BooleanTpe - definitions.ScalaNumericValueClasses - definitions.ScalaValueClassesNoUnit - definitions.ScalaValueClasses - } } diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index bd5be44b35..311db64b91 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -15,13 +15,37 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => * is found, a package is created instead. */ class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader with FlagAssigningCompleter { +// def makePackage() { +// println("wrong guess; making package "+clazz) +// val ptpe = newPackageType(module.moduleClass) +// for (sym <- List(clazz, module, module.moduleClass)) { +// sym setFlag Flags.PACKAGE +// sym setInfo ptpe +// } +// } + override def complete(sym: Symbol) = { debugInfo("completing "+sym+"/"+clazz.fullName) assert(sym == clazz || sym == module || sym == module.moduleClass) - slowButSafeAtPhaseNotLaterThan(picklerPhase) { +// try { + atPhaseNotLaterThan(picklerPhase) { val loadingMirror = mirrorThatLoaded(sym) val javaClass = loadingMirror.javaClass(clazz.javaClassName) loadingMirror.unpickleClass(clazz, module, javaClass) +// } catch { +// case ex: ClassNotFoundException => makePackage() +// case ex: NoClassDefFoundError => makePackage() + // Note: We catch NoClassDefFoundError because there are situations + // where a package and a class have the same name except for capitalization. + // It seems in this case the class is loaded even if capitalization differs + // but then a NoClassDefFound error is issued with a ("wrong name: ...") + // reason. (I guess this is a concession to Windows). + // The present behavior is a bit too forgiving, in that it masks + // all class load errors, not just wrong name errors. We should try + // to be more discriminating. To get on the right track simply delete + // the clause above and load a collection class such as collection.Iterable. + // You'll see an error that class `parallel` has the wrong name. +// } } } override def load(sym: Symbol) = complete(sym) @@ -73,51 +97,18 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => 0 < dp && dp < (name.length - 1) } - // Since runtime reflection doesn't have a luxury of enumerating all classes - // on the classpath, it has to materialize symbols for top-level definitions - // (packages, classes, objects) on demand. - // - // Someone asks us for a class named `foo.Bar`? Easy. Let's speculatively create - // a package named `foo` and then look up `newTypeName("bar")` in its decls. - // This lookup, implemented in `SymbolLoaders.PackageScope` tests the waters by - // trying to to `Class.forName("foo.Bar")` and then creates a ClassSymbol upon - // success (the whole story is a bit longer, but the rest is irrelevant here). - // - // That's all neat, but these non-deterministic mutations of the global symbol - // table give a lot of trouble in multi-threaded setting. One of the popular - // reflection crashes happens when multiple threads happen to trigger symbol - // materialization multiple times for the same symbol, making subsequent - // reflective operations stumble upon outrageous stuff like overloaded packages. - // - // Short of significantly changing SymbolLoaders I see no other way than just - // to slap a global lock on materialization in runtime reflection. class PackageScope(pkgClass: Symbol) extends Scope(initFingerPrints = -1L) // disable fingerprinting as we do not know entries beforehand with SynchronizedScope { assert(pkgClass.isType) - - // materializing multiple copies of the same symbol in PackageScope is a very popular bug - // this override does its best to guard against it - override def enter[T <: Symbol](sym: T): T = { - val existing = super.lookupEntry(sym.name) - assert(existing == null || existing.sym.isMethod, s"pkgClass = $pkgClass, sym = $sym, existing = $existing") - super.enter(sym) - } - - // package scopes need to synchronize on the GIL - // because lookupEntry might cause changes to the global symbol table - override def syncLockSynchronized[T](body: => T): T = gilSynchronized(body) - private val negatives = new mutable.HashSet[Name] - override def lookupEntry(name: Name): ScopeEntry = syncLockSynchronized { - def lookupExisting: Option[ScopeEntry] = { - val e = super.lookupEntry(name) - if (e != null) - Some(e) - else if (isInvalidClassName(name) || (negatives contains name)) - Some(null) // TODO: omg - else - None - } - def materialize: ScopeEntry = { + // disable fingerprinting as we do not know entries beforehand + private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. + override def lookupEntry(name: Name): ScopeEntry = { + val e = super.lookupEntry(name) + if (e != null) + e + else if (isInvalidClassName(name) || (negatives contains name)) + null + else { val path = if (pkgClass.isEmptyPackageClass) name.toString else pkgClass.fullName + "." + name @@ -146,7 +137,6 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => null } } - lookupExisting getOrElse materialize } } diff --git a/src/reflect/scala/reflect/runtime/SymbolTable.scala b/src/reflect/scala/reflect/runtime/SymbolTable.scala index d317d6a12b..5c08e9a508 100644 --- a/src/reflect/scala/reflect/runtime/SymbolTable.scala +++ b/src/reflect/scala/reflect/runtime/SymbolTable.scala @@ -8,7 +8,7 @@ import scala.reflect.internal.Flags._ * It can be used either from a reflexive universe (class scala.reflect.runtime.JavaUniverse), or else from * a runtime compiler that uses reflection to get a class information (class scala.tools.reflect.ReflectGlobal) */ -private[scala] trait SymbolTable extends internal.SymbolTable with JavaMirrors with SymbolLoaders with SynchronizedOps with Gil { +private[scala] trait SymbolTable extends internal.SymbolTable with JavaMirrors with SymbolLoaders with SynchronizedOps { def info(msg: => String) = if (settings.verbose.value) println("[reflect-compiler] "+msg) diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala index f9f4a26b42..7b280e59b9 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala @@ -8,40 +8,28 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable // Names - // this lock isn't subsumed by the reflection GIL - // because there's no way newXXXName methods are going to call anything reflective - // therefore we don't have a danger of a deadlock from having a fine-grained lock for name creation private lazy val nameLock = new Object - // these three methods are the only gateways into name hashtable manipulations - // we need to protected them with a lock, because they are by far not atomic - override protected def newTermName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TermName = - nameLock.synchronized { super.newTermName(cs, offset, len, cachedString) } - override protected def toTypeName(termName: TermName): TypeName = nameLock.synchronized { super.toTypeName(termName) } - override protected def toTermName(typeName: TypeName): TermName = nameLock.synchronized { super.toTermName(typeName) } + override def newTermName(s: String): TermName = nameLock.synchronized { super.newTermName(s) } + override def newTypeName(s: String): TypeName = nameLock.synchronized { super.newTypeName(s) } // BaseTypeSeqs override protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) = - // only need to synchronize BaseTypeSeqs if they contain refined types - if (elems.filter(_.isInstanceOf[RefinedType]).nonEmpty) new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq - else new BaseTypeSeq(parents, elems) + new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq trait SynchronizedBaseTypeSeq extends BaseTypeSeq { - override def apply(i: Int): Type = gilSynchronized { super.apply(i) } - override def rawElem(i: Int) = gilSynchronized { super.rawElem(i) } - override def typeSymbol(i: Int): Symbol = gilSynchronized { super.typeSymbol(i) } - override def toList: List[Type] = gilSynchronized { super.toList } - override def copy(head: Type, offset: Int): BaseTypeSeq = gilSynchronized { super.copy(head, offset) } - override def map(f: Type => Type): BaseTypeSeq = gilSynchronized { super.map(f) } - override def exists(p: Type => Boolean): Boolean = gilSynchronized { super.exists(p) } - override lazy val maxDepth = gilSynchronized { maxDepthOfElems } - override def toString = gilSynchronized { super.toString } - - override def lateMap(f: Type => Type): BaseTypeSeq = - // only need to synchronize BaseTypeSeqs if they contain refined types - if (map(f).toList.filter(_.isInstanceOf[RefinedType]).nonEmpty) new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq - else new MappedBaseTypeSeq(this, f) + override def apply(i: Int): Type = synchronized { super.apply(i) } + override def rawElem(i: Int) = synchronized { super.rawElem(i) } + override def typeSymbol(i: Int): Symbol = synchronized { super.typeSymbol(i) } + override def toList: List[Type] = synchronized { super.toList } + override def copy(head: Type, offset: Int): BaseTypeSeq = synchronized { super.copy(head, offset) } + override def map(f: Type => Type): BaseTypeSeq = synchronized { super.map(f) } + override def exists(p: Type => Boolean): Boolean = synchronized { super.exists(p) } + override lazy val maxDepth = synchronized { maxDepthOfElems } + override def toString = synchronized { super.toString } + + override def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq } // Scopes @@ -50,19 +38,15 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable override def newNestedScope(outer: Scope): Scope = new Scope(outer) with SynchronizedScope trait SynchronizedScope extends Scope { - // we can keep this lock fine-grained, because methods of Scope don't do anything extraordinary, which makes deadlocks impossible - // fancy subclasses of internal.Scopes#Scope should do synchronization themselves (e.g. see PackageScope for an example) - private lazy val syncLock = new Object - def syncLockSynchronized[T](body: => T): T = if (isCompilerUniverse) body else syncLock.synchronized { body } - override def isEmpty: Boolean = syncLockSynchronized { super.isEmpty } - override def size: Int = syncLockSynchronized { super.size } - override def enter[T <: Symbol](sym: T): T = syncLockSynchronized { super.enter(sym) } - override def rehash(sym: Symbol, newname: Name) = syncLockSynchronized { super.rehash(sym, newname) } - override def unlink(e: ScopeEntry) = syncLockSynchronized { super.unlink(e) } - override def unlink(sym: Symbol) = syncLockSynchronized { super.unlink(sym) } - override def lookupAll(name: Name) = syncLockSynchronized { super.lookupAll(name) } - override def lookupEntry(name: Name) = syncLockSynchronized { super.lookupEntry(name) } - override def lookupNextEntry(entry: ScopeEntry) = syncLockSynchronized { super.lookupNextEntry(entry) } - override def toList: List[Symbol] = syncLockSynchronized { super.toList } + override def isEmpty: Boolean = synchronized { super.isEmpty } + override def size: Int = synchronized { super.size } + override def enter[T <: Symbol](sym: T): T = synchronized { super.enter(sym) } + override def rehash(sym: Symbol, newname: Name) = synchronized { super.rehash(sym, newname) } + override def unlink(e: ScopeEntry) = synchronized { super.unlink(e) } + override def unlink(sym: Symbol) = synchronized { super.unlink(sym) } + override def lookupAll(name: Name) = synchronized { super.lookupAll(name) } + override def lookupEntry(name: Name) = synchronized { super.lookupEntry(name) } + override def lookupNextEntry(entry: ScopeEntry) = synchronized { super.lookupNextEntry(entry) } + override def toList: List[Symbol] = synchronized { super.toList } } } diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 5a0ac01ac4..00f6952dc1 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -5,18 +5,14 @@ import scala.reflect.io.AbstractFile private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => - // we can keep this lock fine-grained, because nextId is just a simple increment, which makes deadlocks impossible - private lazy val nextIdLock = new Object - override protected def nextId() = nextIdLock.synchronized { super.nextId() } + override protected def nextId() = synchronized { super.nextId() } - // we can keep this lock fine-grained, because freshExistentialName is just a simple increment, which makes deadlocks impossible - private lazy val freshExistentialNameLock = new Object override protected def freshExistentialName(suffix: String) = - freshExistentialNameLock.synchronized { super.freshExistentialName(suffix) } + synchronized { super.freshExistentialName(suffix) } // Set the fields which point companions at one another. Returns the module. override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = - gilSynchronized { super.connectModuleToClass(m, moduleClass) } + synchronized { super.connectModuleToClass(m, moduleClass) } override def newFreeTermSymbol(name: TermName, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = new FreeTermSymbol(name, value, origin) with SynchronizedTermSymbol initFlags flags @@ -28,40 +24,35 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb trait SynchronizedSymbol extends Symbol { - def gilSynchronizedIfNotInited[T](body: => T): T = { - if (isFullyInitialized) body - else gilSynchronized { body } - } - - override def validTo = gilSynchronizedIfNotInited { super.validTo } - override def info = gilSynchronizedIfNotInited { super.info } - override def rawInfo: Type = gilSynchronizedIfNotInited { super.rawInfo } - - override def typeParams: List[Symbol] = gilSynchronizedIfNotInited { - if (isCompilerUniverse) super.typeParams - else { - if (isMonomorphicType) Nil - else { - // analogously to the "info" getter, here we allow for two completions: - // one: sourceCompleter to LazyType, two: LazyType to completed type - if (validTo == NoPeriod) - rawInfo load this - if (validTo == NoPeriod) - rawInfo load this - - rawInfo.typeParams - } - } - } - override def unsafeTypeParams: List[Symbol] = gilSynchronizedIfNotInited { - if (isCompilerUniverse) super.unsafeTypeParams - else { - if (isMonomorphicType) Nil - else rawInfo.typeParams - } - } - - override def isStable: Boolean = gilSynchronized { super.isStable } + override def rawflags = synchronized { super.rawflags } + override def rawflags_=(x: Long) = synchronized { super.rawflags_=(x) } + + override def rawowner = synchronized { super.rawowner } + override def owner_=(owner: Symbol) = synchronized { super.owner_=(owner) } + + override def validTo = synchronized { super.validTo } + override def validTo_=(x: Period) = synchronized { super.validTo_=(x) } + + override def pos = synchronized { super.pos } + override def setPos(pos: Position): this.type = { synchronized { super.setPos(pos) }; this } + + override def privateWithin = synchronized { super.privateWithin } + override def privateWithin_=(sym: Symbol) = synchronized { super.privateWithin_=(sym) } + + override def info = synchronized { super.info } + override def info_=(info: Type) = synchronized { super.info_=(info) } + override def updateInfo(info: Type): Symbol = synchronized { super.updateInfo(info) } + override def rawInfo: Type = synchronized { super.rawInfo } + + override def typeParams: List[Symbol] = synchronized { super.typeParams } + + override def reset(completer: Type): this.type = synchronized { super.reset(completer) } + + override def infosString: String = synchronized { super.infosString } + + override def annotations: List[AnnotationInfo] = synchronized { super.annotations } + override def setAnnotations(annots: List[AnnotationInfo]): this.type = { synchronized { super.setAnnotations(annots) }; this } + // ------ creators ------------------------------------------------------------------- @@ -101,38 +92,49 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb override protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags - override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = - createModuleSymbol(name, pos, newFlags) - - override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long) = - new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags + override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = createModuleSymbol(name, pos, newFlags) - override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long) = - new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags + // TODO + // override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long) + // override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long) } // ------- subclasses --------------------------------------------------------------------- - trait SynchronizedTermSymbol extends SynchronizedSymbol + trait SynchronizedTermSymbol extends TermSymbol with SynchronizedSymbol { + override def name_=(x: Name) = synchronized { super.name_=(x) } + override def rawname = synchronized { super.rawname } + override def referenced: Symbol = synchronized { super.referenced } + override def referenced_=(x: Symbol) = synchronized { super.referenced_=(x) } + } trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol { - // we can keep this lock fine-grained, because it's just a cache over asSeenFrom, which makes deadlocks impossible - // unfortunately we cannot elide this lock, because the cache depends on `pre` - private lazy val typeAsMemberOfLock = new Object - override def typeAsMemberOf(pre: Type): Type = gilSynchronizedIfNotInited { typeAsMemberOfLock.synchronized { super.typeAsMemberOf(pre) } } + override def typeAsMemberOf(pre: Type): Type = synchronized { super.typeAsMemberOf(pre) } + override def paramss: List[List[Symbol]] = synchronized { super.paramss } + override def returnType: Type = synchronized { super.returnType } } - trait SynchronizedModuleSymbol extends ModuleSymbol with SynchronizedTermSymbol - trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol { - // unlike with typeConstructor, a lock is necessary here, because tpe calculation relies on - // temporarily assigning NoType to tpeCache to detect cyclic reference errors - private lazy val tpeLock = new Object - override def tpe: Type = gilSynchronizedIfNotInited { tpeLock.synchronized { super.tpe } } + override def name_=(x: Name) = synchronized { super.name_=(x) } + override def rawname = synchronized { super.rawname } + override def typeConstructor: Type = synchronized { super.typeConstructor } + override def tpe: Type = synchronized { super.tpe } } - trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol + trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol { + override def associatedFile = synchronized { super.associatedFile } + override def associatedFile_=(f: AbstractFile) = synchronized { super.associatedFile_=(f) } + override def thisSym: Symbol = synchronized { super.thisSym } + override def thisType: Type = synchronized { super.thisType } + override def typeOfThis: Type = synchronized { super.typeOfThis } + override def typeOfThis_=(tp: Type) = synchronized { super.typeOfThis_=(tp) } + override def children = synchronized { super.children } + override def addChild(sym: Symbol) = synchronized { super.addChild(sym) } + } - trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol + trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol { + override def sourceModule = synchronized { super.sourceModule } + override def implicitMembers: Scope = synchronized { super.implicitMembers } + } } diff --git a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala index 939363f8b4..a3e7c28ca4 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala @@ -12,9 +12,8 @@ private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTa // No sharing of map objects: override protected def commonOwnerMap = new CommonOwnerMap - // we can keep this lock fine-grained, because super.unique just updates the cache - // and, in particular, doesn't call any reflection APIs which makes deadlocks impossible - private lazy val uniqueLock = new Object + private object uniqueLock + private val uniques = WeakHashMap[Type, WeakReference[Type]]() override def unique[T <: Type](tp: T): T = uniqueLock.synchronized { // we need to have weak uniques for runtime reflection @@ -38,35 +37,46 @@ private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTa } class SynchronizedUndoLog extends UndoLog { - final override def lock(): Unit = gil.lock() - final override def unlock(): Unit = gil.unlock() + private val actualLock = new java.util.concurrent.locks.ReentrantLock + + final override def lock(): Unit = actualLock.lock() + final override def unlock(): Unit = actualLock.unlock() } override protected def newUndoLog = new SynchronizedUndoLog override protected def baseTypeOfNonClassTypeRef(tpe: NonClassTypeRef, clazz: Symbol) = - gilSynchronized { super.baseTypeOfNonClassTypeRef(tpe, clazz) } + synchronized { super.baseTypeOfNonClassTypeRef(tpe, clazz) } + + private object subsametypeLock override def isSameType(tp1: Type, tp2: Type): Boolean = - gilSynchronized { super.isSameType(tp1, tp2) } + subsametypeLock.synchronized { super.isSameType(tp1, tp2) } override def isDifferentType(tp1: Type, tp2: Type): Boolean = - gilSynchronized { super.isDifferentType(tp1, tp2) } + subsametypeLock.synchronized { super.isDifferentType(tp1, tp2) } override def isSubType(tp1: Type, tp2: Type, depth: Int): Boolean = - gilSynchronized { super.isSubType(tp1, tp2, depth) } + subsametypeLock.synchronized { super.isSubType(tp1, tp2, depth) } + + private object lubglbLock override def glb(ts: List[Type]): Type = - gilSynchronized { super.glb(ts) } + lubglbLock.synchronized { super.glb(ts) } override def lub(ts: List[Type]): Type = - gilSynchronized { super.lub(ts) } + lubglbLock.synchronized { super.lub(ts) } + + private object indentLock + + override protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = { + indentLock.synchronized { super.explain(op, p, tp1, arg2) } + } - override protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = - gilSynchronized { super.explain(op, p, tp1, arg2) } + private object toStringLock override protected def typeToString(tpe: Type): String = - gilSynchronized(super.typeToString(tpe)) + toStringLock.synchronized(super.typeToString(tpe)) /* The idea of caches is as follows. * When in reflexive mode, a cache is either null, or one sentinal @@ -79,18 +89,18 @@ private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTa */ override protected def defineUnderlyingOfSingleType(tpe: SingleType) = - gilSynchronized { super.defineUnderlyingOfSingleType(tpe) } + tpe.synchronized { super.defineUnderlyingOfSingleType(tpe) } override protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) = - gilSynchronized { super.defineBaseTypeSeqOfCompoundType(tpe) } + tpe.synchronized { super.defineBaseTypeSeqOfCompoundType(tpe) } override protected def defineBaseClassesOfCompoundType(tpe: CompoundType) = - gilSynchronized { super.defineBaseClassesOfCompoundType(tpe) } + tpe.synchronized { super.defineBaseClassesOfCompoundType(tpe) } override protected def defineParentsOfTypeRef(tpe: TypeRef) = - gilSynchronized { super.defineParentsOfTypeRef(tpe) } + tpe.synchronized { super.defineParentsOfTypeRef(tpe) } override protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) = - gilSynchronized { super.defineBaseTypeSeqOfTypeRef(tpe) } + tpe.synchronized { super.defineBaseTypeSeqOfTypeRef(tpe) } } diff --git a/src/reflect/scala/reflect/runtime/TwoWayCache.scala b/src/reflect/scala/reflect/runtime/TwoWayCache.scala new file mode 100644 index 0000000000..05debcba65 --- /dev/null +++ b/src/reflect/scala/reflect/runtime/TwoWayCache.scala @@ -0,0 +1,66 @@ +package scala.reflect +package runtime + +import scala.collection.mutable.WeakHashMap +import java.lang.ref.WeakReference + +/** A cache that maintains a bijection between Java reflection type `J` + * and Scala reflection type `S`. + * + * The cache is two-way weak (i.e. is powered by weak references), + * so that neither Java artifacts prevent Scala artifacts from being garbage collected, + * nor the other way around. + */ +private[runtime] class TwoWayCache[J, S] { + + private val toScalaMap = new WeakHashMap[J, WeakReference[S]] + private val toJavaMap = new WeakHashMap[S, WeakReference[J]] + + def enter(j: J, s: S) = synchronized { + // debugInfo("cached: "+j+"/"+s) + toScalaMap(j) = new WeakReference(s) + toJavaMap(s) = new WeakReference(j) + } + + private object SomeRef { + def unapply[T](optRef: Option[WeakReference[T]]): Option[T] = + if (optRef.nonEmpty) { + val result = optRef.get.get + if (result != null) Some(result) else None + } else None + } + + def toScala(key: J)(body: => S): S = synchronized { + toScalaMap get key match { + case SomeRef(v) => + v + case _ => + val result = body + enter(key, result) + result + } + } + + def toJava(key: S)(body: => J): J = synchronized { + toJavaMap get key match { + case SomeRef(v) => + v + case _ => + val result = body + enter(result, key) + result + } + } + + def toJavaOption(key: S)(body: => Option[J]): Option[J] = synchronized { + toJavaMap get key match { + case SomeRef(v) => + Some(v) + case _ => + val result = body + for (value <- result) enter(value, key) + result + } + } +} + diff --git a/src/reflect/scala/reflect/runtime/TwoWayCaches.scala b/src/reflect/scala/reflect/runtime/TwoWayCaches.scala deleted file mode 100644 index 6e2890e536..0000000000 --- a/src/reflect/scala/reflect/runtime/TwoWayCaches.scala +++ /dev/null @@ -1,68 +0,0 @@ -package scala.reflect -package runtime - -import scala.collection.mutable.WeakHashMap -import java.lang.ref.WeakReference - -/** A cache that maintains a bijection between Java reflection type `J` - * and Scala reflection type `S`. - * - * The cache is two-way weak (i.e. is powered by weak references), - * so that neither Java artifacts prevent Scala artifacts from being garbage collected, - * nor the other way around. - */ -private[runtime] trait TwoWayCaches { self: SymbolTable => - class TwoWayCache[J, S] { - - private val toScalaMap = new WeakHashMap[J, WeakReference[S]] - private val toJavaMap = new WeakHashMap[S, WeakReference[J]] - - def enter(j: J, s: S) = gilSynchronized { - // debugInfo("cached: "+j+"/"+s) - toScalaMap(j) = new WeakReference(s) - toJavaMap(s) = new WeakReference(j) - } - - private object SomeRef { - def unapply[T](optRef: Option[WeakReference[T]]): Option[T] = - if (optRef.nonEmpty) { - val result = optRef.get.get - if (result != null) Some(result) else None - } else None - } - - def toScala(key: J)(body: => S): S = gilSynchronized { - toScalaMap get key match { - case SomeRef(v) => - v - case _ => - val result = body - enter(key, result) - result - } - } - - def toJava(key: S)(body: => J): J = gilSynchronized { - toJavaMap get key match { - case SomeRef(v) => - v - case _ => - val result = body - enter(result, key) - result - } - } - - def toJavaOption(key: S)(body: => Option[J]): Option[J] = gilSynchronized { - toJavaMap get key match { - case SomeRef(v) => - Some(v) - case _ => - val result = body - for (value <- result) enter(value, key) - result - } - } - } -} - diff --git a/test/files/run/reflection-crazy-logs.check b/test/files/run/reflection-crazy-logs.check deleted file mode 100644 index 27ba77ddaf..0000000000 --- a/test/files/run/reflection-crazy-logs.check +++ /dev/null @@ -1 +0,0 @@ -true diff --git a/test/files/run/reflection-crazy-logs.scala b/test/files/run/reflection-crazy-logs.scala deleted file mode 100644 index 6844faabf6..0000000000 --- a/test/files/run/reflection-crazy-logs.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.runtime.universe._ - -object Test extends App { - println(typeOf[List[Any]] <:< typeOf[List[T] forSome { type T }]) -} \ No newline at end of file diff --git a/test/files/run/reflection-sync-potpourri.check b/test/files/run/reflection-sync-potpourri.check deleted file mode 100644 index fa83c149a6..0000000000 --- a/test/files/run/reflection-sync-potpourri.check +++ /dev/null @@ -1,1000 +0,0 @@ -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec -s1 = java.lang.String, s2 = java.lang.annotation.Annotation, java.lang.reflect.Method, scala.io.BufferedSource, scala.io.Codec diff --git a/test/files/run/reflection-sync-potpourri.scala b/test/files/run/reflection-sync-potpourri.scala deleted file mode 100644 index 06dcea9209..0000000000 --- a/test/files/run/reflection-sync-potpourri.scala +++ /dev/null @@ -1,31 +0,0 @@ -import scala.reflect.runtime.universe._ - -// this test checks that under heavily multithreaded conditions: -// 1) scala.reflect.runtime.universe, its rootMirror and definitions are initialized correctly -// 2) symbols are correctly materialized into PackageScopes (no dupes) -// 3) unpickling works okay even we unpickle the same symbol a lot of times - -object Test extends App { - def foo[T: TypeTag](x: T) = typeOf[T].toString - val n = 1000 - val rng = new scala.util.Random() - val types = List( - () => typeOf[java.lang.reflect.Method], - () => typeOf[java.lang.annotation.Annotation], - () => typeOf[scala.io.BufferedSource], - () => typeOf[scala.io.Codec]) - val perms = types.permutations.toList - def force(lazytpe: () => Type): String = { - lazytpe().typeSymbol.typeSignature - lazytpe().toString - } - val diceRolls = List.fill(n)(rng.nextInt(perms.length)) - val threads = (1 to n) map (i => new Thread(s"Reflector-$i") { - override def run(): Unit = { - val s1 = foo("42") - val s2 = perms(diceRolls(i - 1)).map(x => force(x)).sorted.mkString(", ") - println(s"s1 = $s1, s2 = $s2") - } - }) - threads foreach (_.start) -} \ No newline at end of file diff --git a/test/files/run/reflection-sync-subtypes.check b/test/files/run/reflection-sync-subtypes.check deleted file mode 100644 index f223c7ae2a..0000000000 --- a/test/files/run/reflection-sync-subtypes.check +++ /dev/null @@ -1,1000 +0,0 @@ -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true -false, false, true, true diff --git a/test/files/run/reflection-sync-subtypes.scala b/test/files/run/reflection-sync-subtypes.scala deleted file mode 100644 index 659a7c0cdb..0000000000 --- a/test/files/run/reflection-sync-subtypes.scala +++ /dev/null @@ -1,20 +0,0 @@ -import scala.reflect.runtime.universe._ - -object Test extends App { - val n = 1000 - val rng = new scala.util.Random() - val tasks = List( - () => typeOf[List[Int]] <:< typeOf[List[T] forSome { type T }], - () => typeOf[List[T] forSome { type T }] <:< typeOf[List[Any]], - () => typeOf[Map[Int, Object]] <:< typeOf[Iterable[(Int, String)]], - () => typeOf[Expr[Any] { val mirror: rootMirror.type }] <:< typeOf[Expr[List[List[List[Int]]]]{ val mirror: rootMirror.type }]) - val perms = tasks.permutations.toList - val diceRolls = List.fill(n)(rng.nextInt(perms.length)) - val threads = (1 to n) map (i => new Thread(s"Reflector-$i") { - override def run(): Unit = { - val result = perms(diceRolls(i - 1)).map(_()) - println(result.sorted.mkString(", ")) - } - }) - threads foreach (_.start) -} \ No newline at end of file diff --git a/test/files/run/t7045.check b/test/files/run/t7045.check deleted file mode 100644 index 28134535c8..0000000000 --- a/test/files/run/t7045.check +++ /dev/null @@ -1,2 +0,0 @@ -D with C -D with C diff --git a/test/files/run/t7045.scala b/test/files/run/t7045.scala deleted file mode 100644 index f41baca05e..0000000000 --- a/test/files/run/t7045.scala +++ /dev/null @@ -1,12 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.runtime.{currentMirror => cm} - -class C -class D { self: C => } - -object Test extends App { - val d = cm.staticClass("D") - println(d.selfType) - d.typeSignature - println(d.selfType) -} \ No newline at end of file -- cgit v1.2.3 From b775d8f16d988a4fc7992f0cea1459b8a317f995 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 1 Mar 2013 18:16:22 -0800 Subject: test.done again checks bin compat (using mima 0.1.5) --- bincompat-backward.whitelist.conf | 4 ++++ build.xml | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index f559d673f0..4794666721 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -154,6 +154,10 @@ filter { { matchName="scala.reflect.internal.util.Statistics#RelCounter.scala$reflect$internal$util$Statistics$RelCounter$$super$prefix" problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Names#NameOps.name" + problemName=MissingFieldProblem } ] } diff --git a/build.xml b/build.xml index 5a8c200835..01d867d8ca 100644 --- a/build.xml +++ b/build.xml @@ -22,7 +22,7 @@ END-USER TARGETS - - + - + @@ -2665,7 +2665,7 @@ Binary compatibility testing - + Date: Fri, 1 Mar 2013 17:05:12 -0800 Subject: [nomaster] SI-7195 minor version mustn't introduce warnings We want 2.10.1 to be a drop-in replacement for 2.10.0, so we can't start warning where we weren't warning in 2.10.0. See SI-5954 (#1882, #2079) for when it was an implementation restriction, which was then weakened to a warning. It's now hidden behind -Ydebug. --- .../scala/tools/nsc/typechecker/Typers.scala | 4 +- test/files/neg/t5954.check | 16 -------- test/files/neg/t5954.flags | 1 - test/files/neg/t5954.scala | 46 ---------------------- 4 files changed, 3 insertions(+), 64 deletions(-) delete mode 100644 test/files/neg/t5954.check delete mode 100644 test/files/neg/t5954.flags delete mode 100644 test/files/neg/t5954.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 4fb68fc2a9..6e9b3b3fcd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1823,7 +1823,9 @@ trait Typers extends Modes with Adaptations with Tags { def pkgObjectWarning(m : Symbol, mdef : ModuleDef, restricted : String) = { val pkgName = mdef.symbol.ownerChain find (_.isPackage) map (_.decodedName) getOrElse mdef.symbol.toString - context.warning(if (m.pos.isDefined) m.pos else mdef.pos, s"${m} should be placed directly in package ${pkgName} instead of package object ${pkgName}. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954.") + val pos = if (m.pos.isDefined) m.pos else mdef.pos + debugwarn(s"${m} should be placed directly in package ${pkgName} instead of package object ${pkgName}. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954.") + debugwarn(pos.lineContent + (if (pos.isDefined) " " * (pos.column - 1) + "^" else "")) } } diff --git a/test/files/neg/t5954.check b/test/files/neg/t5954.check deleted file mode 100644 index ed10658b24..0000000000 --- a/test/files/neg/t5954.check +++ /dev/null @@ -1,16 +0,0 @@ -t5954.scala:36: error: class D should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - case class D() - ^ -t5954.scala:35: error: object C should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - object C - ^ -t5954.scala:34: error: trait C should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - trait C - ^ -t5954.scala:33: error: object B should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - object B - ^ -t5954.scala:32: error: class B should be placed directly in package A instead of package object A. Under some circumstances companion objects and case classes in package objects can fail to recompile. See https://issues.scala-lang.org/browse/SI-5954. - class B - ^ -5 errors found diff --git a/test/files/neg/t5954.flags b/test/files/neg/t5954.flags deleted file mode 100644 index 85d8eb2ba2..0000000000 --- a/test/files/neg/t5954.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings diff --git a/test/files/neg/t5954.scala b/test/files/neg/t5954.scala deleted file mode 100644 index 3ccb5ed3ff..0000000000 --- a/test/files/neg/t5954.scala +++ /dev/null @@ -1,46 +0,0 @@ -// if you ever think you've fixed the underlying reason for the warning -// imposed by SI-5954, then here's a test that should pass with two "succes"es -// -//import scala.tools.partest._ -// -//object Test extends DirectTest { -// def code = ??? -// -// def problemCode = """ -// package object A { -// class B -// object B -// case class C() -// } -// """ -// -// def compileProblemCode() = { -// val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator") -// compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(problemCode) -// } -// -// def show() : Unit = { -// for (i <- 0 until 2) { -// compileProblemCode() -// println(s"success ${i + 1}") -// } -// } -//} - -package object A { - // these should be prevented by the implementation restriction - class B - object B - trait C - object C - case class D() - // all the rest of these should be ok - class E - object F - val g = "omg" - var h = "wtf" - def i = "lol" - type j = String - class K(val k : Int) extends AnyVal - implicit class L(val l : Int) -} -- cgit v1.2.3 From 387fbf459efe5bb89f3d7a76c819f72b8f8fd58f Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 26 Feb 2013 13:20:03 +0100 Subject: SI-7185 Avoid NPE in TreeInfo.isExprSafeToInline We got there typechecking code with a redundant layer of Block. We can't express that in source code, so we test this with manual tree construction and with XML literals, which as reported produce such trees. --- src/reflect/scala/reflect/internal/TreeInfo.scala | 3 +- test/files/neg/t7185.check | 7 +++++ test/files/neg/t7185.scala | 3 ++ test/files/run/t7185.check | 34 +++++++++++++++++++++++ test/files/run/t7185.scala | 12 ++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 test/files/neg/t7185.check create mode 100644 test/files/neg/t7185.scala create mode 100644 test/files/run/t7185.check create mode 100644 test/files/run/t7185.scala diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 3040486076..3e74b5d22d 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -98,7 +98,8 @@ abstract class TreeInfo { // However, before typing, applications of nullary functional values are also // Apply(function, Nil) trees. To prevent them from being treated as pure, // we check that the callee is a method. - fn.symbol.isMethod && !fn.symbol.isLazy && isExprSafeToInline(fn) + // The callee might also be a Block, which has a null symbol, so we guard against that (SI-7185) + fn.symbol != null && fn.symbol.isMethod && !fn.symbol.isLazy && isExprSafeToInline(fn) case Typed(expr, _) => isExprSafeToInline(expr) case Block(stats, expr) => diff --git a/test/files/neg/t7185.check b/test/files/neg/t7185.check new file mode 100644 index 0000000000..46f2cc797e --- /dev/null +++ b/test/files/neg/t7185.check @@ -0,0 +1,7 @@ +t7185.scala:2: error: overloaded method value apply with alternatives: + (f: scala.xml.Node => Boolean)scala.xml.NodeSeq + (i: Int)scala.xml.Node + cannot be applied to () + () + ^ +one error found diff --git a/test/files/neg/t7185.scala b/test/files/neg/t7185.scala new file mode 100644 index 0000000000..2f9284bc5f --- /dev/null +++ b/test/files/neg/t7185.scala @@ -0,0 +1,3 @@ +object Test { + () +} diff --git a/test/files/run/t7185.check b/test/files/run/t7185.check new file mode 100644 index 0000000000..455c1aa3b7 --- /dev/null +++ b/test/files/run/t7185.check @@ -0,0 +1,34 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.tools.reflect.ToolBox +import scala.tools.reflect.ToolBox + +scala> import scala.reflect.runtime.universe._ +import scala.reflect.runtime.universe._ + +scala> object O { def apply() = 0 } +defined module O + +scala> val ORef = reify { O }.tree +ORef: reflect.runtime.universe.Tree = $read.O + +scala> val tree = Apply(Block(Nil, Block(Nil, ORef)), Nil) +tree: reflect.runtime.universe.Apply = +{ + { + $read.O + } +}() + +scala> {val tb = reflect.runtime.currentMirror.mkToolBox(); tb.typeCheck(tree): Any} +res0: Any = +{ + { + $read.O.apply() + } +} + +scala> diff --git a/test/files/run/t7185.scala b/test/files/run/t7185.scala new file mode 100644 index 0000000000..d9d913e78a --- /dev/null +++ b/test/files/run/t7185.scala @@ -0,0 +1,12 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def code = """ +import scala.tools.reflect.ToolBox +import scala.reflect.runtime.universe._ +object O { def apply() = 0 } +val ORef = reify { O }.tree +val tree = Apply(Block(Nil, Block(Nil, ORef)), Nil) +{val tb = reflect.runtime.currentMirror.mkToolBox(); tb.typeCheck(tree): Any} +""" +} -- cgit v1.2.3 From 0a3219b90e1611d074abe935c5f05dab097e116d Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 22 Feb 2013 16:45:45 -0800 Subject: move sat solving to separate file --- .../scala/tools/nsc/transform/patmat/Logic.scala | 232 -------------------- .../nsc/transform/patmat/PatternMatching.scala | 2 +- .../scala/tools/nsc/transform/patmat/Solving.scala | 242 +++++++++++++++++++++ 3 files changed, 243 insertions(+), 233 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/transform/patmat/Solving.scala diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala index a726a230ac..22eabb6d6f 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala @@ -289,238 +289,6 @@ trait Logic extends Debugging { } } -// naive CNF translation and simple DPLL solver -trait SimpleSolver extends Logic { - import PatternMatchingStats._ - trait CNF extends PropositionalLogic { - - /** Override Array creation for efficiency (to not go through reflection). */ - private implicit val clauseTag: scala.reflect.ClassTag[Clause] = new scala.reflect.ClassTag[Clause] { - def runtimeClass: java.lang.Class[Clause] = classOf[Clause] - final override def newArray(len: Int): Array[Clause] = new Array[Clause](len) - } - - import scala.collection.mutable.ArrayBuffer - type FormulaBuilder = ArrayBuffer[Clause] - def formulaBuilder = ArrayBuffer[Clause]() - def formulaBuilderSized(init: Int) = new ArrayBuffer[Clause](init) - def addFormula(buff: FormulaBuilder, f: Formula): Unit = buff ++= f - def toFormula(buff: FormulaBuilder): Formula = buff - - // CNF: a formula is a conjunction of clauses - type Formula = FormulaBuilder - def formula(c: Clause*): Formula = ArrayBuffer(c: _*) - - type Clause = Set[Lit] - // a clause is a disjunction of distinct literals - def clause(l: Lit*): Clause = l.toSet - - type Lit - def Lit(sym: Sym, pos: Boolean = true): Lit - - def andFormula(a: Formula, b: Formula): Formula = a ++ b - def simplifyFormula(a: Formula): Formula = a.distinct - - private def merge(a: Clause, b: Clause) = a ++ b - - // throws an AnalysisBudget.Exception when the prop results in a CNF that's too big - // TODO: be smarter/more efficient about this (http://lara.epfl.ch/w/sav09:tseitin_s_encoding) - def eqFreePropToSolvable(p: Prop): Formula = { - def negationNormalFormNot(p: Prop, budget: Int): Prop = - if (budget <= 0) throw AnalysisBudget.exceeded - else p match { - case And(a, b) => Or(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1)) - case Or(a, b) => And(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1)) - case Not(p) => negationNormalForm(p, budget - 1) - case True => False - case False => True - case s: Sym => Not(s) - } - - def negationNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Prop = - if (budget <= 0) throw AnalysisBudget.exceeded - else p match { - case And(a, b) => And(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1)) - case Or(a, b) => Or(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1)) - case Not(negated) => negationNormalFormNot(negated, budget - 1) - case True - | False - | (_ : Sym) => p - } - - val TrueF = formula() - val FalseF = formula(clause()) - def lit(s: Sym) = formula(clause(Lit(s))) - def negLit(s: Sym) = formula(clause(Lit(s, false))) - - def conjunctiveNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Formula = { - def distribute(a: Formula, b: Formula, budget: Int): Formula = - if (budget <= 0) throw AnalysisBudget.exceeded - else - (a, b) match { - // true \/ _ = true - // _ \/ true = true - case (trueA, trueB) if trueA.size == 0 || trueB.size == 0 => TrueF - // lit \/ lit - case (a, b) if a.size == 1 && b.size == 1 => formula(merge(a(0), b(0))) - // (c1 /\ ... /\ cn) \/ d = ((c1 \/ d) /\ ... /\ (cn \/ d)) - // d \/ (c1 /\ ... /\ cn) = ((d \/ c1) /\ ... /\ (d \/ cn)) - case (cs, ds) => - val (big, small) = if (cs.size > ds.size) (cs, ds) else (ds, cs) - big flatMap (c => distribute(formula(c), small, budget - (big.size*small.size))) - } - - if (budget <= 0) throw AnalysisBudget.exceeded - - p match { - case True => TrueF - case False => FalseF - case s: Sym => lit(s) - case Not(s: Sym) => negLit(s) - case And(a, b) => - val cnfA = conjunctiveNormalForm(a, budget - 1) - val cnfB = conjunctiveNormalForm(b, budget - cnfA.size) - cnfA ++ cnfB - case Or(a, b) => - val cnfA = conjunctiveNormalForm(a) - val cnfB = conjunctiveNormalForm(b) - distribute(cnfA, cnfB, budget - (cnfA.size + cnfB.size)) - } - } - - val start = if (Statistics.canEnable) Statistics.startTimer(patmatCNF) else null - val res = conjunctiveNormalForm(negationNormalForm(p)) - - if (Statistics.canEnable) Statistics.stopTimer(patmatCNF, start) - - // - if (Statistics.canEnable) patmatCNFSizes(res.size).value += 1 - -// debug.patmat("cnf for\n"+ p +"\nis:\n"+cnfString(res)) - res - } - } - - // simple solver using DPLL - trait Solver extends CNF { - // a literal is a (possibly negated) variable - def Lit(sym: Sym, pos: Boolean = true) = new Lit(sym, pos) - class Lit(val sym: Sym, val pos: Boolean) { - override def toString = if (!pos) "-"+ sym.toString else sym.toString - override def equals(o: Any) = o match { - case o: Lit => (o.sym eq sym) && (o.pos == pos) - case _ => false - } - override def hashCode = sym.hashCode + pos.hashCode - - def unary_- = Lit(sym, !pos) - } - - def cnfString(f: Formula) = alignAcrossRows(f map (_.toList) toList, "\\/", " /\\\n") - - // adapted from http://lara.epfl.ch/w/sav10:simple_sat_solver (original by Hossein Hojjat) - val EmptyModel = Map.empty[Sym, Boolean] - val NoModel: Model = null - - // returns all solutions, if any (TODO: better infinite recursion backstop -- detect fixpoint??) - def findAllModelsFor(f: Formula): List[Model] = { - val vars: Set[Sym] = f.flatMap(_ collect {case l: Lit => l.sym}).toSet - // debug.patmat("vars "+ vars) - // the negation of a model -(S1=True/False /\ ... /\ SN=True/False) = clause(S1=False/True, ...., SN=False/True) - def negateModel(m: Model) = clause(m.toSeq.map{ case (sym, pos) => Lit(sym, !pos) } : _*) - - def findAllModels(f: Formula, models: List[Model], recursionDepthAllowed: Int = 10): List[Model]= - if (recursionDepthAllowed == 0) models - else { - debug.patmat("find all models for\n"+ cnfString(f)) - val model = findModelFor(f) - // if we found a solution, conjunct the formula with the model's negation and recurse - if (model ne NoModel) { - val unassigned = (vars -- model.keySet).toList - debug.patmat("unassigned "+ unassigned +" in "+ model) - def force(lit: Lit) = { - val model = withLit(findModelFor(dropUnit(f, lit)), lit) - if (model ne NoModel) List(model) - else Nil - } - val forced = unassigned flatMap { s => - force(Lit(s, true)) ++ force(Lit(s, false)) - } - debug.patmat("forced "+ forced) - val negated = negateModel(model) - findAllModels(f :+ negated, model :: (forced ++ models), recursionDepthAllowed - 1) - } - else models - } - - findAllModels(f, Nil) - } - - private def withLit(res: Model, l: Lit): Model = if (res eq NoModel) NoModel else res + (l.sym -> l.pos) - private def dropUnit(f: Formula, unitLit: Lit): Formula = { - val negated = -unitLit - // drop entire clauses that are trivially true - // (i.e., disjunctions that contain the literal we're making true in the returned model), - // and simplify clauses by dropping the negation of the literal we're making true - // (since False \/ X == X) - val dropped = formulaBuilderSized(f.size) - for { - clause <- f - if !(clause contains unitLit) - } dropped += (clause - negated) - dropped - } - - def findModelFor(f: Formula): Model = { - @inline def orElse(a: Model, b: => Model) = if (a ne NoModel) a else b - - debug.patmat("DPLL\n"+ cnfString(f)) - - val start = if (Statistics.canEnable) Statistics.startTimer(patmatAnaDPLL) else null - - val satisfiableWithModel: Model = - if (f isEmpty) EmptyModel - else if(f exists (_.isEmpty)) NoModel - else f.find(_.size == 1) match { - case Some(unitClause) => - val unitLit = unitClause.head - // debug.patmat("unit: "+ unitLit) - withLit(findModelFor(dropUnit(f, unitLit)), unitLit) - case _ => - // partition symbols according to whether they appear in positive and/or negative literals - val pos = new mutable.HashSet[Sym]() - val neg = new mutable.HashSet[Sym]() - f.foreach{_.foreach{ lit => - if (lit.pos) pos += lit.sym else neg += lit.sym - }} - // appearing in both positive and negative - val impures = pos intersect neg - // appearing only in either positive/negative positions - val pures = (pos ++ neg) -- impures - - if (pures nonEmpty) { - val pureSym = pures.head - // turn it back into a literal - // (since equality on literals is in terms of equality - // of the underlying symbol and its positivity, simply construct a new Lit) - val pureLit = Lit(pureSym, pos(pureSym)) - // debug.patmat("pure: "+ pureLit +" pures: "+ pures +" impures: "+ impures) - val simplified = f.filterNot(_.contains(pureLit)) - withLit(findModelFor(simplified), pureLit) - } else { - val split = f.head.head - // debug.patmat("split: "+ split) - orElse(findModelFor(f :+ clause(split)), findModelFor(f :+ clause(-split))) - } - } - - if (Statistics.canEnable) Statistics.stopTimer(patmatAnaDPLL, start) - - satisfiableWithModel - } - } -} - trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis { trait TreesAndTypesDomain extends PropositionalLogic with CheckableTreeAndTypeAnalysis { type Type = global.Type diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala index 946b0b0714..6d6774cf20 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala @@ -41,7 +41,7 @@ trait PatternMatching extends Transform with TypingTransformers with MatchTreeMaking with MatchCodeGen with ScalaLogic - with SimpleSolver + with Solving with MatchAnalysis with MatchOptimization { import global._ diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala new file mode 100644 index 0000000000..843f831ea1 --- /dev/null +++ b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala @@ -0,0 +1,242 @@ +/* NSC -- new Scala compiler + * + * Copyright 2011-2013 LAMP/EPFL + * @author Adriaan Moors + */ + +package scala.tools.nsc.transform.patmat + +import scala.collection.mutable +import scala.reflect.internal.util.Statistics + +// naive CNF translation and simple DPLL solver +trait Solving extends Logic { + import PatternMatchingStats._ + trait CNF extends PropositionalLogic { + + /** Override Array creation for efficiency (to not go through reflection). */ + private implicit val clauseTag: scala.reflect.ClassTag[Clause] = new scala.reflect.ClassTag[Clause] { + def runtimeClass: java.lang.Class[Clause] = classOf[Clause] + final override def newArray(len: Int): Array[Clause] = new Array[Clause](len) + } + + import scala.collection.mutable.ArrayBuffer + type FormulaBuilder = ArrayBuffer[Clause] + def formulaBuilder = ArrayBuffer[Clause]() + def formulaBuilderSized(init: Int) = new ArrayBuffer[Clause](init) + def addFormula(buff: FormulaBuilder, f: Formula): Unit = buff ++= f + def toFormula(buff: FormulaBuilder): Formula = buff + + // CNF: a formula is a conjunction of clauses + type Formula = FormulaBuilder + def formula(c: Clause*): Formula = ArrayBuffer(c: _*) + + type Clause = Set[Lit] + // a clause is a disjunction of distinct literals + def clause(l: Lit*): Clause = l.toSet + + type Lit + def Lit(sym: Sym, pos: Boolean = true): Lit + + def andFormula(a: Formula, b: Formula): Formula = a ++ b + def simplifyFormula(a: Formula): Formula = a.distinct + + private def merge(a: Clause, b: Clause) = a ++ b + + // throws an AnalysisBudget.Exception when the prop results in a CNF that's too big + // TODO: be smarter/more efficient about this (http://lara.epfl.ch/w/sav09:tseitin_s_encoding) + def eqFreePropToSolvable(p: Prop): Formula = { + def negationNormalFormNot(p: Prop, budget: Int): Prop = + if (budget <= 0) throw AnalysisBudget.exceeded + else p match { + case And(a, b) => Or(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1)) + case Or(a, b) => And(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1)) + case Not(p) => negationNormalForm(p, budget - 1) + case True => False + case False => True + case s: Sym => Not(s) + } + + def negationNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Prop = + if (budget <= 0) throw AnalysisBudget.exceeded + else p match { + case And(a, b) => And(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1)) + case Or(a, b) => Or(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1)) + case Not(negated) => negationNormalFormNot(negated, budget - 1) + case True + | False + | (_ : Sym) => p + } + + val TrueF = formula() + val FalseF = formula(clause()) + def lit(s: Sym) = formula(clause(Lit(s))) + def negLit(s: Sym) = formula(clause(Lit(s, false))) + + def conjunctiveNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Formula = { + def distribute(a: Formula, b: Formula, budget: Int): Formula = + if (budget <= 0) throw AnalysisBudget.exceeded + else + (a, b) match { + // true \/ _ = true + // _ \/ true = true + case (trueA, trueB) if trueA.size == 0 || trueB.size == 0 => TrueF + // lit \/ lit + case (a, b) if a.size == 1 && b.size == 1 => formula(merge(a(0), b(0))) + // (c1 /\ ... /\ cn) \/ d = ((c1 \/ d) /\ ... /\ (cn \/ d)) + // d \/ (c1 /\ ... /\ cn) = ((d \/ c1) /\ ... /\ (d \/ cn)) + case (cs, ds) => + val (big, small) = if (cs.size > ds.size) (cs, ds) else (ds, cs) + big flatMap (c => distribute(formula(c), small, budget - (big.size*small.size))) + } + + if (budget <= 0) throw AnalysisBudget.exceeded + + p match { + case True => TrueF + case False => FalseF + case s: Sym => lit(s) + case Not(s: Sym) => negLit(s) + case And(a, b) => + val cnfA = conjunctiveNormalForm(a, budget - 1) + val cnfB = conjunctiveNormalForm(b, budget - cnfA.size) + cnfA ++ cnfB + case Or(a, b) => + val cnfA = conjunctiveNormalForm(a) + val cnfB = conjunctiveNormalForm(b) + distribute(cnfA, cnfB, budget - (cnfA.size + cnfB.size)) + } + } + + val start = if (Statistics.canEnable) Statistics.startTimer(patmatCNF) else null + val res = conjunctiveNormalForm(negationNormalForm(p)) + + if (Statistics.canEnable) Statistics.stopTimer(patmatCNF, start) + + // + if (Statistics.canEnable) patmatCNFSizes(res.size).value += 1 + +// debug.patmat("cnf for\n"+ p +"\nis:\n"+cnfString(res)) + res + } + } + + // simple solver using DPLL + trait Solver extends CNF { + // a literal is a (possibly negated) variable + def Lit(sym: Sym, pos: Boolean = true) = new Lit(sym, pos) + class Lit(val sym: Sym, val pos: Boolean) { + override def toString = if (!pos) "-"+ sym.toString else sym.toString + override def equals(o: Any) = o match { + case o: Lit => (o.sym eq sym) && (o.pos == pos) + case _ => false + } + override def hashCode = sym.hashCode + pos.hashCode + + def unary_- = Lit(sym, !pos) + } + + def cnfString(f: Formula) = alignAcrossRows(f map (_.toList) toList, "\\/", " /\\\n") + + // adapted from http://lara.epfl.ch/w/sav10:simple_sat_solver (original by Hossein Hojjat) + val EmptyModel = Map.empty[Sym, Boolean] + val NoModel: Model = null + + // returns all solutions, if any (TODO: better infinite recursion backstop -- detect fixpoint??) + def findAllModelsFor(f: Formula): List[Model] = { + val vars: Set[Sym] = f.flatMap(_ collect {case l: Lit => l.sym}).toSet + // debug.patmat("vars "+ vars) + // the negation of a model -(S1=True/False /\ ... /\ SN=True/False) = clause(S1=False/True, ...., SN=False/True) + def negateModel(m: Model) = clause(m.toSeq.map{ case (sym, pos) => Lit(sym, !pos) } : _*) + + def findAllModels(f: Formula, models: List[Model], recursionDepthAllowed: Int = 10): List[Model]= + if (recursionDepthAllowed == 0) models + else { + debug.patmat("find all models for\n"+ cnfString(f)) + val model = findModelFor(f) + // if we found a solution, conjunct the formula with the model's negation and recurse + if (model ne NoModel) { + val unassigned = (vars -- model.keySet).toList + debug.patmat("unassigned "+ unassigned +" in "+ model) + def force(lit: Lit) = { + val model = withLit(findModelFor(dropUnit(f, lit)), lit) + if (model ne NoModel) List(model) + else Nil + } + val forced = unassigned flatMap { s => + force(Lit(s, true)) ++ force(Lit(s, false)) + } + debug.patmat("forced "+ forced) + val negated = negateModel(model) + findAllModels(f :+ negated, model :: (forced ++ models), recursionDepthAllowed - 1) + } + else models + } + + findAllModels(f, Nil) + } + + private def withLit(res: Model, l: Lit): Model = if (res eq NoModel) NoModel else res + (l.sym -> l.pos) + private def dropUnit(f: Formula, unitLit: Lit): Formula = { + val negated = -unitLit + // drop entire clauses that are trivially true + // (i.e., disjunctions that contain the literal we're making true in the returned model), + // and simplify clauses by dropping the negation of the literal we're making true + // (since False \/ X == X) + val dropped = formulaBuilderSized(f.size) + for { + clause <- f + if !(clause contains unitLit) + } dropped += (clause - negated) + dropped + } + + def findModelFor(f: Formula): Model = { + @inline def orElse(a: Model, b: => Model) = if (a ne NoModel) a else b + + debug.patmat("DPLL\n"+ cnfString(f)) + + val start = if (Statistics.canEnable) Statistics.startTimer(patmatAnaDPLL) else null + + val satisfiableWithModel: Model = + if (f isEmpty) EmptyModel + else if(f exists (_.isEmpty)) NoModel + else f.find(_.size == 1) match { + case Some(unitClause) => + val unitLit = unitClause.head + // debug.patmat("unit: "+ unitLit) + withLit(findModelFor(dropUnit(f, unitLit)), unitLit) + case _ => + // partition symbols according to whether they appear in positive and/or negative literals + val pos = new mutable.HashSet[Sym]() + val neg = new mutable.HashSet[Sym]() + f.foreach{_.foreach{ lit => + if (lit.pos) pos += lit.sym else neg += lit.sym + }} + // appearing in both positive and negative + val impures = pos intersect neg + // appearing only in either positive/negative positions + val pures = (pos ++ neg) -- impures + + if (pures nonEmpty) { + val pureSym = pures.head + // turn it back into a literal + // (since equality on literals is in terms of equality + // of the underlying symbol and its positivity, simply construct a new Lit) + val pureLit = Lit(pureSym, pos(pureSym)) + // debug.patmat("pure: "+ pureLit +" pures: "+ pures +" impures: "+ impures) + val simplified = f.filterNot(_.contains(pureLit)) + withLit(findModelFor(simplified), pureLit) + } else { + val split = f.head.head + // debug.patmat("split: "+ split) + orElse(findModelFor(f :+ clause(split)), findModelFor(f :+ clause(-split))) + } + } + + if (Statistics.canEnable) Statistics.stopTimer(patmatAnaDPLL, start) + + satisfiableWithModel + } + } +} -- cgit v1.2.3 From 5b7cfe3c63c15488ed7d8a9bb3b8d7f2043874d8 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 22 Feb 2013 16:46:21 -0800 Subject: better names for components of MatchTranslator --- .../tools/nsc/transform/patmat/MatchAnalysis.scala | 31 ++++++++++----------- .../nsc/transform/patmat/MatchOptimization.scala | 32 +++++++++++----------- .../nsc/transform/patmat/PatternMatching.scala | 4 +-- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index 95c3744ca1..74b932e173 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -125,23 +125,15 @@ trait TreeAndTypeAnalysis extends Debugging { } } -trait MatchAnalysis extends TreeAndTypeAnalysis with ScalaLogic with MatchTreeMaking { - import PatternMatchingStats._ - import global.{Tree, Type, Symbol, CaseDef, atPos, - Select, Block, ThisType, SingleType, NoPrefix, NoType, definitions, needsOuterTest, - ConstantType, Literal, Constant, gen, This, analyzer, EmptyTree, map2, NoSymbol, Traverser, - Function, Typed, treeInfo, DefTree, ValDef, nme, appliedType, Name, WildcardType, Ident, TypeRef, - UniqueType, RefinedType, currentUnit, SingletonType, singleType, ModuleClassSymbol, - nestedMemberType, TypeMap, EmptyScope, Apply, If, Bind, lub, Alternative, deriveCaseDef, Match, MethodType, LabelDef, TypeTree, Throw, newTermName} - - import definitions._ - import analyzer.{Typer, ErrorUtils, formalTypes} +trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchTreeMaking { + import global.{Tree, Type, NoType, Symbol, NoSymbol, ConstantType, Literal, Constant, Ident, UniqueType, RefinedType, EmptyScope} + import global.definitions.{ListClass, NilModule} /** * Represent a match as a formula in propositional logic that encodes whether the match matches (abstractly: we only consider types) * */ - trait TreeMakerApproximation extends TreeMakers with TreesAndTypesDomain { + trait MatchApproximator extends TreeMakers with TreesAndTypesDomain { object Test { var currId = 0 } @@ -348,7 +340,14 @@ trait MatchAnalysis extends TreeAndTypeAnalysis with ScalaLogic with MatchTreeMa } } - trait MatchAnalyses extends TreeMakerApproximation { +} + +trait MatchAnalysis extends MatchApproximation { + import PatternMatchingStats._ + import global.{Tree, Type, Symbol, NoSymbol, Ident, Select} + import global.definitions.{isPrimitiveValueClass, ConsClass, isTupleSymbol} + + trait MatchAnalyzer extends MatchApproximator { def uncheckedWarning(pos: Position, msg: String) = global.currentUnit.uncheckedWarning(pos, msg) def warn(pos: Position, ex: AnalysisBudget.Exception, kind: String) = uncheckedWarning(pos, s"Cannot check match for $kind.\n${ex.advice}") @@ -498,7 +497,7 @@ trait MatchAnalysis extends TreeAndTypeAnalysis with ScalaLogic with MatchTreeMa // a way to construct a value that will make the match fail: a constructor invocation, a constant, an object of some type) class CounterExample { - protected[MatchAnalyses] def flattenConsArgs: List[CounterExample] = Nil + protected[MatchAnalyzer] def flattenConsArgs: List[CounterExample] = Nil def coveredBy(other: CounterExample): Boolean = this == other || other == WildcardExample } case class ValueExample(c: ValueConst) extends CounterExample { override def toString = c.toString } @@ -513,11 +512,11 @@ trait MatchAnalysis extends TreeAndTypeAnalysis with ScalaLogic with MatchTreeMa } } case class ListExample(ctorArgs: List[CounterExample]) extends CounterExample { - protected[MatchAnalyses] override def flattenConsArgs: List[CounterExample] = ctorArgs match { + protected[MatchAnalyzer] override def flattenConsArgs: List[CounterExample] = ctorArgs match { case hd :: tl :: Nil => hd :: tl.flattenConsArgs case _ => Nil } - protected[MatchAnalyses] lazy val elems = flattenConsArgs + protected[MatchAnalyzer] lazy val elems = flattenConsArgs override def coveredBy(other: CounterExample): Boolean = other match { diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala index ebc2750a4d..dcf2413b15 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala @@ -30,7 +30,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { //// - trait CommonSubconditionElimination extends TreeMakerApproximation { self: OptimizedCodegen => + trait CommonSubconditionElimination extends OptimizedCodegen with MatchApproximator { /** a flow-sensitive, generalised, common sub-expression elimination * reuse knowledge from performed tests * the only sub-expressions we consider are the conditions and results of the three tests (type, type&equality, equality) @@ -205,16 +205,16 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { //// DCE - trait DeadCodeElimination extends TreeMakers { - // TODO: non-trivial dead-code elimination - // e.g., the following match should compile to a simple instanceof: - // case class Ident(name: String) - // for (Ident(name) <- ts) println(name) - def doDCE(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): List[List[TreeMaker]] = { - // do minimal DCE - cases - } - } +// trait DeadCodeElimination extends TreeMakers { +// // TODO: non-trivial dead-code elimination +// // e.g., the following match should compile to a simple instanceof: +// // case class Ident(name: String) +// // for (Ident(name) <- ts) println(name) +// def doDCE(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): List[List[TreeMaker]] = { +// // do minimal DCE +// cases +// } +// } //// SWITCHES -- TODO: operate on Tests rather than TreeMakers trait SwitchEmission extends TreeMakers with OptimizedMatchMonadInterface { @@ -589,12 +589,12 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { } } - trait MatchOptimizations extends CommonSubconditionElimination - with DeadCodeElimination - with SwitchEmission - with OptimizedCodegen { + trait MatchOptimizer extends OptimizedCodegen + with SwitchEmission + with CommonSubconditionElimination { override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): (List[List[TreeMaker]], List[Tree]) = { - val optCases = doCSE(prevBinder, doDCE(prevBinder, cases, pt), pt) + // TODO: do CSE on result of doDCE(prevBinder, cases, pt) + val optCases = doCSE(prevBinder, cases, pt) val toHoist = ( for (treeMakers <- optCases) yield treeMakers.collect{case tm: ReusedCondTreeMaker => tm.treesToHoist} diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala index 6d6774cf20..f8d8044bdb 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala @@ -85,8 +85,8 @@ trait PatternMatching extends Transform with TypingTransformers } class OptimizingMatchTranslator(val typer: analyzer.Typer) extends MatchTranslator - with MatchOptimizations - with MatchAnalyses + with MatchOptimizer + with MatchAnalyzer with Solver } -- cgit v1.2.3 From ebaa34e84dbefd2fa60f3efd09484ce6c8d0faac Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 22 Feb 2013 16:18:57 -0800 Subject: simplify dependencies between patmat components, remove self types --- .../scala/tools/nsc/transform/patmat/Logic.scala | 9 ++++++-- .../tools/nsc/transform/patmat/MatchAnalysis.scala | 23 +++++++++++++++------ .../tools/nsc/transform/patmat/MatchCodeGen.scala | 2 +- .../nsc/transform/patmat/MatchOptimization.scala | 24 +++++----------------- .../nsc/transform/patmat/MatchTranslation.scala | 2 +- .../nsc/transform/patmat/MatchTreeMaking.scala | 12 ++++++----- .../nsc/transform/patmat/PatternMatching.scala | 20 +++++++++++------- 7 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala index 9af4800a70..a726a230ac 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala @@ -287,7 +287,11 @@ trait Logic extends Debugging { def findModelFor(f: Formula): Model def findAllModelsFor(f: Formula): List[Model] } +} +// naive CNF translation and simple DPLL solver +trait SimpleSolver extends Logic { + import PatternMatchingStats._ trait CNF extends PropositionalLogic { /** Override Array creation for efficiency (to not go through reflection). */ @@ -397,7 +401,8 @@ trait Logic extends Debugging { } } - trait DPLLSolver extends CNF { + // simple solver using DPLL + trait Solver extends CNF { // a literal is a (possibly negated) variable def Lit(sym: Sym, pos: Boolean = true) = new Lit(sym, pos) class Lit(val sym: Sym, val pos: Boolean) { @@ -516,7 +521,7 @@ trait Logic extends Debugging { } } -trait ScalaLogic extends Logic { self: PatternMatching => +trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis { trait TreesAndTypesDomain extends PropositionalLogic with CheckableTreeAndTypeAnalysis { type Type = global.Type type Tree = global.Tree diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index ed990105fd..95c3744ca1 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -125,7 +125,7 @@ trait TreeAndTypeAnalysis extends Debugging { } } -trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => +trait MatchAnalysis extends TreeAndTypeAnalysis with ScalaLogic with MatchTreeMaking { import PatternMatchingStats._ import global.{Tree, Type, Symbol, CaseDef, atPos, Select, Block, ThisType, SingleType, NoPrefix, NoType, definitions, needsOuterTest, @@ -141,7 +141,7 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => * Represent a match as a formula in propositional logic that encodes whether the match matches (abstractly: we only consider types) * */ - trait TreeMakerApproximation extends TreeMakers with PropositionalLogic with TreesAndTypesDomain with CheckableTreeAndTypeAnalysis { self: CodegenCore => + trait TreeMakerApproximation extends TreeMakers with TreesAndTypesDomain { object Test { var currId = 0 } @@ -348,7 +348,7 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => } } - trait SymbolicMatchAnalysis extends TreeMakerApproximation { self: CodegenCore => + trait MatchAnalyses extends TreeMakerApproximation { def uncheckedWarning(pos: Position, msg: String) = global.currentUnit.uncheckedWarning(pos, msg) def warn(pos: Position, ex: AnalysisBudget.Exception, kind: String) = uncheckedWarning(pos, s"Cannot check match for $kind.\n${ex.advice}") @@ -498,7 +498,7 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => // a way to construct a value that will make the match fail: a constructor invocation, a constant, an object of some type) class CounterExample { - protected[SymbolicMatchAnalysis] def flattenConsArgs: List[CounterExample] = Nil + protected[MatchAnalyses] def flattenConsArgs: List[CounterExample] = Nil def coveredBy(other: CounterExample): Boolean = this == other || other == WildcardExample } case class ValueExample(c: ValueConst) extends CounterExample { override def toString = c.toString } @@ -513,11 +513,11 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => } } case class ListExample(ctorArgs: List[CounterExample]) extends CounterExample { - protected[SymbolicMatchAnalysis] override def flattenConsArgs: List[CounterExample] = ctorArgs match { + protected[MatchAnalyses] override def flattenConsArgs: List[CounterExample] = ctorArgs match { case hd :: tl :: Nil => hd :: tl.flattenConsArgs case _ => Nil } - protected[SymbolicMatchAnalysis] lazy val elems = flattenConsArgs + protected[MatchAnalyses] lazy val elems = flattenConsArgs override def coveredBy(other: CounterExample): Boolean = other match { @@ -691,5 +691,16 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => // this is the variable we want a counter example for VariableAssignment(scrutVar).toCounterExample() } + + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit = { + unreachableCase(prevBinder, cases, pt) foreach { caseIndex => + reportUnreachable(cases(caseIndex).last.pos) + } + if (!unchecked) { + val counterExamples = exhaustive(prevBinder, cases, pt) + if (counterExamples.nonEmpty) + reportMissingCases(prevBinder.pos, counterExamples) + } + } } } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala index ce19d9cba8..57fab4eafa 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala @@ -17,7 +17,7 @@ import scala.reflect.internal.util.NoPosition * We have two modes in which to emit trees: optimized (the default) * and pure (aka "virtualized": match is parametric in its monad). */ -trait MatchCodeGen { self: PatternMatching => +trait MatchCodeGen extends Interface { import PatternMatchingStats._ import global.{nme, treeInfo, definitions, gen, Tree, Type, Symbol, NoSymbol, appliedType, NoType, MethodType, newTermName, Name, diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala index c14b4ebc3b..ebc2750a4d 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala @@ -19,7 +19,7 @@ import scala.reflect.internal.util.NoPosition * * TODO: split out match analysis */ -trait MatchOptimization { self: PatternMatching => +trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { import PatternMatchingStats._ import global.{Tree, Type, Symbol, NoSymbol, CaseDef, atPos, ConstantType, Literal, Constant, gen, EmptyTree, @@ -205,7 +205,7 @@ trait MatchOptimization { self: PatternMatching => //// DCE - trait DeadCodeElimination extends TreeMakers { self: CodegenCore => + trait DeadCodeElimination extends TreeMakers { // TODO: non-trivial dead-code elimination // e.g., the following match should compile to a simple instanceof: // case class Ident(name: String) @@ -217,7 +217,7 @@ trait MatchOptimization { self: PatternMatching => } //// SWITCHES -- TODO: operate on Tests rather than TreeMakers - trait SwitchEmission extends TreeMakers with OptimizedMatchMonadInterface { self: CodegenCore => + trait SwitchEmission extends TreeMakers with OptimizedMatchMonadInterface { import treeInfo.isGuardedCase abstract class SwitchMaker { @@ -589,25 +589,11 @@ trait MatchOptimization { self: PatternMatching => } } - - - trait MatchOptimizations extends CommonSubconditionElimination with DeadCodeElimination with SwitchEmission - with OptimizedCodegen - with SymbolicMatchAnalysis - with DPLLSolver { self: TreeMakers => - override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) = { - unreachableCase(prevBinder, cases, pt) foreach { caseIndex => - reportUnreachable(cases(caseIndex).last.pos) - } - if (!unchecked) { - val counterExamples = exhaustive(prevBinder, cases, pt) - if (counterExamples.nonEmpty) - reportMissingCases(prevBinder.pos, counterExamples) - } - + with OptimizedCodegen { + override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): (List[List[TreeMaker]], List[Tree]) = { val optCases = doCSE(prevBinder, doDCE(prevBinder, cases, pt), pt) val toHoist = ( for (treeMakers <- optCases) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala index 5d11fb6459..90c52e3eb6 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala @@ -24,7 +24,7 @@ trait MatchTranslation { self: PatternMatching => repeatedToSeq, isRepeatedParamType, getProductArgs} import global.analyzer.{ErrorUtils, formalTypes} - trait MatchTranslator extends MatchMonadInterface { self: TreeMakers with CodegenCore => + trait MatchTranslator extends TreeMakers { import typer.context // Why is it so difficult to say "here's a name and a context, give me any diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index c9285f9229..51f21780b5 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -18,7 +18,7 @@ import scala.reflect.internal.util.NoPosition * The IR is mostly concerned with sequencing, substitution, and rendering all necessary conditions, * mostly agnostic to whether we're in optimized/pure (virtualized) mode. */ -trait MatchTreeMaking { self: PatternMatching => +trait MatchTreeMaking extends MatchCodeGen with Debugging { import PatternMatchingStats._ import global.{Tree, Type, Symbol, CaseDef, atPos, settings, Select, Block, ThisType, SingleType, NoPrefix, NoType, needsOuterTest, @@ -30,9 +30,9 @@ trait MatchTreeMaking { self: PatternMatching => /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // the making of the trees /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - trait TreeMakers extends TypedSubstitution { self: CodegenCore => - def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) = - (cases, Nil) + trait TreeMakers extends TypedSubstitution with CodegenCore { + def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): (List[List[TreeMaker]], List[Tree]) + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type, matchFailGenOverride: Option[Tree => Tree], unchecked: Boolean): Option[Tree] = None @@ -550,7 +550,9 @@ trait MatchTreeMaking { self: PatternMatching => }) None else matchFailGen - val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt, unchecked) + analyzeCases(scrutSym, casesNoSubstOnly, pt, unchecked) + + val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt) val matchRes = codegen.matcher(scrut, scrutSym, pt)(cases map combineExtractors, synthCatchAll) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala index 07eed2cd94..946b0b0714 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala @@ -34,13 +34,14 @@ import scala.reflect.internal.util.Position * - recover GADT typing by locally inserting implicit witnesses to type equalities derived from the current case, and considering these witnesses during subtyping (?) * - recover exhaustivity/unreachability of user-defined extractors by partitioning the types they match on using an HList or similar type-level structure */ -trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL +trait PatternMatching extends Transform with TypingTransformers with Debugging with Interface with MatchTranslation with MatchTreeMaking with MatchCodeGen with ScalaLogic + with SimpleSolver with MatchAnalysis with MatchOptimization { import global._ @@ -78,15 +79,20 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } } - class PureMatchTranslator(val typer: analyzer.Typer, val matchStrategy: Tree) extends MatchTranslator with TreeMakers with PureCodegen - class OptimizingMatchTranslator(val typer: analyzer.Typer) extends MatchTranslator with TreeMakers with MatchOptimizations + class PureMatchTranslator(val typer: analyzer.Typer, val matchStrategy: Tree) extends MatchTranslator with PureCodegen { + def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type) = (cases, Nil) + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit = {} + } + + class OptimizingMatchTranslator(val typer: analyzer.Typer) extends MatchTranslator + with MatchOptimizations + with MatchAnalyses + with Solver } -trait HasGlobal { +trait Debugging { val global: Global -} -trait Debugging extends HasGlobal { // TODO: the inliner fails to inline the closures to debug.patmat unless the method is nested in an object object debug { val printPatmat = global.settings.Ypatmatdebug.value @@ -94,7 +100,7 @@ trait Debugging extends HasGlobal { } } -trait Interface { self: ast.TreeDSL with HasGlobal => +trait Interface extends ast.TreeDSL { import global.{newTermName, analyzer, Type, ErrorType, Symbol, Tree} import analyzer.Typer -- cgit v1.2.3 From 2cf6c5d7e5cfbd60958eac0a545f5c2978a8e5cd Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 1 Mar 2013 18:23:57 -0800 Subject: [port] SI-7183 Disable unreachability for withFilter matches. This is a forward port of #2168 (originally for 2.10.1, but the pattern matcher has since been refactored in 2.10.x.) --- .../tools/nsc/transform/patmat/MatchAnalysis.scala | 10 ++++--- .../nsc/transform/patmat/MatchTreeMaking.scala | 33 ++++++++++++++-------- .../nsc/transform/patmat/PatternMatching.scala | 2 +- test/files/pos/t7183.flags | 1 + test/files/pos/t7183.scala | 13 +++++++++ 5 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 test/files/pos/t7183.flags create mode 100644 test/files/pos/t7183.scala diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index 74b932e173..d9f93f27b6 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -691,11 +691,13 @@ trait MatchAnalysis extends MatchApproximation { VariableAssignment(scrutVar).toCounterExample() } - def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit = { - unreachableCase(prevBinder, cases, pt) foreach { caseIndex => - reportUnreachable(cases(caseIndex).last.pos) + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit = { + if (!suppression.unreachable) { + unreachableCase(prevBinder, cases, pt) foreach { caseIndex => + reportUnreachable(cases(caseIndex).last.pos) + } } - if (!unchecked) { + if (!suppression.exhaustive) { val counterExamples = exhaustive(prevBinder, cases, pt) if (counterExamples.nonEmpty) reportMissingCases(prevBinder.pos, counterExamples) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index 51f21780b5..202f3444f8 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -23,16 +23,21 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { import global.{Tree, Type, Symbol, CaseDef, atPos, settings, Select, Block, ThisType, SingleType, NoPrefix, NoType, needsOuterTest, ConstantType, Literal, Constant, gen, This, EmptyTree, map2, NoSymbol, Traverser, - Function, Typed, treeInfo, TypeRef, DefTree} + Function, Typed, treeInfo, TypeRef, DefTree, Ident, nme} import global.definitions.{SomeClass, AnyRefClass, UncheckedClass, BooleanClass} + final case class Suppression(exhaustive: Boolean, unreachable: Boolean) + object Suppression { + val NoSuppression = Suppression(false, false) + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // the making of the trees /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// trait TreeMakers extends TypedSubstitution with CodegenCore { def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): (List[List[TreeMaker]], List[Tree]) - def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type, matchFailGenOverride: Option[Tree => Tree], unchecked: Boolean): Option[Tree] = None @@ -522,18 +527,24 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { def matchFailGen = (matchFailGenOverride orElse Some(CODE.MATCHERROR(_: Tree))) debug.patmat("combining cases: "+ (casesNoSubstOnly.map(_.mkString(" >> ")).mkString("{", "\n", "}"))) - val (unchecked, requireSwitch) = - if (settings.XnoPatmatAnalysis.value) (true, false) + val (suppression, requireSwitch): (Suppression, Boolean) = + if (settings.XnoPatmatAnalysis.value) (Suppression.NoSuppression, false) else scrut match { - case Typed(_, tpt) => - (tpt.tpe hasAnnotation UncheckedClass, - // matches with two or fewer cases need not apply for switchiness (if-then-else will do) - treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0) + case Typed(tree, tpt) => + val suppressExhaustive = tpt.tpe hasAnnotation UncheckedClass + val supressUnreachable = tree match { + case Ident(name) if name startsWith nme.CHECK_IF_REFUTABLE_STRING => true // SI-7183 don't warn for withFilter's that turn out to be irrefutable. + case _ => false + } + val suppression = Suppression(suppressExhaustive, supressUnreachable) + // matches with two or fewer cases need not apply for switchiness (if-then-else will do) + val requireSwitch = treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0 + (suppression, requireSwitch) case _ => - (false, false) + (Suppression.NoSuppression, false) } - emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, unchecked).getOrElse{ + emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, suppression.exhaustive).getOrElse{ if (requireSwitch) typer.context.unit.warning(scrut.pos, "could not emit switch for @switch annotated match") if (casesNoSubstOnly nonEmpty) { @@ -550,7 +561,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { }) None else matchFailGen - analyzeCases(scrutSym, casesNoSubstOnly, pt, unchecked) + analyzeCases(scrutSym, casesNoSubstOnly, pt, suppression) val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala index f8d8044bdb..df4e699620 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala @@ -81,7 +81,7 @@ trait PatternMatching extends Transform with TypingTransformers class PureMatchTranslator(val typer: analyzer.Typer, val matchStrategy: Tree) extends MatchTranslator with PureCodegen { def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type) = (cases, Nil) - def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit = {} + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit = {} } class OptimizingMatchTranslator(val typer: analyzer.Typer) extends MatchTranslator diff --git a/test/files/pos/t7183.flags b/test/files/pos/t7183.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t7183.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/pos/t7183.scala b/test/files/pos/t7183.scala new file mode 100644 index 0000000000..7647c1634b --- /dev/null +++ b/test/files/pos/t7183.scala @@ -0,0 +1,13 @@ +class A +object A { + def unapply(a: A): Some[A] = Some(a) // Change return type to Option[A] and the warning is gone +} + +object Test { + for (A(a) <- List(new A)) yield a // spurious dead code warning. +} + +// List(new A()).withFilter(((check$ifrefutable$2) => check$ifrefutable$2: @scala.unchecked match { +// case A((a @ _)) => true +// case _ => false // this is dead code, but it's compiler generated. +// })) -- cgit v1.2.3 From ad6983518dd6860564d16f5b6e99178db3cff7a2 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 5 Mar 2013 10:27:41 +0100 Subject: SI-7215 Fix transpose of an empty Array[Array[T]]. --- .../scala/collection/mutable/ArrayOps.scala | 23 ++++++++++++---------- test/files/run/t7215.scala | 6 ++++++ 2 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 test/files/run/t7215.scala diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index bb938a7aeb..25ba7e4ce6 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -76,18 +76,21 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza * @return An array obtained by replacing elements of this arrays with rows the represent. */ def transpose[U](implicit asArray: T => Array[U]): Array[Array[U]] = { - def mkRowBuilder() = Array.newBuilder(ClassTag[U](arrayElementClass(elementClass))) - val bs = asArray(head) map (_ => mkRowBuilder()) - for (xs <- this) { - var i = 0 - for (x <- asArray(xs)) { - bs(i) += x - i += 1 + val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass)) + if (isEmpty) bb.result() + else { + def mkRowBuilder() = Array.newBuilder(ClassTag[U](arrayElementClass(elementClass))) + val bs = asArray(head) map (_ => mkRowBuilder()) + for (xs <- this) { + var i = 0 + for (x <- asArray(xs)) { + bs(i) += x + i += 1 + } } + for (b <- bs) bb += b.result() + bb.result() } - val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass)) - for (b <- bs) bb += b.result - bb.result } def seq = thisCollection diff --git a/test/files/run/t7215.scala b/test/files/run/t7215.scala new file mode 100644 index 0000000000..c93e97f9c8 --- /dev/null +++ b/test/files/run/t7215.scala @@ -0,0 +1,6 @@ +object Test extends App { + List[List[Any]]().transpose.isEmpty + Array[Array[Any]]().transpose.isEmpty + Vector[Vector[Any]]().transpose.isEmpty + Stream[Stream[Any]]().transpose.isEmpty +} -- cgit v1.2.3 From acd74cae0935d79cedbeb2bec719174b7cf54e5e Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 5 Mar 2013 09:57:35 +0100 Subject: SI-7214 outer check based on dealiased pattern type. A Typed Pattern (_: T) is more than `.isInstanceOf`: if `T` is a path dependent type, the scrutinee's $outer reference is also compared against the prefix of `T`. The code that synthesises this is split into two places. `needsOuterCheck` determines whether to add this check, based on the type `T`, and the type of the scrutinee. If it gives the go-ahead, `treeCondStrategy.outerCheck` synthesizes the check. The new test case demonstrates the problems caused by the failure to dealias in `needsOuterCheck`: it could either wrongly lead to synthesis of an outer test (which would crash), or wrongly omit the outer test (meaning overly liberal matching.) A simple `dealias` remedies this. `dealiasWiden` is *not* appropriate here; we need to keep hold of singleton types. I'll also note that there is already a little slack between these methods, as commented: > ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` > by `Select(q, > outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix` > if there's an outer accessor, otherwise the condition becomes `true` > TODO: can we improve needsOuterTest so there's always an outerAccessor? So this is probably a fragile area that warrants a careful review with a view to design improvements. --- src/reflect/scala/reflect/internal/Types.scala | 4 +- test/files/run/t7214.scala | 57 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t7214.scala diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 76d6ec80be..81e0457916 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -5354,7 +5354,9 @@ trait Types extends api.Types { self: SymbolTable => case _ => NoType } - patType match { + // See the test for SI-7214 for motivation for dealias. Later `treeCondStrategy#outerTest` + // generates an outer test based on `patType.prefix` with automatically dealises. + patType.dealias match { case TypeRef(pre, sym, args) => val pre1 = maybeCreateDummyClone(pre, sym) (pre1 ne NoType) && isPopulated(copyTypeRef(patType, pre1, sym, args), selType) diff --git a/test/files/run/t7214.scala b/test/files/run/t7214.scala new file mode 100644 index 0000000000..ff1ea8082d --- /dev/null +++ b/test/files/run/t7214.scala @@ -0,0 +1,57 @@ +// pattern matcher crashes here trying to synthesize an uneeded outer test. +// no-symbol does not have an owner +// at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49) +// at scala.tools.nsc.Global.abort(Global.scala:253) +// at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3248) +// at scala.reflect.internal.Symbols$Symbol.effectiveOwner(Symbols.scala:678) +// at scala.reflect.internal.Symbols$Symbol.isDefinedInPackage(Symbols.scala:664) +// at scala.reflect.internal.TreeGen.mkAttributedSelect(TreeGen.scala:188) +// at scala.reflect.internal.TreeGen.mkAttributedRef(TreeGen.scala:124) +// at scala.tools.nsc.ast.TreeDSL$CODE$.REF(TreeDSL.scala:308) +// at scala.tools.nsc.typechecker.PatternMatching$TreeMakers$TypeTestTreeMaker$treeCondStrategy$.outerTest(PatternMatching.scala:1209) +class Crash { + type Alias = C#T + + val c = new C + val t = new c.T + + // Crash via a Typed Pattern... + (t: Any) match { + case e: Alias => + } + + // ... or via a Typed Extractor Pattern. + object Extractor { + def unapply(a: Alias): Option[Any] = None + } + (t: Any) match { + case Extractor() => + case _ => + } + + // checking that correct outer tests are applied when + // aliases for path dependent types are involved. + val c2 = new C + type CdotT = c.T + type C2dotT = c2.T + + val outerField = t.getClass.getDeclaredFields.find(_.getName contains ("outer")).get + outerField.setAccessible(true) + + (t: Any) match { + case _: C2dotT => + println(s"!!! wrong match. t.outer=${outerField.get(t)} / c2 = $c2") // this matches on 2.10.0 + case _: CdotT => + case _ => + println(s"!!! wrong match. t.outer=${outerField.get(t)} / c = $c") + } +} + +class C { + class T +} + +object Test extends App { + new Crash +} + -- cgit v1.2.3