All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.airbnb.paris.processor.RFinder.kt Maven / Gradle / Ivy

package com.airbnb.paris.processor

import com.airbnb.paris.annotations.ParisConfig
import com.airbnb.paris.processor.models.AttrInfo
import com.airbnb.paris.processor.models.StyleableChildInfo
import com.airbnb.paris.processor.models.StyleableInfo
import javax.lang.model.element.TypeElement
import javax.lang.model.type.MirroredTypeException
import javax.lang.model.type.TypeMirror

internal class RFinder(override val processor: ParisProcessor) : WithParisProcessor {

    var element: TypeElement? = null

    fun processConfig(config: ParisConfig) {
        if (element != null) {
            return
        }

        getRTypeFromConfig(config)?.let {
            element = it.asTypeElement()
        }
    }

    fun processResourceAnnotations(
        styleableChildrenInfo: List,
        attrsInfo: List
    ) {
        if (element != null) {
            return
        }

        val arbitraryResId = when {
            styleableChildrenInfo.isNotEmpty() -> styleableChildrenInfo[0].styleableResId
            attrsInfo.isNotEmpty() -> attrsInfo[0].styleableResId
            else -> null
        }
        arbitraryResId?.let {
            element = elements.getTypeElement(it.className.enclosingClassName().reflectionName())
        }
    }

    fun processStyleables(styleablesInfo: List) {
        if (element == null && styleablesInfo.isNotEmpty()) {
            styleablesInfo[0].let { styleableInfo ->
                var packageName = styleableInfo.elementPackageName
                while (packageName.isNotBlank()) {
                    elements.getTypeElement("$packageName.R")?.let {
                        element = it
                        return
                    }
                    val lastIndexOfDot = packageName.lastIndexOf('.')
                    packageName = if (lastIndexOfDot > 0) {
                        packageName.substring(0, lastIndexOfDot)
                    } else {
                        ""
                    }
                }
            }
        }
    }

    private fun getRTypeFromConfig(config: ParisConfig): TypeMirror? {
        var rType: TypeMirror? = null
        try {
            config.rClass
        } catch (mte: MirroredTypeException) {
            rType = mte.typeMirror
        }

        // Void is the default so check against that
        val voidType = elements.getTypeElement(Void::class.java.canonicalName).asType()
        return if (types.isSameType(voidType, rType)) {
            null
        } else {
            if (rType != null && rType.asTypeElement().simpleName.toString() != "R") {
                logError {
                    "@ParisConfig's rClass parameter is pointing to a non-R class"
                }
                null
            } else {
                rType
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy