<commit_before>/**
* @author ven
*/
package org.jetbrains.plugins.scala
package lang
package psi
package types


import api.base.ScReferenceElement
import com.intellij.psi.{PsiTypeParameterListOwner, PsiTypeParameter, PsiSubstitutor, PsiClass}
import com.intellij.openapi.util.Key
import collection.immutable.{Map, HashMap}
import com.intellij.openapi.project.Project
import api.statements.ScTypeAlias
import java.lang.String
import nonvalue.{Parameter, TypeParameter, ScTypePolymorphicType, ScMethodType}
import org.jetbrains.annotations.NotNull

object ScSubstitutor {
  val empty = new ScSubstitutor()

  val key: Key[ScSubstitutor] = Key.create("scala substitutor key")
}

class ScSubstitutor(val tvMap: Map[String, ScType],
                    val aliasesMap: Map[String, Suspension[ScType]],
                    val outerMap: Map[PsiClass, Tuple2[ScType, ScReferenceElement]]) {
  def this() = this (Map.empty, Map.empty, Map.empty)

  def this(tvMap: Map[String, ScType],
                    aliasesMap: Map[String, Suspension[ScType]],
                    outerMap: Map[PsiClass, Tuple2[ScType, ScReferenceElement]], follower: ScSubstitutor) = {
    this(tvMap, aliasesMap, outerMap)
    this.follower = follower
  }

  private var follower: ScSubstitutor = null

  override def toString: String = "ScSubstitutor(" + tvMap + ", " + aliasesMap + ", " + outerMap + ")" +
    (if (follower != null) " followed " + follower.toString else "")

  def bindT(name : String, t: ScType) = new ScSubstitutor(tvMap + ((name, t)), aliasesMap, outerMap, follower)
  def bindA(name: String, t: ScType) = new ScSubstitutor(tvMap, aliasesMap + ((name, new Suspension[ScType](t))), outerMap, follower)
  def bindA(name: String, f: () => ScType) = new ScSubstitutor(tvMap, aliasesMap + ((name, new Suspension[ScType](f))), outerMap, follower)
  def bindO(outer: PsiClass, t: ScType, ref : ScReferenceElement) = new ScSubstitutor(tvMap, aliasesMap, outerMap + ((outer, (t, ref))), follower)
  def incl(s: ScSubstitutor) = new ScSubstitutor(s.tvMap ++ tvMap, s.aliasesMap ++ aliasesMap, s.outerMap ++ outerMap, follower)
  def followed(s: ScSubstitutor) : ScSubstitutor = new ScSubstitutor(tvMap, aliasesMap, outerMap,
    if (follower != null) follower followed s else s)

  def subst(t: ScType): ScType = if (follower != null) follower.subst(substInternal(t)) else substInternal(t)

  protected def substInternal(t: ScType) : ScType = t match {
    case f@ScFunctionType(ret, params) => new ScFunctionType(substInternal(ret), 
      collection.immutable.Seq(params.map(substInternal _).toSeq : _*), f.isImplicit)
    case t1@ScTupleType(comps) => new ScTupleType(comps map {substInternal _}, t1.getProject)
    case ScProjectionType(proj, ref) => new ScProjectionType(substInternal(proj), ref)<commit_msg>SCL-1655 Catch StackOverflowError, and rethrow in an exception containin the type and substitutor to help diagnose the problem.<commit_after>/**
* @author ven
*/
package org.jetbrains.plugins.scala
package lang
package psi
package types


import api.base.ScReferenceElement
import com.intellij.psi.{PsiTypeParameterListOwner, PsiTypeParameter, PsiSubstitutor, PsiClass}
import com.intellij.openapi.util.Key
import collection.immutable.{Map, HashMap}
import com.intellij.openapi.project.Project
import api.statements.ScTypeAlias
import java.lang.String
import nonvalue.{Parameter, TypeParameter, ScTypePolymorphicType, ScMethodType}
import org.jetbrains.annotations.NotNull

object ScSubstitutor {
  val empty = new ScSubstitutor()

  val key: Key[ScSubstitutor] = Key.create("scala substitutor key")
}

class ScSubstitutor(val tvMap: Map[String, ScType],
                    val aliasesMap: Map[String, Suspension[ScType]],
                    val outerMap: Map[PsiClass, Tuple2[ScType, ScReferenceElement]]) {
  def this() = this (Map.empty, Map.empty, Map.empty)

  def this(tvMap: Map[String, ScType],
                    aliasesMap: Map[String, Suspension[ScType]],
                    outerMap: Map[PsiClass, Tuple2[ScType, ScReferenceElement]], follower: ScSubstitutor) = {
    this(tvMap, aliasesMap, outerMap)
    this.follower = follower
  }

  private var follower: ScSubstitutor = null

  override def toString: String = "ScSubstitutor(" + tvMap + ", " + aliasesMap + ", " + outerMap + ")" +
    (if (follower != null) " followed " + follower.toString else "")

  def bindT(name : String, t: ScType) = new ScSubstitutor(tvMap + ((name, t)), aliasesMap, outerMap, follower)
  def bindA(name: String, t: ScType) = new ScSubstitutor(tvMap, aliasesMap + ((name, new Suspension[ScType](t))), outerMap, follower)
  def bindA(name: String, f: () => ScType) = new ScSubstitutor(tvMap, aliasesMap + ((name, new Suspension[ScType](f))), outerMap, follower)
  def bindO(outer: PsiClass, t: ScType, ref : ScReferenceElement) = new ScSubstitutor(tvMap, aliasesMap, outerMap + ((outer, (t, ref))), follower)
  def incl(s: ScSubstitutor) = new ScSubstitutor(s.tvMap ++ tvMap, s.aliasesMap ++ aliasesMap, s.outerMap ++ outerMap, follower)
  def followed(s: ScSubstitutor) : ScSubstitutor = new ScSubstitutor(tvMap, aliasesMap, outerMap,
    if (follower != null) follower followed s else s)

  def subst(t: ScType): ScType = try {
    if (follower != null) follower.subst(substInternal(t)) else substInternal(t)
  }
  catch {
    case s: StackOverflowError => throw new RuntimeException("StackOverFlow during ScSubstitutor.subst(" + t + ") this = " + this, s)
  }

  protected def substInternal(t: ScType) : ScType = t match {
    case f@ScFunctionType(ret, params) => new ScFunctionType(substInternal(ret), 
      collection.immutable.Seq(params.map(substInternal _).toSeq : _*), f.isImplicit)
    case t1@ScTupleType(comps) => new ScTupleType(comps map {substInternal _}, t1.getProject)
    case ScProjectionType(proj, ref) => new ScProjectionType(substInternal(proj), ref)
{'fraction_non_alphanumeric': 0.12175989085948158, 'fraction_numerical': 0.0020463847203274215, 'mean_word_length': 4.716374269005848, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 12, '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': '138848', 'n_tokens_mistral': 2008, 'n_tokens_neox': 1885, 'n_words': 476}