@@ -24,20 +24,38 @@ import kotlin.math.round
24
24
import org.jetbrains.uast.UCallExpression
25
25
import org.jetbrains.uast.UElement
26
26
import org.jetbrains.uast.UExpression
27
+ import org.jetbrains.uast.UField
27
28
import org.jetbrains.uast.UIdentifier
28
29
import org.jetbrains.uast.ULiteralExpression
29
30
import org.jetbrains.uast.UQualifiedReferenceExpression
30
31
import org.jetbrains.uast.UReferenceExpression
32
+ import org.jetbrains.uast.UResolvable
31
33
import org.jetbrains.uast.generate.generationPlugin
32
34
import org.jetbrains.uast.generate.replace
35
+ import org.jetbrains.uast.resolveToUElement
33
36
34
37
fun <T > UIdentifier.findColor (function : (Map <String , Color >, Map .Entry <String , Color >) -> T ): T ? {
35
38
val parent = this .uastParent
36
39
val expression = parent as ? UReferenceExpression ? : return null
37
- val type = expression.getExpressionType() ? : return null
40
+ return findColorFromExpression(expression, function)
41
+ }
42
+
43
+ private fun <T > findColorFromExpression (
44
+ expression : UReferenceExpression ,
45
+ function : (Map <String , Color >, Map .Entry <String , Color >) -> T
46
+ ): T ? {
47
+ val referencedElement = expression.resolveToUElement()
48
+ if (referencedElement is UField ) {
49
+ val referencedFieldInitializer = referencedElement.uastInitializer
50
+ if (referencedFieldInitializer is UReferenceExpression ) {
51
+ return findColorFromExpression(referencedFieldInitializer, function)
52
+ }
53
+ }
38
54
39
- val module = this .sourcePsi?.findModule() ? : return null
55
+ val type = expression.getExpressionType() ? : return null
56
+ val module = expression.sourcePsi?.findModule() ? : return null
40
57
val facet = MinecraftFacet .getInstance(module) ? : return null
58
+ val resolvedName = expression.resolvedName ? : return null
41
59
for (abstractModuleType in facet.types) {
42
60
val map = abstractModuleType.classToColorMappings
43
61
for (entry in map.entries) {
@@ -47,7 +65,7 @@ fun <T> UIdentifier.findColor(function: (Map<String, Color>, Map.Entry<String, C
47
65
// So we combine those checks and get this
48
66
val colorClass = entry.key.substringBeforeLast(' .' )
49
67
val colorName = entry.key.substringAfterLast(' .' )
50
- if (colorClass.startsWith(type.canonicalText) && colorName == expression. resolvedName ? : continue ) {
68
+ if (colorClass.startsWith(type.canonicalText) && colorName == resolvedName) {
51
69
return function(map.filterKeys { key -> key.startsWith(colorClass) }, entry)
52
70
}
53
71
}
@@ -61,21 +79,50 @@ fun UIdentifier.findColor(
61
79
vectorClasses : Array <String >?
62
80
): Pair <Color , UElement >? {
63
81
val sourcePsi = this .sourcePsi ? : return null
64
- val project = sourcePsi.project
65
-
66
82
val module = ModuleUtilCore .findModuleForPsiElement(sourcePsi) ? : return null
67
-
68
83
val facet = MinecraftFacet .getInstance(module) ? : return null
69
-
70
84
if (! facet.isOfType(moduleType)) {
71
85
return null
72
86
}
73
87
74
- val methodExpression = uastParent as ? UCallExpression ? : return null
75
- if (methodExpression.resolve()?.containingClass?.qualifiedName ! = className) {
76
- return null
88
+ val methodExpression = uastParent as ? UCallExpression
89
+ if (methodExpression? .resolve()?.containingClass?.qualifiedName = = className) {
90
+ return findColorFromCallExpression(methodExpression, vectorClasses)
77
91
}
78
92
93
+ var referencedElement = (uastParent as ? UResolvable )?.resolveToUElement()
94
+ while (referencedElement is UField ) {
95
+ val referencedFieldInitializer: UExpression ? = referencedElement.uastInitializer
96
+ if (referencedFieldInitializer is UCallExpression ) {
97
+ // The field is initialized with a method call
98
+ return referencedFieldInitializer.methodIdentifier?.findColor(moduleType, className, vectorClasses)
99
+ }
100
+
101
+ if (referencedFieldInitializer is UReferenceExpression ) {
102
+ // The field is probably initialized with a reference to another field
103
+ val referenceNameElement = referencedFieldInitializer.referenceNameElement
104
+ if (referenceNameElement is UIdentifier ) {
105
+ // The expression was simple enough
106
+ return referenceNameElement.findColor(moduleType, className, vectorClasses)
107
+ } else if (referenceNameElement is UResolvable ) {
108
+ // The expression is complex, so we resolve it. If it is a field we're on for another round
109
+ referencedElement = referenceNameElement.resolveToUElement()
110
+ continue
111
+ }
112
+ }
113
+
114
+ break
115
+ }
116
+
117
+ return null
118
+ }
119
+
120
+ private fun findColorFromCallExpression (
121
+ methodExpression : UCallExpression ,
122
+ vectorClasses : Array <String >?
123
+ ): Pair <Color , UElement >? {
124
+ val project = methodExpression.sourcePsi?.project ? : return null
125
+
79
126
val arguments = methodExpression.valueArguments
80
127
val types = arguments.map(UExpression ::getExpressionType)
81
128
0 commit comments