<commit_before>package org.jetbrains.plugins.scala.lang.psi.impl.expr

import api.ScalaFile
import api.statements.params.ScTypeParam
import api.toplevel.imports.ScImportExpr
import api.statements._
import api.base.patterns.ScReferencePattern
import api.toplevel.typedef.{ScClass, ScTypeDefinition, ScTrait}
import com.intellij.util.IncorrectOperationException
import resolve._

import toplevel.synthetic.ScSyntheticFunction
import types._
import api.expr.ScMethodCall
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
import org.jetbrains.plugins.scala.lang.parser.ScalaElementTypes
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiElementImpl

import com.intellij.psi.tree.TokenSet
import com.intellij.lang.ASTNode
import com.intellij.psi.tree.IElementType
import com.intellij.psi._
import util.PsiTreeUtil

import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiElementFactory
import org.jetbrains.plugins.scala.lang.psi.api.expr._
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiElement
import com.intellij.openapi.util._
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.ScTyped

/**
 * @author AlexanderPodkhalyuzin
* Date: 06.03.2008
 */

class ScReferenceExpressionImpl(node: ASTNode) extends ScalaPsiElementImpl(node) with ScReferenceExpression {
  override def toString: String = "ReferenceExpression"

  def nameId: PsiElement = findChildByType(ScalaTokenTypes.tIDENTIFIER)

  def bindToElement(element: PsiElement): PsiElement = {
    if (isReferenceTo(element)) return this
    element match {
      case _: ScTrait => this
      case c: ScClass if !c.isCase => this
      case c: PsiClass => {
        if (!ResolveUtils.kindMatches(element, getKinds(false)))
          throw new IncorrectOperationException("class does not match expected kind")
        if (refName != c.getName)
          throw new IncorrectOperationException("class does not match expected name")
        val file = getContainingFile.asInstanceOf[ScalaFile]
        if (isReferenceTo(element)) return this
        val qualName = c.getQualifiedName
        if (qualName != null) {
          file.addImportForClass(c)
        }
        this
      }
      case _ => throw new IncorrectOperationException("Cannot bind to anything but class")
    }
  }

  def getVariants(): Array[Object] = _resolve(this, new CompletionProcessor(getKinds(true))).map(r => r.getElement)

  def getSameNameVariants: Array[Object] = _resolve(this, new SameNameCompletionProcessor(getKinds(true), refName)).map(r => r.getElement)

  import com.intellij.psi.impl.PsiManagerEx

  def multiResolve(incomplete: Boolean) =
    getManager.asInstanceOf[PsiManagerEx].getResolveCache.resolveWithCaching(this, MyResolver, true, incomplete)

  def getKinds(incomplete: Boolean) = {
    getParent match {
      case _: ScReferenceExpression => StdKinds.refExprQualRef
      case _ => StdKinds.refExprLastRef
    }
  }

  import com.intellij.psi.impl.source.resolve.ResolveCache

  object MyResolver extends ResolveCache.PolyVariantResolver[ScReferenceExpressionImpl] {
    def resolve(ref: ScReferenceExpressionImpl, incomplete: Boolean) = {
      def proc(e : PsiElement) : ResolveProcessor = e.getParent match {
        case generic : ScGenericCall => proc(generic)
        case call: ScMethodCall =>
          new MethodResolveProcessor(ref, call.args.exprs.map{_.getType}, expectedType)
        case inf: ScInfixExpr if ref == inf.operation => {
          val args = if (ref.rightAssoc) Seq.singleton(inf.lOp.getType) else inf.rOp match {
            case tuple: ScTuple => tuple.exprs.map{_.getType}
            case rOp => Seq.singleton(rOp.getType)
          }
          new MethodResolveProcessor(ref, args, expectedType)
        }
        case postf: ScPostfixExpr if ref == postf.operation =>
          new MethodResolveProcessor(ref, Seq.empty, expectedType)
        case pref: ScPrefixExpr if ref == pref.operation =>
          new MethodResolveProcessor(ref, Seq.empty, expectedType)
        case _ => new RefExprResolveProcessor(getKinds(incomplete), refName)
      }

      _resolve(ref, proc(ref))
    }
  }

