@@ -13,6 +13,9 @@ import com.itangcent.intellij.jvm.element.ExplicitParameter
13
13
import kotlin.reflect.KClass
14
14
15
15
interface ExportContext : Extensible {
16
+ /* *
17
+ * the parent context, allowing navigation up the context hierarchy.
18
+ */
16
19
fun parent (): ExportContext ?
17
20
18
21
/* *
@@ -23,22 +26,45 @@ interface ExportContext : Extensible {
23
26
fun psi (): PsiElement
24
27
}
25
28
29
+ /* *
30
+ * Extends ExportContext for contexts dealing with variables (methods or parameters).
31
+ */
26
32
interface VariableExportContext : ExportContext {
27
33
34
+ /* *
35
+ * the name of the variable.
36
+ */
28
37
fun name (): String
29
38
39
+ /* *
40
+ * the type of the variable, which may be null if the type is not resolved.
41
+ */
30
42
fun type (): DuckType ?
31
43
44
+ /* *
45
+ * the explicit element representation of the variable.
46
+ */
32
47
fun element (): ExplicitElement <* >
48
+
49
+ /* *
50
+ * Sets a resolved name for the variable, typically used for renaming.
51
+ */
52
+ fun setResolvedName (name : String )
33
53
}
34
54
35
55
// region kits of ExportContext
36
56
57
+ /* *
58
+ * find specific contexts by type.
59
+ */
37
60
@Suppress(" UNCHECKED_CAST" )
38
61
fun <T : ExportContext > ExportContext.findContext (condition : KClass <T >): T ? {
39
62
return findContext { condition.isInstance(it) } as ? T
40
63
}
41
64
65
+ /* *
66
+ * find specific contexts by condition.
67
+ */
42
68
fun ExportContext.findContext (condition : (ExportContext ) -> Boolean ): ExportContext ? {
43
69
var exportContext: ExportContext ? = this
44
70
while (exportContext != null ) {
@@ -50,39 +76,58 @@ fun ExportContext.findContext(condition: (ExportContext) -> Boolean): ExportCont
50
76
return null
51
77
}
52
78
53
- fun <T > ExportContext.findExt (attr : String ): T ? {
54
- var exportContext: ExportContext ? = this
55
- while (exportContext != null ) {
56
- exportContext.getExt<T >(attr)?.let { return it }
57
- exportContext = exportContext.parent()
58
- }
59
- return null
60
- }
61
-
62
79
// endregion
63
80
81
+ /* *
82
+ * Base context with no parent, typically used for top-level classes.
83
+ */
64
84
abstract class RootExportContext :
65
85
SimpleExtensible (), ExportContext {
66
86
override fun parent (): ExportContext ? {
67
87
return null
68
88
}
69
89
}
70
90
91
+ /* *
92
+ * General purpose context implementation with a specified parent context.
93
+ */
71
94
abstract class AbstractExportContext (private val parent : ExportContext ) :
72
- SimpleExtensible (), ExportContext {
95
+ SimpleExtensible (), VariableExportContext {
96
+
97
+ private var resolvedName: String? = null
98
+
73
99
override fun parent (): ExportContext ? {
74
100
return this .parent
75
101
}
102
+
103
+ /* *
104
+ * Returns the name of the element.
105
+ *
106
+ * @return the element name.
107
+ */
108
+ override fun name (): String {
109
+ return resolvedName ? : element().name()
110
+ }
111
+
112
+ override fun setResolvedName (name : String ) {
113
+ this .resolvedName = name
114
+ }
76
115
}
77
116
117
+ /* *
118
+ * Context specifically for a class
119
+ */
78
120
class ClassExportContext (val cls : PsiClass ) : RootExportContext() {
79
121
override fun psi (): PsiClass {
80
122
return cls
81
123
}
82
124
}
83
125
126
+ /* *
127
+ * Context for a method, containing specifics about the method being exported.
128
+ */
84
129
class MethodExportContext (
85
- private val parent : ExportContext ,
130
+ parent : ExportContext ,
86
131
private val method : ExplicitMethod
87
132
) : AbstractExportContext(parent), VariableExportContext {
88
133
@@ -113,19 +158,27 @@ class MethodExportContext(
113
158
}
114
159
}
115
160
116
- class ParameterExportContext (
117
- private val parent : ExportContext ,
118
- private val parameter : ExplicitParameter
119
- ) : AbstractExportContext(parent), VariableExportContext {
161
+ /* *
162
+ * Context for a parameter, containing specifics about the parameter being exported.
163
+ */
164
+ interface ParameterExportContext : VariableExportContext {
120
165
121
- /* *
122
- * Returns the name of the element.
123
- *
124
- * @return the element name.
125
- */
126
- override fun name (): String {
127
- return parameter.name()
128
- }
166
+ override fun element (): ExplicitParameter
167
+
168
+ override fun psi (): PsiParameter
169
+ }
170
+
171
+ fun ParameterExportContext (
172
+ parent : ExportContext ,
173
+ parameter : ExplicitParameter
174
+ ): ParameterExportContext {
175
+ return ParameterExportContextImpl (parent, parameter)
176
+ }
177
+
178
+ class ParameterExportContextImpl (
179
+ parent : ExportContext ,
180
+ private val parameter : ExplicitParameter
181
+ ) : AbstractExportContext(parent), ParameterExportContext {
129
182
130
183
/* *
131
184
* Returns the type of the variable.
@@ -145,18 +198,30 @@ class ParameterExportContext(
145
198
}
146
199
}
147
200
201
+ /* *
202
+ * retrieve ClassExportContext based on the current context.
203
+ */
148
204
fun ExportContext.classContext (): ClassExportContext ? {
149
205
return this .findContext(ClassExportContext ::class )
150
206
}
151
207
208
+ /* *
209
+ * retrieve MethodExportContext based on the current context.
210
+ */
152
211
fun ExportContext.methodContext (): MethodExportContext ? {
153
212
return this .findContext(MethodExportContext ::class )
154
213
}
155
214
215
+ /* *
216
+ * retrieve ParameterExportContext based on the current context.
217
+ */
156
218
fun ExportContext.paramContext (): ParameterExportContext ? {
157
219
return this .findContext(ParameterExportContext ::class )
158
220
}
159
221
222
+ /* *
223
+ * Searches for an extended property, first locally then up the context hierarchy.
224
+ */
160
225
fun <T > ExportContext.searchExt (attr : String ): T ? {
161
226
this .getExt<T >(attr)?.let { return it }
162
227
this .parent()?.searchExt<T >(attr)?.let { return it }
0 commit comments