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

import com.intellij.lang.ASTNode
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi._
import com.intellij.psi.util.{PsiModificationTracker, PsiTreeUtil}
import org.jetbrains.plugins.scala.caches.CachesUtil
import org.jetbrains.plugins.scala.extensions._
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiUtil.SafeCheckException
import org.jetbrains.plugins.scala.lang.psi.api.base._
import org.jetbrains.plugins.scala.lang.psi.api.base.types._
import org.jetbrains.plugins.scala.lang.psi.api.expr.{ScSuperReference, ScThisReference, ScUnderScoreSectionUtil}
import org.jetbrains.plugins.scala.lang.psi.api.statements._
import org.jetbrains.plugins.scala.lang.psi.api.statements.params.ScTypeParam
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.ScTypeParametersOwner
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.{ScObject, ScTemplateDefinition}
import org.jetbrains.plugins.scala.lang.psi.api.{InferUtil, ScalaElementVisitor}
import org.jetbrains.plugins.scala.lang.psi.impl.toplevel.synthetic.ScSyntheticClass
import org.jetbrains.plugins.scala.lang.psi.types
import org.jetbrains.plugins.scala.lang.psi.types.Compatibility.Expression
import org.jetbrains.plugins.scala.lang.psi.types._
import org.jetbrains.plugins.scala.lang.psi.types.nonvalue.{Parameter, ScMethodType, ScTypePolymorphicType, TypeParameter}
import org.jetbrains.plugins.scala.lang.psi.types.result.{Failure, Success, TypeResult, TypingContext}
import org.jetbrains.plugins.scala.lang.resolve.ScalaResolveResult

import scala.collection.immutable.HashMap

/**
 * @author <NAME>
 * Date: 22.02.2008
 */

class ScSimpleTypeElementImpl(node: ASTNode) extends ScalaPsiElementImpl(node) with ScSimpleTypeElement {
  override def toString: String = "SimpleTypeElement: " + getText

  def singleton = getNode.findChildByType(ScalaTokenTypes.kTYPE) != null

  def findConstructor: Option[ScConstructor] = {
    getContext match {
      case constr: ScConstructor => Some(constr)
      case param: ScParameterizedTypeElement =>
        param.getContext match {
          case constr: ScConstructor => Some(constr)
          case _ => None
        }
      case _ => None
    }
  }

  protected def innerType(ctx: TypingContext): TypeResult[ScType] = innerNonValueType(ctx, inferValueType = true)

  override def getTypeNoConstructor(ctx: TypingContext): TypeResult[ScType] = {
    CachesUtil.getWithRecursionPreventingWithRollback(this, CachesUtil.SIMPLE_TYPE_ELEMENT_TYPE_NO_CONSTRUCTOR_KEY,
      new CachesUtil.MyProvider[ScSimpleTypeElement, TypeResult[ScType]](
        this, elem => innerNonValueType(ctx, inferValueType = true, noConstructor = true)
      )(PsiModificationTracker.MODIFICATION_COUNT), Failure("Recursive type of type element", Some(this)))
  }

  override def getNonValueType(ctx: TypingContext): TypeResult[ScType] = {
    CachesUtil.getWithRecursionPreventingWithRollback(this, CachesUtil.NON_VALUE_TYPE_ELEMENT_TYPE_KEY,
        new CachesUtil.MyProvider[ScSimpleTypeElementImpl, TypeResult[ScType]](
        this, elem => elem.innerNonValueType(ctx, inferValueType = false)
      )(PsiModificationTracker.MODIFICATION_COUNT), Failure("Recursive non value type of type element", Some(this)))
  }