  private def _resolve(ref: ScReferenceExpressionImpl, processor: BaseProcessor): Array[ResolveResult] = {
    def processTypes(e: ScExpression) = {
      for (t <- allTypes) {   
        if (processor.candidates.length == 0 || processor.isInstanceOf[CompletionProcessor]) {
          processor.processType(t, e)
        }
      }
    }

      ref.qualifier match {
      case None => ref.getParent match {
        case inf: ScInfixExpr if ref == inf.operation => {
          val thisOp = if (ref.rightAssoc) inf.rOp else inf.lOp
          processTypes(thisOp)
        }
        case postf: ScPostfixExpr if ref == postf.operation => processTypes(postf.operand)
        case pref: ScPrefixExpr if ref == pref.operation => processTypes(pref.operand)
        case _ => {
          def treeWalkUp(place: PsiElement, lastParent: PsiElement) {
            place match {
              case null =>
              case p => {
                if (!p.processDeclarations(processor,
                  ResolveState.initial(),
                  lastParent, ref)) return
                if (!processor.changedLevel) return
                treeWalkUp(place.getParent, place)
              }
            }
          }
          treeWalkUp(ref, null)
        }
      }<commit_msg>completion fixed<commit_after>package org.jetbrains.plugins.scala.lang.psi.impl.expr

import api.ScalaFile
import api.statements.params.ScTypeParam
import api.toplevel.imports.ScImportExpr
import api.statements._
import api.base.patterns.ScReferencePattern
import api.toplevel.typedef.{ScClass, ScTypeDefinition, ScTrait}
import com.intellij.util.IncorrectOperationException
import resolve._

import toplevel.synthetic.ScSyntheticFunction
import types._
import api.expr.ScMethodCall
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
import org.jetbrains.plugins.scala.lang.parser.ScalaElementTypes
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiElementImpl

import com.intellij.psi.tree.TokenSet
import com.intellij.lang.ASTNode
import com.intellij.psi.tree.IElementType
import com.intellij.psi._
import util.PsiTreeUtil

import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiElementFactory
import org.jetbrains.plugins.scala.lang.psi.api.expr._
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiElement
import com.intellij.openapi.util._
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.ScTyped

/**
 * @author AlexanderPodkhalyuzin
* Date: 06.03.2008
 */

class ScReferenceExpressionImpl(node: ASTNode) extends ScalaPsiElementImpl(node) with ScReferenceExpression {
  override def toString: String = "ReferenceExpression"

  def nameId: PsiElement = findChildByType(ScalaTokenTypes.tIDENTIFIER)

  def bindToElement(element: PsiElement): PsiElement = {
    if (isReferenceTo(element)) return this
    element match {
      case _: ScTrait => this
      case c: ScClass if !c.isCase => this
      case c: PsiClass => {
        if (!ResolveUtils.kindMatches(element, getKinds(false)))
          throw new IncorrectOperationException("class does not match expected kind")
        if (refName != c.getName)
          throw new IncorrectOperationException("class does not match expected name")
        val file = getContainingFile.asInstanceOf[ScalaFile]
        if (isReferenceTo(element)) return this
        val qualName = c.getQualifiedName
        if (qualName != null) {
          file.addImportForClass(c)
        }
        this
      }
      case _ => throw new IncorrectOperationException("Cannot bind to anything but class")
    }
  }

  def getVariants(): Array[Object] = _resolve(this, new CompletionProcessor(getKinds(true))).map(r => r.getElement)

  def getSameNameVariants: Array[Object] = _resolve(this, new SameNameCompletionProcessor(getKinds(true), refName)).map(r => r.getElement)

  import com.intellij.psi.impl.PsiManagerEx

  def multiResolve(incomplete: Boolean) =
    getManager.asInstanceOf[PsiManagerEx].getResolveCache.resolveWithCaching(this, MyResolver, true, incomplete)

  def getKinds(incomplete: Boolean) = {
    getParent match {
      case _: ScReferenceExpression => StdKinds.refExprQualRef
      case _ => StdKinds.refExprLastRef
    }
  }

  import com.intellij.psi.impl.source.resolve.ResolveCache

  object MyResolver extends ResolveCache.PolyVariantResolver[ScReferenceExpressionImpl] {
    def resolve(ref: ScReferenceExpressionImpl, incomplete: Boolean) = {
      def proc(e : PsiElement) : ResolveProcessor = e.getParent match {
        case generic : ScGenericCall => proc(generic)
        case call: ScMethodCall =>
          new MethodResolveProcessor(ref, call.args.exprs.map{_.getType}, expectedType)
        case inf: ScInfixExpr if ref == inf.operation => {
          val args = if (ref.rightAssoc) Seq.singleton(inf.lOp.getType) else inf.rOp match {
            case tuple: ScTuple => tuple.exprs.map{_.getType}
            case rOp => Seq.singleton(rOp.getType)
          }
          new MethodResolveProcessor(ref, args, expectedType)
        }
        case postf: ScPostfixExpr if ref == postf.operation =>
          new MethodResolveProcessor(ref, Seq.empty, expectedType)
        case pref: ScPrefixExpr if ref == pref.operation =>
          new MethodResolveProcessor(ref, Seq.empty, expectedType)
        case _ => new RefExprResolveProcessor(getKinds(incomplete), refName)
      }

      _resolve(ref, proc(ref))
    }
  }

  private def _resolve(ref: ScReferenceExpressionImpl, processor: BaseProcessor): Array[ResolveResult] = {
    def processTypes(e: ScExpression) = {
      for (t <- e.allTypes) {
        processor.processType(t, e)
      }
    }

      ref.qualifier match {
      case None => ref.getParent match {
        case inf: ScInfixExpr if ref == inf.operation => {
          val thisOp = if (ref.rightAssoc) inf.rOp else inf.lOp
          processTypes(thisOp)
        }
        case postf: ScPostfixExpr if ref == postf.operation => processTypes(postf.operand)
        case pref: ScPrefixExpr if ref == pref.operation => processTypes(pref.operand)
        case _ => {
          def treeWalkUp(place: PsiElement, lastParent: PsiElement) {
            place match {
              case null =>
              case p => {
                if (!p.processDeclarations(processor,
                  ResolveState.initial(),
                  lastParent, ref)) return
                if (!processor.changedLevel) return
                treeWalkUp(place.getParent, place)
              }
            }
          }
          treeWalkUp(ref, null)
        }
      }
{'fraction_non_alphanumeric': 0.09531882829424508, 'fraction_numerical': 0.0016012056136385042, 'mean_word_length': 3.1590285938112026, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '2147585', 'n_tokens_mistral': 3164, 'n_tokens_neox': 3103, 'n_words': 659}