>How is the connection between source file name and symbols it defines established? In particular, what if we are trying to load symbol for A but there's no class file corresponding to it and A is defined in B.scala?

In the same way as for classfiles: The package loader enters symbols for each filename, and links the `info` of that symbol with the corresponding loader (a classfile loader, source file loader, or package loader). If the top-level symbol is defined in a file with a different name, it won't be entered ("not found"). This is the crux of the IDE limitation, requiring the folder/filename convention that Java uses.

There is a partial fix: `BrowsingLoaders` are a special loader, swapped as the package loader for the interactive compiler. It does a very fast parse phase of each file in a directory, and enters symbols for all top-level definitions (as opposed to just one symbol per file, with the name of the file). This would solve the `class A` defined in `B.scala`, as long as the folder/package match.

>What does it mean out-of-band process exactly? Does it mean that we parse the file, then we apply namer/typer to that file and all other subsequent phases? Do we really execute tree transformers from all previous phases until current one?

No, it never goes farther than typer. The whole code is pretty short, check `Global.compileLate(CompilationUnit)`. It does the minimal amount of work necessary to recover type signatures from source files.

>I realize that this mechanism is used to implement -sourcepath and thus allows us to compile Scala library. However, I wonder if the logic for this mechanism should live in SymbolLoaders. Or if we could create a separate component solely responsible for this out-of-band process and its semantics. SymbolLoaders could depend on that component.

It is not much more than those 6 lines of code.