<commit_before>/*
 * Copyright 2016 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package intellij.haskell.navigation

import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi._
import intellij.haskell.external.component._
import intellij.haskell.psi._
import intellij.haskell.util.Util.removeAllSpaces
import intellij.haskell.util.{HaskellProjectUtil, LineColumnPosition}

import scala.Option.option2Iterable

class HaskellReference(element: HaskellNamedElement, textRange: TextRange) extends PsiPolyVariantReferenceBase[HaskellNamedElement](element, textRange) {

  override def multiResolve(incompleteCode: Boolean): Array[ResolveResult] = {
    val project = myElement.getProject
    val psiFile = myElement.getContainingFile

    val result = myElement match {
      case mi: HaskellModid =>
        (for {
          haskellFile <- HaskellProjectUtil.findFilesForModule(mi.getName, project)
        } yield new HaskellFileResolveResult(haskellFile)).toArray
      case qe: HaskellQualifierElement =>
        val importDeclarations = HaskellPsiUtil.findImportDeclarations(psiFile)
        val resolveResults = findQualifier(importDeclarations, qe).map(q => Iterable(new HaskellQualifierResolveResult(q))).getOrElse(
          findModuleFiles(importDeclarations, qe, project).map(f => new HaskellFileResolveResult(f.getOriginalElement)))
        if (resolveResults.isEmpty) {
          // return itself
          HaskellPsiUtil.findNamedElement(myElement).map(new HaskellProjectResolveResult(_)).toArray
        } else {
          resolveResults.toArray
        }
      case ne: HaskellNamedElement
        if HaskellPsiUtil.findTopDeclarationParent(ne).isDefined |
          HaskellPsiUtil.findModuleDeclarationParent(ne).isDefined |
          HaskellPsiUtil.findImportDeclarationParent(ne).isDefined =>
        val isProjectFile = HaskellProjectUtil.isProjectFile(psiFile)
        findResolveResults(ne, isProjectFile, project).toArray
      case _ => Array[ResolveResult]()
    }
    result.asInstanceOf[Array[ResolveResult]]
  }

  override def isReferenceTo(element: PsiElement): Boolean = {
    val psiManager = getElement.getManager
    val resolveResults = multiResolve(false)
    resolveResults.exists(rr => psiManager.areElementsEquivalent(rr.getElement, element))
  }

  /** Implemented in [[intellij.haskell.editor.HaskellCompletionContributor]] **/
  override def getVariants: Array[AnyRef] = {
    Array()
  }

  private def findQualifier(importDeclarations: Iterable[HaskellImportDeclaration], qualifierElement: HaskellQualifierElement) = {
    importDeclarations.flatMap(id => Option(id.getImportQualifiedAs)).flatMap(iqa => Option(iqa.getQualifier)).find(_.getName == qualifierElement.getName)
  }

  private def findModuleFiles(importDeclarations: Iterable[HaskellImportDeclaration], qualifierElement: HaskellQualifierElement, project: Project) = {
    importDeclarations.flatMap(id => Option(id.getModid)).find(mi => mi.getName == qualifierElement.getName).map(mi => HaskellProjectUtil.findFilesForModule(mi.getName, project)).getOrElse(Iterable())
  }

  private def findResolveResults(namedElement: HaskellNamedElement, isProjectFile: Boolean, project: Project) = {<commit_msg>Fix to not return duplicates in  resolved results.<commit_after>/*
 * Copyright 2016 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package intellij.haskell.navigation

import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi._
import intellij.haskell.external.component._
import intellij.haskell.psi._
import intellij.haskell.util.Util.removeAllSpaces
import intellij.haskell.util.{HaskellProjectUtil, LineColumnPosition}

import scala.Option.option2Iterable

class HaskellReference(element: HaskellNamedElement, textRange: TextRange) extends PsiPolyVariantReferenceBase[HaskellNamedElement](element, textRange) {

  override def multiResolve(incompleteCode: Boolean): Array[ResolveResult] = {
    val project = myElement.getProject
    val psiFile = myElement.getContainingFile

    val result = myElement match {
      case mi: HaskellModid =>
        (for {
          haskellFile <- HaskellProjectUtil.findFilesForModule(mi.getName, project)
        } yield new HaskellFileResolveResult(haskellFile)).toArray
      case qe: HaskellQualifierElement =>
        val importDeclarations = HaskellPsiUtil.findImportDeclarations(psiFile)
        val resolveResults = findQualifier(importDeclarations, qe).map(q => Iterable(new HaskellQualifierResolveResult(q))).getOrElse(
          findModuleFiles(importDeclarations, qe, project).map(f => new HaskellFileResolveResult(f.getOriginalElement)))
        if (resolveResults.isEmpty) {
          // return itself
          HaskellPsiUtil.findNamedElement(myElement).map(new HaskellProjectResolveResult(_)).toArray
        } else {
          resolveResults.toArray
        }
      case ne: HaskellNamedElement
        if HaskellPsiUtil.findTopDeclarationParent(ne).isDefined |
          HaskellPsiUtil.findModuleDeclarationParent(ne).isDefined |
          HaskellPsiUtil.findImportDeclarationParent(ne).isDefined =>
        val isProjectFile = HaskellProjectUtil.isProjectFile(psiFile)
        findResolveResults(ne, isProjectFile, project).toArray.distinct
      case _ => Array[ResolveResult]()
    }
    result.asInstanceOf[Array[ResolveResult]]
  }

  override def isReferenceTo(element: PsiElement): Boolean = {
    val psiManager = getElement.getManager
    val resolveResults = multiResolve(false)
    resolveResults.exists(rr => psiManager.areElementsEquivalent(rr.getElement, element))
  }

  /** Implemented in [[intellij.haskell.editor.HaskellCompletionContributor]] **/
  override def getVariants: Array[AnyRef] = {
    Array()
  }

  private def findQualifier(importDeclarations: Iterable[HaskellImportDeclaration], qualifierElement: HaskellQualifierElement) = {
    importDeclarations.flatMap(id => Option(id.getImportQualifiedAs)).flatMap(iqa => Option(iqa.getQualifier)).find(_.getName == qualifierElement.getName)
  }

  private def findModuleFiles(importDeclarations: Iterable[HaskellImportDeclaration], qualifierElement: HaskellQualifierElement, project: Project) = {
    importDeclarations.flatMap(id => Option(id.getModid)).find(mi => mi.getName == qualifierElement.getName).map(mi => HaskellProjectUtil.findFilesForModule(mi.getName, project)).getOrElse(Iterable())
  }

  private def findResolveResults(namedElement: HaskellNamedElement, isProjectFile: Boolean, project: Project) = {
{'fraction_non_alphanumeric': 0.09031068983675619, 'fraction_numerical': 0.002369668246445498, 'mean_word_length': 4.716328066215199, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2561003', 'n_tokens_mistral': 2186, 'n_tokens_neox': 2071, 'n_words': 465}