class IMain extends Repl with Imports with PresentationCompilation
An interpreter for Scala code.
The main public entry points are compile(), interpret(), and bind(). The compile() method loads a complete Scala file. The interpret() method executes one line of Scala code at the request of the user. The bind() method binds an object to a variable that can then be used by later interpreted code.
The overall approach is based on compiling the requested code and then using a Java classloader and Java reflection to run the code and access its results.
In more detail, a single compiler instance is used to accumulate all successfully compiled or interpreted Scala code. To "interpret" a line of code, the compiler generates a fresh object that includes the line of code and which has public member(s) to export all variables defined by that code. To extract the result of an interpreted line to show the user, a second "result object" is created which imports the variables exported by the above object and then exports members called "$eval" and "$print". To accommodate user expressions that read from variables or methods defined in previous statements, "import" statements are used.
This interpreter shares the strengths and weaknesses of using the full compiler-to-Java. The main strength is that interpreted code behaves exactly as does compiled code, including running at full speed. The main weakness is that redefining classes and methods is not handled properly, because rebinding at the Java level is technically difficult.
- Source
- IMain.scala
- Alphabetic
- By Inheritance
- IMain
- PresentationCompilation
- Imports
- Repl
- ReplCore
- AnyRef
- Any
- by any2stringadd
- by StringFormat
- by Ensuring
- by ArrowAssoc
- Hide All
- Show All
- Public
- All
Instance Constructors
- new IMain(interpreterSettings: Settings, reporter: ReplReporter)
- new IMain(settings: Settings, parentClassLoaderOverride: Option[ClassLoader], compilerSettings: Settings, reporter: ReplReporter)
Type Members
- abstract class PhaseDependentOps extends AnyRef
-
class
ReadEvalPrint extends AnyRef
Here is where we:
Here is where we:
1) Read some source code, and put it in the "read" object. 2) Evaluate the read object, and put the result in the "eval" object. 3) Create a String for human consumption, and put it in the "print" object.
Read! Eval! Print! Some of that not yet centralized here.
- implicit class ReplTypeOps extends AnyRef
-
class
Request extends ReplRequest
One line of code submitted by the user for interpretation
-
type
Setting = Settings.Setting
- Definition Classes
- Repl
-
type
SettingSet = Set[Setting]
- Definition Classes
- Repl
-
case class
ComputedImports(header: String, prepend: String, append: String, access: String) extends Product with Serializable
Compute imports that allow definitions from previous requests to be visible in a new request.
Compute imports that allow definitions from previous requests to be visible in a new request. Returns three or four pieces of related code:
0. Header code fragment that should go at the beginning of the compilation unit, specifically, import Predef.
- An initial code fragment that should go before the code of the new request.
2. A code fragment that should go after the code of the new request.
3. An access path which can be traversed to access any bindings inside code wrapped by #1 and #2 .
The argument is a set of Names that need to be imported.
Limitations: This method is not as precise as it could be. (1) It does not process wildcard imports to see what exactly they import. (2) If it imports any names from a request, it imports all of them, which is not really necessary. (3) It imports multiple same-named implicits, but only the last one imported is actually usable.
- Definition Classes
- Imports
-
abstract
class
PresentationCompileResult extends PresentationCompilationResult
- Definition Classes
- PresentationCompilation
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
- Definition Classes
- AnyRef → Any
- def +(other: String): String
- def ->[B](y: B): (IMain, B)
-
final
def
==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
addUrlsToClassPath(urls: URL*): Unit
Adds all specified jars to the compile and runtime classpaths.
- def allDefinedNames: List[Global.Name]
- def allHandlers: collection.immutable.List[(memberHandlers)#MemberHandler]
-
def
allImportedNames: collection.immutable.List[Global.Name]
- Definition Classes
- Imports
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
- def backticked(s: String): String
-
final
def
beQuietDuring(body: ⇒ Unit): Unit
The reporter will not print results during execution of
body
. - def bind[T](name: String, value: T)(implicit arg0: reflect.api.JavaUniverse.TypeTag[T], arg1: ClassTag[T]): Result
- def bind(p: NamedParam): Result
-
def
bind(name: String, boundType: String, value: Any, modifiers: List[String] = Nil): Result
Bind a specified name to a specified value.
Bind a specified name to a specified value. The name may later be used by expressions passed to interpret.
A fresh
ReadEvalPrint
, which defines aline
package, is used to compile a customeval
object that wraps the bound value.If the bound value is successfully installed, then bind the name by interpreting
val name = $line42.$eval.value
.- name
the variable name to bind
- boundType
the type of the variable, as a string
- value
the object value to bind to it
- returns
an indication of whether the binding succeeded
-
def
bindValue(name: String, value: Any): Result
Bind a specified
name
to a specifiedvalue
.Bind a specified
name
to a specifiedvalue
. The type is derived from the run-time class of the value.- Definition Classes
- ReplCore
- def classLoader: AbstractFileClassLoader
- def classOfTerm(id: String): Option[Class[_]]
- def classPathString: String
- def cleanMemberDecl(owner: Global.Symbol, member: Global.Name): Global.Type
- def cleanTypeAfterTyper(sym: ⇒ Global.Symbol): Global.Type
- def clearExecutionWrapper(): Unit
-
def
clone(): AnyRef
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )
-
def
close(): Unit
This instance is no longer needed, so release any resources it is using.
- def compile(line: String, synthetic: Boolean): Either[Result, Request]
-
def
compileSources(sources: SourceFile*): Boolean
Compile an nsc SourceFile.
- def compileSourcesKeepingRun(sources: SourceFile*): (Boolean, Run)
-
def
compileString(code: String): Boolean
Compile a string.
- def compilerClasspath: Seq[URL]
- def dealiasNonPublic(tp: Global.Type): Global.Type
- def debugging[T](msg: String)(res: T): T
- def definedSymbolList: collection.immutable.List[Global.Symbol]
- def definedTerms: collection.immutable.List[Global.TermName]
- def definedTypes: List[String]
- def directBind[T](name: String, value: T)(implicit arg0: reflect.api.JavaUniverse.TypeTag[T], arg1: ClassTag[T]): Result
- def directBind(p: NamedParam): Result
- def directBind(name: String, boundType: String, value: Any): Result
- final def ensureClassLoader(): Unit
- def ensuring(cond: (IMain) ⇒ Boolean, msg: ⇒ Any): IMain
- def ensuring(cond: (IMain) ⇒ Boolean): IMain
- def ensuring(cond: Boolean, msg: ⇒ Any): IMain
- def ensuring(cond: Boolean): IMain
-
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- def executionWrapper: String
-
def
finalize(): Unit
- Definition Classes
- IMain → AnyRef
- def flatPath(sym: Global.Symbol): String
- def formatted(fmtstr: String): String
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def getClassIfDefined(path: String): Global.Symbol
- def getModuleIfDefined(path: String): Global.Symbol
- lazy val global: Global
-
def
hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
def
implicitSymbolsBySource: List[(Global.Symbol, List[Global.Symbol])]
- Definition Classes
- Imports
- def implicitsCommandInternal(line: String): (List[String], String)
- def importHandlers: collection.immutable.List[(memberHandlers)#ImportHandler]
-
def
importedSymbols: collection.immutable.List[Global.Symbol]
- Definition Classes
- Imports
-
def
importedSymbolsBySource: List[(Global.Symbol, List[Global.Symbol])]
Tuples of (source, imported symbols) in the order they were imported.
Tuples of (source, imported symbols) in the order they were imported.
- Definition Classes
- Imports
-
def
importedTermSymbols: collection.immutable.List[Global.TermSymbol]
- Definition Classes
- Imports
-
def
importsCode(wanted: Set[Global.Name], request: Request, definesClass: Boolean, generousImports: Boolean): ComputedImports
- Attributes
- protected
- Definition Classes
- Imports
- def importsCommandInternal(tokens: List[String]): List[String]
- def initializeCompiler(): Boolean
- def initializeComplete: Boolean
- def interpret(line: String, synthetic: Boolean): Result
-
def
interpret(line: String): Result
Interpret one line of input.
Interpret one line of input. All feedback, including parse errors and evaluation results, are printed via the supplied compiler's reporter. Values defined are available for future interpreted strings.
The return value is whether the line was interpreter successfully, e.g. that there were no parse errors.
- def interpretSynthetic(line: String): Result
- lazy val isClassBased: Boolean
-
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
def
isPackaged(line: String): Boolean
Does code start with a package definition?
- def kindCommandInternal(typeString: String, verbose: Boolean): String
-
def
languageSymbols: collection.immutable.List[Global.Symbol]
- Definition Classes
- Imports
-
def
languageWildcardHandlers: collection.immutable.List[(memberHandlers)#ImportHandler]
- Definition Classes
- Imports
-
def
languageWildcardSyms: List[Global.Symbol]
Symbols whose contents are language-defined to be imported.
Symbols whose contents are language-defined to be imported.
- Definition Classes
- Imports
- def lastRequest: Request
- def lastWarnings: List[(Global.Position, String)]
- lazy val memberHandlers: MemberHandlers { val intp: IMain.this.type }
-
def
mostRecentVar: String
Returns the name of the most recent interpreter result.
- def namedDefinedTerms: List[String]
- def namedParam[T](name: String, value: T)(implicit arg0: reflect.api.JavaUniverse.TypeTag[T], arg1: ClassTag[T]): NamedParam
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
newPresentationCompiler(): interactive.Global
Create an instance of the presentation compiler with a classpath comprising the REPL's configured classpath and the classes output by previously compiled REPL lines.
Create an instance of the presentation compiler with a classpath comprising the REPL's configured classpath and the classes output by previously compiled REPL lines.
You may directly interact with this compiler from any thread, although you must not access it concurrently from multiple threads.
You may downcast the
reporter
toStoreReporter
to access type errors.- Definition Classes
- PresentationCompilation
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
def
onlyTerms(xs: List[Global.Name]): List[Global.TermName]
- Attributes
- protected
-
def
onlyTypes(xs: List[Global.Name]): List[Global.TypeName]
- Attributes
- protected
- def originalPath(sym: Global.Symbol): String
- def originalPath(name: Global.Name): String
- def originalPath(name: String): String
-
def
parentClassLoader: ClassLoader
Parent classloader.
Parent classloader. Overridable.
- Attributes
- protected
-
def
parse(line: String): Either[Result, (List[Global.Tree], Global.Position)]
Parse a line into and return parsing result (error, incomplete or success with list of trees)
- lazy val power: Power[StdReplVals]
-
def
presentationCompile(cursor: Int, buf: String): Either[Result, PresentationCompileResult]
Typecheck a line of REPL input, suitably wrapped with "interpreter wrapper" objects/classes, with the presentation compiler.
Typecheck a line of REPL input, suitably wrapped with "interpreter wrapper" objects/classes, with the presentation compiler. The result of this method gives access to the typechecked tree and to autocompletion suggestions.
The caller is responsible for calling PresentationCompileResult#cleanup to dispose of the compiler instance.
- Definition Classes
- PresentationCompilation
- def prevRequestList: collection.immutable.List[Request]
- def quietBind(p: NamedParam): Result
- def quietRun(code: String): Result
-
val
readInstanceName: String
For class based repl mode we use an .INSTANCE accessor.
- def readRootPath(readPath: String): Global.Symbol
- def rebind(p: NamedParam): Result
- def recordRequest(req: Request): Unit
-
def
replClass: Class[_]
- Attributes
- protected
- def replScope: Global.Scope
- val reporter: ReplReporter
- def requestDefining(name: String): Option[Request]
-
def
reset(): Unit
Reset this interpreter, forgetting all user-specified requests.
- def resetClassLoader(): Unit
- def runtimeClassAndTypeOfTerm(id: String): Option[(Class[_], Global.Type)]
- lazy val runtimeMirror: Mirror
- def runtimeTypeOfTerm(id: String): Global.Type
-
def
sessionImportedSymbols: collection.immutable.List[Global.Symbol]
- Definition Classes
- Imports
-
def
sessionWildcards: List[Global.Type]
Types which have been wildcard imported, such as: val x = "abc" ; import x._ // type java.lang.String import java.lang.String._ // object java.lang.String
Types which have been wildcard imported, such as: val x = "abc" ; import x._ // type java.lang.String import java.lang.String._ // object java.lang.String
Used by tab completion.
XXX right now this gets import x._ and import java.lang.String._, but doesn't figure out import String._. There's a lot of ad hoc scope twiddling which should be swept away in favor of digging into the compiler scopes.
- Definition Classes
- Imports
-
def
setContextClassLoader(): Unit
Set the current Java "context" class loader to this interpreter's class loader
- def setExecutionWrapper(code: String): Unit
- val settings: Settings
- def showDirectory: String
- def symbolDefString(sym: Global.Symbol): String
- def symbolOfIdent(id: String): Global.Symbol
- def symbolOfLine(code: String): Global.Symbol
- def symbolOfName(id: Global.Name): Global.Symbol
- def symbolOfTerm(id: String): Global.Symbol
- def symbolOfType(id: String): Global.Symbol
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
def
toString(): String
- Definition Classes
- AnyRef → Any
- def translateEnclosingClass(n: String): Option[String]
- def translateOriginalPath(p: String): String
- def translatePath(path: String): Option[String]
-
def
translateSimpleResource(path: String): Option[String]
If path represents a class resource in the default package, see if the corresponding symbol has a class file that is a REPL artifact residing at a different resource path.
If path represents a class resource in the default package, see if the corresponding symbol has a class file that is a REPL artifact residing at a different resource path. Translate X.class to $line3/$read$$iw$$iw$X.class.
-
def
tryTwice(op: ⇒ Global.Symbol): Global.Symbol
It's a bit of a shotgun approach, but for now we will gain in robustness.
It's a bit of a shotgun approach, but for now we will gain in robustness. Try a symbol-producing operation at phase typer, and if that is NoSymbol, try again at phase flatten. I'll be able to lose this and run only from exitingTyper as soon as I figure out exactly where a flat name is sneaking in when calculating imports.
-
def
typeCommandInternal(expr: String, verbose: Boolean): (String, String)
TODO - -n normalize -l label with case class parameter names -c complete - leave nothing out
- def typeOfExpression(expr: String, silent: Boolean = true): Global.Type
- def typeOfTerm(id: String): Global.Type
- def unqualifiedIds: List[String]
- def updateSettings(arguments: List[String]): Boolean
- def userSetSettings: SettingSet
- def valueOfTerm(id: String): Option[Any]
- def visibleSettings: SettingSet
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )
- def withLabel[A](temp: String)(body: ⇒ A): A
- def withoutWarnings[T](body: ⇒ T): T
- def →[B](y: B): (IMain, B)
- object deconstruct extends StructuredTypeStrings
- object exprTyper extends ExprTyper
- object flatOp extends PhaseDependentOps
- object naming extends Naming
- object replOutput extends ReplOutput
- object typerOp extends PhaseDependentOps
The Scala compiler and reflection APIs.