<commit_before>package dotty.tools.dotc
package printing

import core._
import Texts._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._
import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annotation
import StdNames.nme
import ast.Trees._, ast.untpd
import java.lang.Integer.toOctalString
import scala.annotation.switch

class PlainPrinter(_ctx: Context) extends Printer {
  protected[this] implicit val ctx = _ctx

  protected def maxToTextRecursions = 100

  protected final def controlled(op: => Text): Text =
    if (ctx.toTextRecursions < maxToTextRecursions)
      try {
        ctx.toTextRecursions += 1
        op
      } finally {
        ctx.toTextRecursions -= 1
      }
    else {
      recursionLimitExceeeded()
      "..."
    }

  protected def recursionLimitExceeeded() = {
    ctx.warning("Exceeded recursion depth attempting to print type.")
    (new Throwable).printStackTrace
  }

  /** Render elements alternating with `sep` string */
  protected def toText(elems: Traversable[Showable], sep: String) =
    Text(elems map (_ toText this), sep)

  /** Render element within highest precedence */
  protected def toTextLocal(elem: Showable): Text =
    atPrec(DotPrec) { elem.toText(this) }

  /** Render element within lowest precedence */
  protected def toTextGlobal(elem: Showable): Text =
    atPrec(GlobalPrec) { elem.toText(this) }

  protected def toTextLocal(elems: Traversable[Showable], sep: String) =
    atPrec(DotPrec) { toText(elems, sep) }

  protected def toTextGlobal(elems: Traversable[Showable], sep: String) =
    atPrec(GlobalPrec) { toText(elems, sep) }

  /** If the name of the symbol's owner should be used when you care about
   *  seeing an interesting name: in such cases this symbol is e.g. a method
   *  parameter with a synthetic name, a constructor named "this", an object
   *  "package", etc.  The kind string, if non-empty, will be phrased relative
   *  to the name of the owner.
   */
  protected def hasMeaninglessName(sym: Symbol) = (
       (sym is Param) && sym.owner.isSetter    // x$1
    || sym.isClassConstructor                  // this
    || (sym.name == nme.PACKAGE)               // package
  )

  def nameString(name: Name): String = name.toString + {
    if (ctx.settings.debugNames.value)
      if (name.isTypeName) "/T" else "/V"
    else ""
  }

  def toText(name: Name): Text = Str(nameString(name))

  /** String representation of a name used in a refinement
   *  In refined printing this undoes type parameter expansion
   */
  protected def refinementNameString(tp: RefinedType) = nameString(tp.refinedName)

  /** String representation of a refinement */
  protected def toTextRefinement(rt: RefinedType) =
    (refinementNameString(rt) ~ toTextRHS(rt.refinedInfo)).close

  /** The longest sequence of refinement types, starting at given type
   *  and following parents.
   */
  private def refinementChain(tp: Type): List[Type] =
    tp :: (tp match {
      case RefinedType(parent, _) => refinementChain(parent)
      case _ => Nil
    })

