@@ -24,20 +24,38 @@ import kotlin.math.round
2424import org.jetbrains.uast.UCallExpression
2525import org.jetbrains.uast.UElement
2626import org.jetbrains.uast.UExpression
27+ import org.jetbrains.uast.UField
2728import org.jetbrains.uast.UIdentifier
2829import org.jetbrains.uast.ULiteralExpression
2930import org.jetbrains.uast.UQualifiedReferenceExpression
3031import org.jetbrains.uast.UReferenceExpression
32+ import org.jetbrains.uast.UResolvable
3133import org.jetbrains.uast.generate.generationPlugin
3234import org.jetbrains.uast.generate.replace
35+ import org.jetbrains.uast.resolveToUElement
3336
3437fun <T > UIdentifier.findColor (function : (Map <String , Color >, Map .Entry <String , Color >) -> T ): T ? {
3538 val parent = this .uastParent
3639 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+ }
3854
39- val module = this .sourcePsi?.findModule() ? : return null
55+ val type = expression.getExpressionType() ? : return null
56+ val module = expression.sourcePsi?.findModule() ? : return null
4057 val facet = MinecraftFacet .getInstance(module) ? : return null
58+ val resolvedName = expression.resolvedName ? : return null
4159 for (abstractModuleType in facet.types) {
4260 val map = abstractModuleType.classToColorMappings
4361 for (entry in map.entries) {
@@ -47,7 +65,7 @@ fun <T> UIdentifier.findColor(function: (Map<String, Color>, Map.Entry<String, C
4765 // So we combine those checks and get this
4866 val colorClass = entry.key.substringBeforeLast(' .' )
4967 val colorName = entry.key.substringAfterLast(' .' )
50- if (colorClass.startsWith(type.canonicalText) && colorName == expression. resolvedName ? : continue ) {
68+ if (colorClass.startsWith(type.canonicalText) && colorName == resolvedName) {
5169 return function(map.filterKeys { key -> key.startsWith(colorClass) }, entry)
5270 }
5371 }
@@ -61,21 +79,50 @@ fun UIdentifier.findColor(
6179 vectorClasses : Array <String >?
6280): Pair <Color , UElement >? {
6381 val sourcePsi = this .sourcePsi ? : return null
64- val project = sourcePsi.project
65-
6682 val module = ModuleUtilCore .findModuleForPsiElement(sourcePsi) ? : return null
67-
6883 val facet = MinecraftFacet .getInstance(module) ? : return null
69-
7084 if (! facet.isOfType(moduleType)) {
7185 return null
7286 }
7387
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)
7791 }
7892
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+
79126 val arguments = methodExpression.valueArguments
80127 val types = arguments.map(UExpression ::getExpressionType)
81128
0 commit comments