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.

Types

Link copied to clipboard
class Built(val session: StandaloneAnalysisAPISession, val context: KaSourceModule)

Handed out together: a KtFile's context module must belong to the session that will analyze it, so neither half is meaningful without the other.

Link copied to clipboard
class Cursor(val file: KtFile, val element: KtElement, val prefix: String)

Where a query is being asked. element is what to hand analyze; filter candidates by prefix, since the element's own name carries the placeholder rather than what was typed.

Link copied to clipboard
class Editor(val file: KtFile)

One editing context — a connection, a pane, whatever owns a caret.

Properties

Link copied to clipboard
val context: KaSourceModule

What a snippet is analyzed against: an empty source module whose dependencies are the game's widened classpath and the running JDK.

Link copied to clipboard

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.

Link copied to clipboard

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.

Link copied to clipboard
val project: Project

Functions

Link copied to clipboard
Link copied to clipboard

A fresh editing context over code. Hold one per caret, and close it when that caret is gone.

Link copied to clipboard
private fun newFile(code: String): KtFile

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.

Link copied to clipboard
private fun registerScriptExtensions(project: Project, owner: Disposable)

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.

Link copied to clipboard
private fun rootScope(project: Project, roots: List<Path>, opened: List<VirtualFile>, environment: CoreApplicationEnvironment): GlobalSearchScope

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.

Link copied to clipboard
private fun splitRoots(widened: List<File>, jarFs: VirtualFileSystem): Pair<List<Path>, List<VirtualFile>>

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.