  private def innerNonValueType(ctx: TypingContext, inferValueType: Boolean, noConstructor: Boolean = false): TypeResult[ScType] = {
    ProgressManager.checkCanceled()
    val lift: (ScType) => Success[ScType] = Success(_, Some(this))

    def parametrise(tp: ScType, clazz: PsiClass, subst: ScSubstitutor): ScType = {
      if (clazz.getTypeParameters.length == 0) {
        tp
      } else {
        ScParameterizedType(tp, clazz.getTypeParameters.map {
          case tp: ScTypeParam => new ScTypeParameterType(tp, subst)
          case ptp             => new ScTypeParameterType(ptp, subst)
        })
      }
    }

    def getConstructorParams(constr: PsiMethod, subst: ScSubstitutor): (Seq[Seq[Parameter]], Boolean) = {
      constr match {
        case fun: ScFunction =>
          (fun.effectiveParameterClauses.map(_.parameters.mapWithIndex {
            case (p, index) =>
              val paramType: ScType = subst.subst(p.getType(TypingContext.empty).getOrAny)
              new Parameter(p.name, p.deprecatedName,
                paramType, paramType, p.isDefaultParam,
                p.isRepeatedParameter, p.isCallByNameParameter, index, Some(p))
          }),
            fun.parameterList.clauses.lastOption.exists(_.isImplicit))
        case f: ScPrimaryConstructor =>
          (f.effectiveParameterClauses.map(_.parameters.mapWithIndex {
            case (p, index) =>
              val paramType: ScType = subst.subst(p.getType(TypingContext.empty).getOrAny)
              new Parameter(p.name, p.deprecatedName,
                paramType, paramType, p.isDefaultParam,
                p.isRepeatedParameter, p.isCallByNameParameter, index, Some(p))
          }),
            f.parameterList.clauses.lastOption.exists(_.isImplicit))
        case m: PsiMethod =>
          (Seq(m.getParameterList.getParameters.toSeq.mapWithIndex {
            case (p, index) => new Parameter("", None, p.paramType, false, p.isVarArgs, false, index)
          }), false)
      }
    }

    def updateImplicits(tp: ScType, withExpected: Boolean, params: Seq[Seq[Parameter]], lastImplicit: Boolean): ScType = {
      if (lastImplicit) {
        //Let's add implicit parameters
        val newTp = tp match {
          case ScTypePolymorphicType(i, p) =>
            ScTypePolymorphicType(ScMethodType(i, params.last, isImplicit = true)(getProject, getResolveScope), p)
          case _ => ScMethodType(tp, params.last, isImplicit = true)(getProject, getResolveScope)
        }
        val res = InferUtil.updateTypeWithImplicitParameters(newTp, this, None, withExpected)
        implicitParameters = res._2
        res._1
      } else tp
    }

    def typeForConstructor(ref: ScStableCodeReferenceElement, constr: PsiMethod,
                           _subst: ScSubstitutor, parentElement: PsiNamedElement): ScType = {
      val clazz = constr.containingClass
      val (constrTypParameters: Seq[ScTypeParam], constrSubst: ScSubstitutor) = parentElement match {<commit_msg>Fixed problem with Java varargs in constructor invocation. #SCL-7388 Comment<commit_after>package org.jetbrains.plugins.scala
package lang
package psi
package impl
package base
package types

import com.intellij.lang.ASTNode
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi._
import com.intellij.psi.util.{PsiModificationTracker, PsiTreeUtil}
import org.jetbrains.plugins.scala.caches.CachesUtil
import org.jetbrains.plugins.scala.extensions._
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiUtil.SafeCheckException
import org.jetbrains.plugins.scala.lang.psi.api.base._
import org.jetbrains.plugins.scala.lang.psi.api.base.types._
import org.jetbrains.plugins.scala.lang.psi.api.expr.{ScSuperReference, ScThisReference, ScUnderScoreSectionUtil}
import org.jetbrains.plugins.scala.lang.psi.api.statements._
import org.jetbrains.plugins.scala.lang.psi.api.statements.params.ScTypeParam
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.ScTypeParametersOwner
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.{ScObject, ScTemplateDefinition}
import org.jetbrains.plugins.scala.lang.psi.api.{InferUtil, ScalaElementVisitor}
import org.jetbrains.plugins.scala.lang.psi.impl.toplevel.synthetic.ScSyntheticClass
import org.jetbrains.plugins.scala.lang.psi.types
import org.jetbrains.plugins.scala.lang.psi.types.Compatibility.Expression
import org.jetbrains.plugins.scala.lang.psi.types._
import org.jetbrains.plugins.scala.lang.psi.types.nonvalue.{Parameter, ScMethodType, ScTypePolymorphicType, TypeParameter}
import org.jetbrains.plugins.scala.lang.psi.types.result.{Failure, Success, TypeResult, TypingContext}
import org.jetbrains.plugins.scala.lang.resolve.ScalaResolveResult

import scala.collection.immutable.HashMap

/**
 * @author <NAME>
 * Date: 22.02.2008
 */

class ScSimpleTypeElementImpl(node: ASTNode) extends ScalaPsiElementImpl(node) with ScSimpleTypeElement {
  override def toString: String = "SimpleTypeElement: " + getText

  def singleton = getNode.findChildByType(ScalaTokenTypes.kTYPE) != null

  def findConstructor: Option[ScConstructor] = {
    getContext match {
      case constr: ScConstructor => Some(constr)
      case param: ScParameterizedTypeElement =>
        param.getContext match {
          case constr: ScConstructor => Some(constr)
          case _ => None
        }
      case _ => None
    }
  }

  protected def innerType(ctx: TypingContext): TypeResult[ScType] = innerNonValueType(ctx, inferValueType = true)

  override def getTypeNoConstructor(ctx: TypingContext): TypeResult[ScType] = {
    CachesUtil.getWithRecursionPreventingWithRollback(this, CachesUtil.SIMPLE_TYPE_ELEMENT_TYPE_NO_CONSTRUCTOR_KEY,
      new CachesUtil.MyProvider[ScSimpleTypeElement, TypeResult[ScType]](
        this, elem => innerNonValueType(ctx, inferValueType = true, noConstructor = true)
      )(PsiModificationTracker.MODIFICATION_COUNT), Failure("Recursive type of type element", Some(this)))
  }

  override def getNonValueType(ctx: TypingContext): TypeResult[ScType] = {
    CachesUtil.getWithRecursionPreventingWithRollback(this, CachesUtil.NON_VALUE_TYPE_ELEMENT_TYPE_KEY,
        new CachesUtil.MyProvider[ScSimpleTypeElementImpl, TypeResult[ScType]](
        this, elem => elem.innerNonValueType(ctx, inferValueType = false)
      )(PsiModificationTracker.MODIFICATION_COUNT), Failure("Recursive non value type of type element", Some(this)))
  }

  private def innerNonValueType(ctx: TypingContext, inferValueType: Boolean, noConstructor: Boolean = false): TypeResult[ScType] = {
    ProgressManager.checkCanceled()
    val lift: (ScType) => Success[ScType] = Success(_, Some(this))

    def parametrise(tp: ScType, clazz: PsiClass, subst: ScSubstitutor): ScType = {
      if (clazz.getTypeParameters.length == 0) {
        tp
      } else {
        ScParameterizedType(tp, clazz.getTypeParameters.map {
          case tp: ScTypeParam => new ScTypeParameterType(tp, subst)
          case ptp             => new ScTypeParameterType(ptp, subst)
        })
      }
    }

    def getConstructorParams(constr: PsiMethod, subst: ScSubstitutor): (Seq[Seq[Parameter]], Boolean) = {
      constr match {
        case fun: ScFunction =>
          (fun.effectiveParameterClauses.map(_.parameters.mapWithIndex {
            case (p, index) =>
              val paramType: ScType = subst.subst(p.getType(TypingContext.empty).getOrAny)
              new Parameter(p.name, p.deprecatedName,
                paramType, paramType, p.isDefaultParam,
                p.isRepeatedParameter, p.isCallByNameParameter, index, Some(p))
          }),
            fun.parameterList.clauses.lastOption.exists(_.isImplicit))
        case f: ScPrimaryConstructor =>
          (f.effectiveParameterClauses.map(_.parameters.mapWithIndex {
            case (p, index) =>
              val paramType: ScType = subst.subst(p.getType(TypingContext.empty).getOrAny)
              new Parameter(p.name, p.deprecatedName,
                paramType, paramType, p.isDefaultParam,
                p.isRepeatedParameter, p.isCallByNameParameter, index, Some(p))
          }),
            f.parameterList.clauses.lastOption.exists(_.isImplicit))
        case m: PsiMethod =>
          (Seq(m.getParameterList.getParameters.toSeq.mapWithIndex {
            case (p, index) => new Parameter("", None, p.exactParamType(), false, p.isVarArgs, false, index)
          }), false)
      }
    }

    def updateImplicits(tp: ScType, withExpected: Boolean, params: Seq[Seq[Parameter]], lastImplicit: Boolean): ScType = {
      if (lastImplicit) {
        //Let's add implicit parameters
        val newTp = tp match {
          case ScTypePolymorphicType(i, p) =>
            ScTypePolymorphicType(ScMethodType(i, params.last, isImplicit = true)(getProject, getResolveScope), p)
          case _ => ScMethodType(tp, params.last, isImplicit = true)(getProject, getResolveScope)
        }
        val res = InferUtil.updateTypeWithImplicitParameters(newTp, this, None, withExpected)
        implicitParameters = res._2
        res._1
      } else tp
    }

    def typeForConstructor(ref: ScStableCodeReferenceElement, constr: PsiMethod,
                           _subst: ScSubstitutor, parentElement: PsiNamedElement): ScType = {
      val clazz = constr.containingClass
      val (constrTypParameters: Seq[ScTypeParam], constrSubst: ScSubstitutor) = parentElement match {
{'fraction_non_alphanumeric': 0.10205191978859009, 'fraction_numerical': 0.002020830094823566, 'mean_word_length': 3.786830357142857, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 41, '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': '4445741', 'n_tokens_mistral': 3950, 'n_tokens_neox': 3839, 'n_words': 705}