AnalysisSession
The Analysis API over the running game: a standalone session whose one library module is the same widened classpath ReplHost compiles snippets against. Ask it what a name means; ReplHost is what runs it.
The two must see the identical classpath or an answer here can contradict what an eval does — hence the widened list, not a freshly enumerated one: private / protected / internal members are callable in a snippet only because the access-widen overlay opened them, and analysis has to be told the same story.
Everything is lazy. Building the session indexes the whole classpath, so the first call is expensive and every later one is free; drive it off-tick.
Properties
The session, built on first access and then kept — the game's classpath is fixed by the time one exists, so there is nothing that could invalidate it. lazy retries rather than caching a failed build.
This class's own loader, exactly as ReplHost finds it — repl.impl.* is masking-owned. Null outside a masking launch (unit tests), where there is no parent kotlin to pin against either.
Functions
An in-memory snippet. Named SCRIPT_EXT for the same reason an eval's source is: any extension but .kt is the whole of what puts the parser into script mode, which is what lets top-level statements sit beside declarations.
Teach the session the same script shape the compiler uses, so a snippet's implicit ScriptScope receiver and its bare Patches / Probe imports resolve here too. McpScriptRegistrar is reused as-is: the relocated Analysis API and the embedded compiler share one FirExtensionRegistrar class.
The library module's content scope, built here rather than left to the module builder: its default routes through VirtualFileUtil.toNioPathOrNull, and intellij-core ships a same-named facade without that method — it survives only in the @Metadata proto, so the call finds nothing and throws NoSuchMethodError the first time a module carries binary virtual files.
Archives opened here, everything else left as a plain root. A binary root is read back by dispatching on endsWith("jar"), so an archive named otherwise — nested-jar extraction leaves *.jar.tmp and friends — would resolve as one opaque file with none of its classes visible. An eval is unaffected: the compiler indexes the same list its own way.