@@ -27,10 +27,12 @@ private class InsertExpression(config: ExpressionCompilerConfig) extends Phase:
27
27
override def phaseName : String = InsertExpression .name
28
28
override def isCheckable : Boolean = false
29
29
30
+ // TODO move reflection methods (callMethod, getField, etc) to scala3-library
31
+ // under scala.runtime (or scala.debug?) to avoid recompiling them again and again
30
32
private val evaluationClassSource =
31
33
s """ |class ${config.expressionClassName}(thisObject: Any, names: Array[String], values: Array[Any]) {
32
34
| import java.lang.reflect.InvocationTargetException
33
- | val classLoader = getClass.getClassLoader.nn
35
+ | val classLoader = getClass.getClassLoader
34
36
|
35
37
| def evaluate(): Any =
36
38
| ()
@@ -50,13 +52,12 @@ private class InsertExpression(config: ExpressionCompilerConfig) extends Phase:
50
52
| }
51
53
|
52
54
| def callMethod(obj: Any, className: String, methodName: String, paramTypesNames: Array[String], returnTypeName: String, args: Array[Object]): Any = {
53
- | val clazz = classLoader.loadClass(className).nn
54
- | val method = clazz.getDeclaredMethods.nn
55
- | .map(_.nn)
55
+ | val clazz = classLoader.loadClass(className)
56
+ | val method = clazz.getDeclaredMethods
56
57
| .find { m =>
57
58
| m.getName == methodName &&
58
- | m.getReturnType.nn. getName == returnTypeName &&
59
- | m.getParameterTypes.nn. map(_.nn .getName).toSeq == paramTypesNames.toSeq
59
+ | m.getReturnType.getName == returnTypeName &&
60
+ | m.getParameterTypes.map(_.getName).toSeq == paramTypesNames.toSeq
60
61
| }
61
62
| .getOrElse(throw new NoSuchMethodException(methodName))
62
63
| method.setAccessible(true)
@@ -65,61 +66,58 @@ private class InsertExpression(config: ExpressionCompilerConfig) extends Phase:
65
66
| }
66
67
|
67
68
| def callConstructor(className: String, paramTypesNames: Array[String], args: Array[Object]): Any = {
68
- | val clazz = classLoader.loadClass(className).nn
69
- | val constructor = clazz.getConstructors.nn
70
- | .find { c => c.getParameterTypes.nn. map(_.nn .getName).toSeq == paramTypesNames.toSeq }
69
+ | val clazz = classLoader.loadClass(className)
70
+ | val constructor = clazz.getConstructors
71
+ | .find { c => c.getParameterTypes.map(_.getName).toSeq == paramTypesNames.toSeq }
71
72
| .getOrElse(throw new NoSuchMethodException(s"new $$ className"))
72
73
| constructor.setAccessible(true)
73
74
| unwrapException(constructor.newInstance(args*))
74
75
| }
75
76
|
76
77
| def getField(obj: Any, className: String, fieldName: String): Any = {
77
- | val clazz = classLoader.loadClass(className).nn
78
- | val field = clazz.getDeclaredField(fieldName).nn
78
+ | val clazz = classLoader.loadClass(className)
79
+ | val field = clazz.getDeclaredField(fieldName)
79
80
| field.setAccessible(true)
80
81
| field.get(obj)
81
82
| }
82
83
|
83
84
| def setField(obj: Any, className: String, fieldName: String, value: Any): Any = {
84
- | val clazz = classLoader.loadClass(className).nn
85
- | val field = clazz.getDeclaredField(fieldName).nn
85
+ | val clazz = classLoader.loadClass(className)
86
+ | val field = clazz.getDeclaredField(fieldName)
86
87
| field.setAccessible(true)
87
88
| field.set(obj, value)
88
89
| }
89
90
|
90
91
| def getOuter(obj: Any, outerTypeName: String): Any = {
91
92
| val clazz = obj.getClass
92
93
| val field = getSuperclassIterator(clazz)
93
- | .flatMap(_.getDeclaredFields.nn.toSeq)
94
- | .map(_.nn)
95
- | .find { field => field.getName == " $$ outer" && field.getType.nn.getName == outerTypeName }
94
+ | .flatMap(_.getDeclaredFields.toSeq)
95
+ | .find { field => field.getName == " $$ outer" && field.getType.getName == outerTypeName }
96
96
| .getOrElse(throw new NoSuchFieldException(" $$ outer"))
97
97
| field.setAccessible(true)
98
98
| field.get(obj)
99
99
| }
100
100
|
101
101
| def getStaticObject(className: String): Any = {
102
- | val clazz = classLoader.loadClass(className).nn
103
- | val field = clazz.getDeclaredField("MODULE $$ ").nn
102
+ | val clazz = classLoader.loadClass(className)
103
+ | val field = clazz.getDeclaredField("MODULE $$ ")
104
104
| field.setAccessible(true)
105
105
| field.get(null)
106
106
| }
107
107
|
108
- | def getSuperclassIterator(clazz: Class[?] | Null): Iterator[Class[?]] =
109
- | Iterator.iterate(clazz)(_.nn.getSuperclass).takeWhile(_ != null).map(_.nn)
108
+ | def getSuperclassIterator(clazz: Class[?]): Iterator[Class[?]] =
109
+ | Iterator.iterate(clazz: Class[?] | Null)(_.nn.getSuperclass)
110
+ | .takeWhile(_ != null)
111
+ | .map(_.nn)
110
112
|
111
113
| // A fake method that is used as a placeholder in the extract-expression phase.
112
114
| // The resolve-reflect-eval phase resolves it to a call of one of the other methods in this class.
113
115
| def reflectEval(qualifier: Object, term: String, args: Array[Object]): Any = ???
114
116
|
115
117
| private def unwrapException(f: => Any): Any =
116
118
| try f catch {
117
- | case e: InvocationTargetException => throw e.getCause.nn
119
+ | case e: InvocationTargetException => throw e.getCause
118
120
| }
119
- |
120
- | extension [T] (x: T | Null) {
121
- | private def nn: T = x.asInstanceOf[T]
122
- | }
123
121
|}
124
122
| """ .stripMargin
125
123
0 commit comments