in rsc/src/main/scala/rsc/outline/Scheduler.scala [650:716]
private def stats(level: Level, env: Env, trees: List[Stat]): Env = {
var essentialObjects: LinkedHashSet[Symbol] = null
trees.foreach {
case outline: DefnClass if outline.hasCase || outline.hasDefaultParams =>
if (essentialObjects == null) {
essentialObjects = new LinkedHashSet[Symbol]
}
val ownerSym = if (level == SourceLevel) EmptyPackage else env.owner.sym
val classSym = TypeSymbol(ownerSym, outline.id.value)
outline.id.sym = classSym
symtab.outlines.put(classSym, outline)
essentialObjects.add(classSym.companionObject)
case _ =>
()
}
var currEnv = env
def outlineEnv(currEnv: Env, tree: Outline): Env = {
tree match {
case _: DefnPackage | _: DefnPackageObject => currEnv
case _ if level == SourceLevel => symtab.scopes(EmptyPackage) :: currEnv
case _ => currEnv
}
}
trees.foreach {
case tree: Import =>
tree.importers.foreach { importer =>
val scope = ImporterScope(importer)
todo.add(currEnv, scope)
currEnv = scope :: currEnv
}
case tree: Outline =>
val treeEnv = outlineEnv(currEnv, tree)
apply(treeEnv, tree)
tree match {
case tree: DefnClass if tree.hasImplicit =>
// When we encounter an implicit class, we must synthesize an implicit factory method
// of the same name located in the same scope.
synthesizer.implicitClassConversion(currEnv, tree)
case _: DefnCtor | _: PrimaryCtor =>
()
case tree: DefnDef if tree.hasDefaultParams =>
synthesizer.defaultGetters(treeEnv, tree)
case _ =>
()
}
case tree: DefnPat =>
apply(currEnv, tree)
case _ =>
()
}
if (essentialObjects != null) {
val essentialObjectsIt = essentialObjects.iterator
while (essentialObjectsIt.hasNext) {
val objectSym = essentialObjectsIt.next()
val needsSynthesis = !symtab.outlines.contains(objectSym)
if (needsSynthesis) {
val companionClassSym = objectSym.companionClass
val classTree = symtab.outlines(companionClassSym).asInstanceOf[DefnClass]
val env = outlineEnv(currEnv, classTree)
synthesizer.syntheticCompanion(env, classTree)
}
}
}
currEnv
}