fun resolveReference()

in src/main/kotlin/org/arend/resolving/util/BinOpParser.kt [20:71]


fun resolveReference(data: Any?, referent: Referable, fixity: Fixity?): Concrete.Expression? {
    return if (data is ArendCompositeElement) {
        val referentData = when (referent) {
            is NamedUnresolvedReference -> referent.data
            is LongUnresolvedReference -> referent.data
            else -> null
        }

        val scope1 =  ((data as? ArendIPName)?.parentLiteral ?: data).scope

        val anchor: ArendReferenceElement? = when (referentData) {
            is ArendLongName -> referentData.referenceNameElement
            is ArendIPName -> referentData.referenceNameElement
            is ArendRefIdentifier -> referentData.referenceNameElement
            else -> null
        }

        val resolveCache = data.project.service<ArendResolveCache>()
        val refExpr = Concrete.FixityReferenceExpression.make(data, referent, fixity, null, null)

        var arg: Concrete.Expression? = null
        var isCachedValue = true
        val referentComputer = {
            isCachedValue = false
            arg = ExpressionResolveNameVisitor.resolve(refExpr, scope1, false, null)
            refExpr.referent
        }

        var referable = if (anchor != null) resolveCache.resolveCached(referentComputer, anchor) else referentComputer.invoke()

        if (fixity == Fixity.POSTFIX)
            arg = null
        else {
            val isDynamicClassMember = (referable as? PsiElement)?.ancestor<ArendDefClass>()?.dynamicReferables?.contains(referable) == true
            if (isDynamicClassMember && isCachedValue) referentComputer.invoke()
        }

        if (arg == null && referent is LongUnresolvedReference && data is ArendLongName) {
            val referable1 = RedirectingReferable.getOriginalReferable(refExpr.referent)
            val resolvedRefs = data.refIdentifierList.map { it.resolve as? Referable }.toMutableList()
            if (referable1 is UnresolvedReference) {
                arg = referable1.resolveArgument(scope1, resolvedRefs)
                referable = referable1.resolve(scope1, null)
            }
        }
        if (referable != null) refExpr.referent = referable

        if (arg == null) refExpr else Concrete.AppExpression.make(data, refExpr, arg, false)
    } else {
        null
    }
}