package org.purescript.psi.expression

import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.LocalQuickFixProvider
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.PsiReferenceBase
import com.intellij.psi.SmartPointerManager

class ExpressionConstructorReference(expressionConstructor: PSExpressionConstructor) :
    LocalQuickFixProvider,
    PsiReferenceBase<PSExpressionConstructor>(
        expressionConstructor,
        expressionConstructor.qualifiedProperName.properName.textRangeInParent,
        false
    ) {

    override fun getVariants(): Array<Any> =
        candidates.toList().toTypedArray()

    override fun resolve(): PsiNamedElement? =
        candidates.firstOrNull { it.name == element.name }

    private val candidates: Sequence<PsiNamedElement>
        get() {
            val module = element.module ?: return emptySequence()
            return sequence {
                yieldAll(module.newTypeConstructors)
                yieldAll(module.dataConstructors)
                val importDeclarations = module.importDeclarations
                yieldAll(importDeclarations.flatMap { it.importedNewTypeConstructors })
                yieldAll(importDeclarations.flatMap { it.importedDataConstructors })
            }
        }

    override fun getQuickFixes(): Array<LocalQuickFix> =
        arrayOf(ImportExpressionConstructorQuickFix(SmartPointerManager.createPointer(element)))
}

package org.purescript.psi.expression

import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.LocalQuickFixProvider
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.PsiReferenceBase
import com.intellij.psi.SmartPointerManager

class ExpressionConstructorReference(expressionConstructor: PSExpressionConstructor) :
    LocalQuickFixProvider,
    PsiReferenceBase<PSExpressionConstructor>(
        expressionConstructor,
        expressionConstructor.qualifiedProperName.properName.textRangeInParent,
        false
    ) {

    override fun getVariants(): Array<Any> =
        candidates.toList().toTypedArray()

    override fun resolve(): PsiNamedElement? =
        candidates.firstOrNull { it.name == element.name }

    private val candidates: Sequence<PsiNamedElement>
        get() {
            val module = element.module ?: return emptySequence()
            val qualifyingName = element.qualifiedProperName.moduleName?.name
            if (qualifyingName != null) {
                val importDeclaration = module.importDeclarations
                    .firstOrNull { it.importAlias?.name == qualifyingName }
                    ?: return emptySequence()
                return sequence {
                    yieldAll(importDeclaration.importedNewTypeConstructors)
                    yieldAll(importDeclaration.importedDataConstructors)
                }
            } else {
                return sequence {
                    yieldAll(module.newTypeConstructors)
                    yieldAll(module.dataConstructors)
                    val importDeclarations = module.importDeclarations
                        .filter { it.importAlias == null }
                    yieldAll(importDeclarations.flatMap { it.importedNewTypeConstructors })
                    yieldAll(importDeclarations.flatMap { it.importedDataConstructors })
                }
            }
        }

    override fun getQuickFixes(): Array<LocalQuickFix> =
        arrayOf(ImportExpressionConstructorQuickFix(SmartPointerManager.createPointer(element)))
}

Implement navigation for qualified expression constructors
Implement navigation for qualified expression constructors

intellij-purescript/intellij-purescript,intellij-purescript/intellij-purescript