@@ -69,6 +69,8 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
69
69
// Used in a test case.
70
70
def showDirectory () = replOutput.show(out)
71
71
72
+ lazy val isClassBased : Boolean = settings.Yreplclassbased .value
73
+
72
74
private [nsc] var printResults = true // whether to print result lines
73
75
private [nsc] var totalSilence = false // whether to print anything
74
76
private var _initializeComplete = false // compiler is initialized
@@ -310,8 +312,14 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
310
312
}
311
313
312
314
def originalPath (name : String ): String = originalPath(TermName (name))
313
- def originalPath (name : Name ): String = typerOp path name
314
- def originalPath (sym : Symbol ): String = typerOp path sym
315
+ def originalPath (name : Name ): String = translateOriginalPath(typerOp path name)
316
+ def originalPath (sym : Symbol ): String = translateOriginalPath(typerOp path sym)
317
+ /** For class based repl mode we use an .INSTANCE accessor. */
318
+ val readInstanceName = if (isClassBased) " .INSTANCE" else " "
319
+ def translateOriginalPath (p : String ): String = {
320
+ val readName = java.util.regex.Matcher .quoteReplacement(sessionNames.read)
321
+ p.replaceFirst(readName, readName + readInstanceName)
322
+ }
315
323
def flatPath (sym : Symbol ): String = flatOp shift sym.javaClassName
316
324
317
325
def translatePath (path : String ) = {
@@ -758,11 +766,13 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
758
766
// object and we can do that much less wrapping.
759
767
def packageDecl = " package " + packageName
760
768
769
+ def pathToInstance (name : String ) = packageName + " ." + name + readInstanceName
761
770
def pathTo (name : String ) = packageName + " ." + name
762
771
def packaged (code : String ) = packageDecl + " \n\n " + code
763
772
764
- def readPath = pathTo(readName)
765
- def evalPath = pathTo(evalName)
773
+ def readPathInstance = pathToInstance(readName)
774
+ def readPath = pathTo(readName)
775
+ def evalPath = pathTo(evalName)
766
776
767
777
def call (name : String , args : Any * ): AnyRef = {
768
778
val m = evalMethod(name)
@@ -802,7 +812,8 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
802
812
/** The innermost object inside the wrapper, found by
803
813
* following accessPath into the outer one.
804
814
*/
805
- def resolvePathToSymbol (accessPath : String ): Symbol = {
815
+ def resolvePathToSymbol (fullAccessPath : String ): Symbol = {
816
+ val accessPath = fullAccessPath.stripPrefix(readPath)
806
817
val readRoot = readRootPath(readPath) // the outermost wrapper
807
818
(accessPath split '.' ).foldLeft(readRoot : Symbol ) {
808
819
case (sym, " " ) => sym
@@ -849,7 +860,6 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
849
860
def defines = defHandlers flatMap (_.definedSymbols)
850
861
def imports = importedSymbols
851
862
def value = Some (handlers.last) filter (h => h.definesValue) map (h => definedSymbols(h.definesTerm.get)) getOrElse NoSymbol
852
-
853
863
val lineRep = new ReadEvalPrint ()
854
864
855
865
private var _originalLine : String = null
@@ -858,6 +868,11 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
858
868
859
869
/** handlers for each tree in this request */
860
870
val handlers : List [MemberHandler ] = trees map (memberHandlers chooseHandler _)
871
+ val definesClass = handlers.exists {
872
+ case _ : ClassHandler => true
873
+ case _ => false
874
+ }
875
+
861
876
def defHandlers = handlers collect { case x : MemberDefHandler => x }
862
877
863
878
/** list of names used by this expression */
@@ -875,13 +890,13 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
875
890
* append to objectName to access anything bound by request.
876
891
*/
877
892
lazy val ComputedImports (importsPreamble, importsTrailer, accessPath) =
878
- exitingTyper(importsCode(referencedNames.toSet, ObjectSourceCode ))
893
+ exitingTyper(importsCode(referencedNames.toSet, ObjectSourceCode , definesClass ))
879
894
880
895
/** the line of code to compute */
881
896
def toCompute = line
882
897
883
898
/** The path of the value that contains the user code. */
884
- def fullAccessPath = s " ${lineRep.readPath }$accessPath"
899
+ def fullAccessPath = s " ${lineRep.readPathInstance }$accessPath"
885
900
886
901
/** The path of the given member of the wrapping instance. */
887
902
def fullPath (vname : String ) = s " $fullAccessPath.` $vname` "
@@ -911,21 +926,24 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
911
926
def postwrap : String
912
927
}
913
928
914
- private class ObjectBasedWrapper extends Wrapper {
929
+ class ObjectBasedWrapper extends Wrapper {
915
930
def preambleHeader = " object %s {"
916
931
917
932
def postamble = importsTrailer + " \n }"
918
933
919
934
def postwrap = " }\n "
920
935
}
921
936
922
- private class ClassBasedWrapper extends Wrapper {
923
- def preambleHeader = " class %s extends Serializable {"
937
+ class ClassBasedWrapper extends Wrapper {
938
+ def preambleHeader = " class %s extends Serializable { "
924
939
925
940
/** Adds an object that instantiates the outer wrapping class. */
926
- def postamble = s """ $importsTrailer
941
+ def postamble = s """
942
+ | $importsTrailer
943
+ |}
944
+ |object ${lineRep.readName} {
945
+ | val INSTANCE = new ${lineRep.readName}();
927
946
|}
928
- |object ${lineRep.readName} extends ${lineRep.readName}
929
947
| """ .stripMargin
930
948
931
949
import nme .{ INTERPRETER_IMPORT_WRAPPER => iw }
@@ -935,7 +953,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
935
953
}
936
954
937
955
private lazy val ObjectSourceCode : Wrapper =
938
- if (settings. Yreplclassbased ) new ClassBasedWrapper else new ObjectBasedWrapper
956
+ if (isClassBased ) new ClassBasedWrapper else new ObjectBasedWrapper
939
957
940
958
private object ResultObjectSourceCode extends IMain .CodeAssembler [MemberHandler ] {
941
959
/** We only want to generate this code when the result
@@ -994,7 +1012,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
994
1012
}
995
1013
}
996
1014
997
- lazy val resultSymbol = lineRep.resolvePathToSymbol(accessPath )
1015
+ lazy val resultSymbol = lineRep.resolvePathToSymbol(fullAccessPath )
998
1016
def applyToResultMember [T ](name : Name , f : Symbol => T ) = exitingTyper(f(resultSymbol.info.nonPrivateDecl(name)))
999
1017
1000
1018
/* typeOf lookup with encoding */
0 commit comments