  def toText(tp: Type): Text = controlled {
    tp match {
      case tp: TypeType =>
        toTextRHS(tp)
      case tp: TermRef if !tp.knownDenotation =>
        toTextRef(tp) ~ ".type"
      case tp: TermRef if tp.denot.isOverloaded =>
        "<overloaded " ~ toTextRef(tp) ~ ">"
      case tp: SingletonType =>
        toText(tp.underlying) ~ "(" ~ toTextRef(tp) ~ ")"
      case tp @ TypeRef(pre, name) =>
        toTextPrefix(pre) ~ selectionString(tp)
      case tp: RefinedType =>
        // return tp.toString // !!! DEBUG
        val parent :: (refined: List[RefinedType]) =
          refinementChain(tp).reverse
        toTextLocal(parent) ~ "{" ~ Text(refined map toTextRefinement, "; ").close ~ "}"
      case AndType(tp1, tp2) =>
        changePrec(AndPrec) { toText(tp1) ~ " & " ~ toText(tp2) }
      case OrType(tp1, tp2) =>
        changePrec(OrPrec) { toText(tp1) ~ " | " ~ toText(tp2) }
      case ErrorType =>
        "<error>"
      case tp: WildcardType =>
        if (tp.optBounds.exists) "?" ~ toTextRHS(tp.bounds) else "?"
      case NoType =>
        "<notype>"
      case NoPrefix =>
        "<noprefix>"
      case tp: MethodType =>
        def paramText(name: TermName, tp: Type) = toText(name) ~ ": " ~ toText(tp)
        changePrec(GlobalPrec) {
          (if (tp.isImplicit) "(implicit " else "(") ~
            Text((tp.paramNames, tp.paramTypes).zipped map paramText, ", ") ~
          ")" ~ toText(tp.resultType)
        }<commit_msg>Avoiding duplication for printing modules.<commit_after>package dotty.tools.dotc
package printing

import core._
import Texts._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._
import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annotation
import StdNames.nme
import ast.Trees._, ast.untpd
import java.lang.Integer.toOctalString
import scala.annotation.switch

class PlainPrinter(_ctx: Context) extends Printer {
  protected[this] implicit val ctx = _ctx

  protected def maxToTextRecursions = 100

  protected final def controlled(op: => Text): Text =
    if (ctx.toTextRecursions < maxToTextRecursions)
      try {
        ctx.toTextRecursions += 1
        op
      } finally {
        ctx.toTextRecursions -= 1
      }
    else {
      recursionLimitExceeeded()
      "..."
    }

  protected def recursionLimitExceeeded() = {
    ctx.warning("Exceeded recursion depth attempting to print type.")
    (new Throwable).printStackTrace
  }

  /** Render elements alternating with `sep` string */
  protected def toText(elems: Traversable[Showable], sep: String) =
    Text(elems map (_ toText this), sep)

  /** Render element within highest precedence */
  protected def toTextLocal(elem: Showable): Text =
    atPrec(DotPrec) { elem.toText(this) }

  /** Render element within lowest precedence */
  protected def toTextGlobal(elem: Showable): Text =
    atPrec(GlobalPrec) { elem.toText(this) }

  protected def toTextLocal(elems: Traversable[Showable], sep: String) =
    atPrec(DotPrec) { toText(elems, sep) }

  protected def toTextGlobal(elems: Traversable[Showable], sep: String) =
    atPrec(GlobalPrec) { toText(elems, sep) }

  /** If the name of the symbol's owner should be used when you care about
   *  seeing an interesting name: in such cases this symbol is e.g. a method
   *  parameter with a synthetic name, a constructor named "this", an object
   *  "package", etc.  The kind string, if non-empty, will be phrased relative
   *  to the name of the owner.
   */
  protected def hasMeaninglessName(sym: Symbol) = (
       (sym is Param) && sym.owner.isSetter    // x$1
    || sym.isClassConstructor                  // this
    || (sym.name == nme.PACKAGE)               // package
  )

  def nameString(name: Name): String = name.toString + {
    if (ctx.settings.debugNames.value)
      if (name.isTypeName) "/T" else "/V"
    else ""
  }

  def toText(name: Name): Text = Str(nameString(name))

  /** String representation of a name used in a refinement
   *  In refined printing this undoes type parameter expansion
   */
  protected def refinementNameString(tp: RefinedType) = nameString(tp.refinedName)

  /** String representation of a refinement */
  protected def toTextRefinement(rt: RefinedType) =
    (refinementNameString(rt) ~ toTextRHS(rt.refinedInfo)).close

  /** The longest sequence of refinement types, starting at given type
   *  and following parents.
   */
  private def refinementChain(tp: Type): List[Type] =
    tp :: (tp match {
      case RefinedType(parent, _) => refinementChain(parent)
      case _ => Nil
    })

  def toText(tp: Type): Text = controlled {
    tp match {
      case tp: TypeType =>
        toTextRHS(tp)
      case tp: TermRef if !tp.knownDenotation =>
        toTextRef(tp) ~ ".type"
      case tp: TermRef if tp.denot.isOverloaded =>
        "<overloaded " ~ toTextRef(tp) ~ ">"
      case tp: TermRef if tp.symbol is Module =>
        toText(tp.underlying)
      case tp: SingletonType =>
        toText(tp.underlying) ~ "(" ~ toTextRef(tp) ~ ")"
      case tp @ TypeRef(pre, name) =>
        toTextPrefix(pre) ~ selectionString(tp)
      case tp: RefinedType =>
        // return tp.toString // !!! DEBUG
        val parent :: (refined: List[RefinedType]) =
          refinementChain(tp).reverse
        toTextLocal(parent) ~ "{" ~ Text(refined map toTextRefinement, "; ").close ~ "}"
      case AndType(tp1, tp2) =>
        changePrec(AndPrec) { toText(tp1) ~ " & " ~ toText(tp2) }
      case OrType(tp1, tp2) =>
        changePrec(OrPrec) { toText(tp1) ~ " | " ~ toText(tp2) }
      case ErrorType =>
        "<error>"
      case tp: WildcardType =>
        if (tp.optBounds.exists) "?" ~ toTextRHS(tp.bounds) else "?"
      case NoType =>
        "<notype>"
      case NoPrefix =>
        "<noprefix>"
      case tp: MethodType =>
        def paramText(name: TermName, tp: Type) = toText(name) ~ ": " ~ toText(tp)
        changePrec(GlobalPrec) {
          (if (tp.isImplicit) "(implicit " else "(") ~
            Text((tp.paramNames, tp.paramTypes).zipped map paramText, ", ") ~
          ")" ~ toText(tp.resultType)
        }
{'fraction_non_alphanumeric': 0.12145660706498038, 'fraction_numerical': 0.0030527692978630614, 'mean_word_length': 2.881929750317393, 'pattern_counts': {'":': 2, '<': 13, '<?xml version=': 0, '>': 44, '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': '2552195', 'n_tokens_mistral': 2920, 'n_tokens_neox': 2859, 'n_words': 766}