<commit_before>/*******************************************************************************
    Copyright (c) 2012-2013, KAIST, S-Core.
    All rights reserved.

    Use is subject to license terms.

    This distribution may include materials developed by third parties.
 ******************************************************************************/

package kr.ac.kaist.jsaf.nodes_util

import _root_.java.util.ArrayList
import kr.ac.kaist.jsaf.nodes._
import kr.ac.kaist.jsaf.nodes_util.{ NodeUtil => NU }
import kr.ac.kaist.jsaf.scala_src.nodes._
import kr.ac.kaist.jsaf.scala_src.useful.Lists._
import kr.ac.kaist.jsaf.scala_src.useful.Options._
import kr.ac.kaist.jsaf.scala_src.useful.Sets._
import edu.rice.cs.plt.iter.IterUtil
import edu.rice.cs.plt.tuple.Option

object JSAstToConcrete extends Walker {

  val width = 50
  var internal = false
  var testWith = false
  val significantBits = NU.significantBits

  def doit(node: ASTNode): String = walk(node)
  def doitInternal(node: ASTNode) = {
    internal = true
    walk(node)
  }
  def doitTestWith(node: ASTNode) = {
    testWith = true
    walk(node)
  }

  /* indentation utilities *************************************************/
  var indent = 0
  val tab: StringBuilder = new StringBuilder("  ")
  def increaseIndent = indent += 1
  def decreaseIndent = indent -= 1
  def getIndent = {
    val s: StringBuilder = new StringBuilder
    for (i <- 0 to indent-1) s.append(tab)
    s.toString
  }
  def isOneline(node: Any):Boolean = node match {
    case SBlock => false
    case Some(in) => isOneline(in)
    case _ => !(node.isInstanceOf[Block])
  }

  /* utility methods ********************************************************/

  /*  make sure it is parenthesized */
  def inParentheses(str: String) =
    if (str.startsWith("(") && str.endsWith(")")) str
    else new StringBuilder("(").append(str).append(")").toString

  def join(all: List[Any], sep: String, result: StringBuilder): StringBuilder = all match {
    case Nil => result
    case _ => result.length match {
      case 0 => {
        join(all.tail, sep, result.append(walk(all.head)))
      }
      case _ =>
        if (result.length > width && sep.equals(", "))
          join(all.tail, sep, result.append(", \n"+getIndent).append(walk(all.head)))
        else
          join(all.tail, sep, result.append(sep).append(walk(all.head)))
    }
  }

  var uniq_id = 0
  def fresh() = { uniq_id += 1; uniq_id.toString }
  type Env = List[(String, String)]
  var env = Nil.asInstanceOf[Env]
  def addE(uniq: String, new_uniq: String) = env = (uniq, new_uniq)::env
  def getE(uniq: String): String = env.find(p => p._1.equals(uniq)) match {
    case None =>
      val new_uniq = fresh
      addE(uniq, new_uniq)
      new_uniq
    case Some((_, new_uniq)) => new_uniq
  }

  def pp(s: StringBuilder, str: String) = {
    for (c <- str) c match {
      case '\u0008' => s.append("\\b")
      case '\t' => s.append("\\t")
      case '\n' => s.append("\\n")
      case '\f' => s.append("\\f")
      case '\r' => s.append("\\r")
      case '\u000b' => s.append("\\v")
      case '"'  => s.append("\"")
      case '\'' => s.append("'")
      case '\\' => s.append("\\")
      case c => s.append(c+"")
    }
  }

  def prFtn(s: StringBuilder, fds: List[FunDecl], vds: List[VarDecl],
            body: List[SourceElement]) = {
    fds match {
      case Nil =>
      case _ =>
        increaseIndent
        s.append(getIndent).append(join(fds, "\n"+getIndent, new StringBuilder("")))
        decreaseIndent
        s.append("\n").append(getIndent)
    }
    vds match {
      case Nil =>
      case _ =>
        increaseIndent
        s.append(getIndent)
        vds.foreach(vd => vd match {
                    case SVarDecl(_,n,_,_) =>
                      s.append("var "+n.getText+";\n"+getIndent)})
        decreaseIndent
        s.append("\n").append(getIndent)
      }
    increaseIndent
    s.append(getIndent).append(join(body, "\n"+getIndent, new StringBuilder("")))
    decreaseIndent
  }

  class StringBuilderHelper(s: StringBuilder) {
    def toStringP() = new StringBuilder("(").append(s.toString).append(")").toString
  }
  implicit def stringBuilderWrapper(s: StringBuilder) = new StringBuilderHelper(s)

  /* The rule of separators(indentation, semicolon and newline) in unparsing pattern matchings.
   * This rule is applied recursively
   * Principle: All case already has indentation at the front and newline at the end.
   *
   * Root case: See [case SProgram].
   *    program's type is List<SourceElement>.
   *    Each <SourceElement> has indentation at the front
   *    and newline at the end to keep the principle.
   *
   * Branch case(Stmt or ListofStmt): SBlock, SFunDecl, SVarStmt, SExprStmt...
   *    Add indentation and newline to keep the principle in inner cases.
   *    When its type is [Stmt], add ";" at the end.
   *
   * Leaf case(not Stmt, may have inner case): SExprList, SArrayExpr, ...
   *    Don't add indentation, newline and ";".
   *    They are already added.
   *    But other separators(like ", " or " ") may be added.
   *
   */
  override def walk(node:Any):String = node match {
    case SArrayExpr(info, elements) =>
      val s: StringBuilder = new StringBuilder
      s.append(walk(info))
      s.append("[")
      elements.foreach(_ match {
        case Some(e) => s.append(walk(e)).append(", ")
        case None => s.append("undefined").append(", ")
      })
      s.append("]")
      s.toString
    case SArrayNumberExpr(info, elements) =>
      val s: StringBuilder = new StringBuilder
      s.append(walk(info))
      s.append("[")
      s.append("A LOT!!! "+elements.size+" elements are not printed here.")
      s.append("]")
      s.toString<commit_msg>do not include trailing comma in array literals<commit_after>/*******************************************************************************
    Copyright (c) 2012-2013, KAIST, S-Core.
    All rights reserved.

    Use is subject to license terms.

    This distribution may include materials developed by third parties.
 ******************************************************************************/

package kr.ac.kaist.jsaf.nodes_util

import _root_.java.util.ArrayList
import kr.ac.kaist.jsaf.nodes._
import kr.ac.kaist.jsaf.nodes_util.{ NodeUtil => NU }
import kr.ac.kaist.jsaf.scala_src.nodes._
import kr.ac.kaist.jsaf.scala_src.useful.Lists._
import kr.ac.kaist.jsaf.scala_src.useful.Options._
import kr.ac.kaist.jsaf.scala_src.useful.Sets._
import edu.rice.cs.plt.iter.IterUtil
import edu.rice.cs.plt.tuple.Option

object JSAstToConcrete extends Walker {

  val width = 50
  var internal = false
  var testWith = false
  val significantBits = NU.significantBits

  def doit(node: ASTNode): String = walk(node)
  def doitInternal(node: ASTNode) = {
    internal = true
    walk(node)
  }
  def doitTestWith(node: ASTNode) = {
    testWith = true
    walk(node)
  }

  /* indentation utilities *************************************************/
  var indent = 0
  val tab: StringBuilder = new StringBuilder("  ")
  def increaseIndent = indent += 1
  def decreaseIndent = indent -= 1
  def getIndent = {
    val s: StringBuilder = new StringBuilder
    for (i <- 0 to indent-1) s.append(tab)
    s.toString
  }
  def isOneline(node: Any):Boolean = node match {
    case SBlock => false
    case Some(in) => isOneline(in)
    case _ => !(node.isInstanceOf[Block])
  }

  /* utility methods ********************************************************/

  /*  make sure it is parenthesized */
  def inParentheses(str: String) =
    if (str.startsWith("(") && str.endsWith(")")) str
    else new StringBuilder("(").append(str).append(")").toString

  def join(all: List[Any], sep: String, result: StringBuilder): StringBuilder = all match {
    case Nil => result
    case _ => result.length match {
      case 0 => {
        join(all.tail, sep, result.append(walk(all.head)))
      }
      case _ =>
        if (result.length > width && sep.equals(", "))
          join(all.tail, sep, result.append(", \n"+getIndent).append(walk(all.head)))
        else
          join(all.tail, sep, result.append(sep).append(walk(all.head)))
    }
  }

  var uniq_id = 0
  def fresh() = { uniq_id += 1; uniq_id.toString }
  type Env = List[(String, String)]
  var env = Nil.asInstanceOf[Env]
  def addE(uniq: String, new_uniq: String) = env = (uniq, new_uniq)::env
  def getE(uniq: String): String = env.find(p => p._1.equals(uniq)) match {
    case None =>
      val new_uniq = fresh
      addE(uniq, new_uniq)
      new_uniq
    case Some((_, new_uniq)) => new_uniq
  }

  def pp(s: StringBuilder, str: String) = {
    for (c <- str) c match {
      case '\u0008' => s.append("\\b")
      case '\t' => s.append("\\t")
      case '\n' => s.append("\\n")
      case '\f' => s.append("\\f")
      case '\r' => s.append("\\r")
      case '\u000b' => s.append("\\v")
      case '"'  => s.append("\"")
      case '\'' => s.append("'")
      case '\\' => s.append("\\")
      case c => s.append(c+"")
    }
  }

  def prFtn(s: StringBuilder, fds: List[FunDecl], vds: List[VarDecl],
            body: List[SourceElement]) = {
    fds match {
      case Nil =>
      case _ =>
        increaseIndent
        s.append(getIndent).append(join(fds, "\n"+getIndent, new StringBuilder("")))
        decreaseIndent
        s.append("\n").append(getIndent)
    }
    vds match {
      case Nil =>
      case _ =>
        increaseIndent
        s.append(getIndent)
        vds.foreach(vd => vd match {
                    case SVarDecl(_,n,_,_) =>
                      s.append("var "+n.getText+";\n"+getIndent)})
        decreaseIndent
        s.append("\n").append(getIndent)
      }
    increaseIndent
    s.append(getIndent).append(join(body, "\n"+getIndent, new StringBuilder("")))
    decreaseIndent
  }

  class StringBuilderHelper(s: StringBuilder) {
    def toStringP() = new StringBuilder("(").append(s.toString).append(")").toString
  }
  implicit def stringBuilderWrapper(s: StringBuilder) = new StringBuilderHelper(s)

  /* The rule of separators(indentation, semicolon and newline) in unparsing pattern matchings.
   * This rule is applied recursively
   * Principle: All case already has indentation at the front and newline at the end.
   *
   * Root case: See [case SProgram].
   *    program's type is List<SourceElement>.
   *    Each <SourceElement> has indentation at the front
   *    and newline at the end to keep the principle.
   *
   * Branch case(Stmt or ListofStmt): SBlock, SFunDecl, SVarStmt, SExprStmt...
   *    Add indentation and newline to keep the principle in inner cases.
   *    When its type is [Stmt], add ";" at the end.
   *
   * Leaf case(not Stmt, may have inner case): SExprList, SArrayExpr, ...
   *    Don't add indentation, newline and ";".
   *    They are already added.
   *    But other separators(like ", " or " ") may be added.
   *
   */
  override def walk(node:Any):String = node match {
    case SArrayExpr(info, elements) =>
      val s: StringBuilder = new StringBuilder
      s.append(walk(info))
      s.append("[")
      elements match {
        case Nil => ()
        case head :: tail =>
          head match {
            case Some(e) => s.append(walk(e))
            case None => s.append("undefined")
          }
          tail.foreach(_ match {
            case Some(e) => s.append(", ").append(walk(e))
            case None => s.append(", ").append("undefined")
          })
      }
      s.append("]")
      s.toString
    case SArrayNumberExpr(info, elements) =>
      val s: StringBuilder = new StringBuilder
      s.append(walk(info))
      s.append("[")
      s.append("A LOT!!! "+elements.size+" elements are not printed here.")
      s.append("]")
      s.toString
{'fraction_non_alphanumeric': 0.1826212520173278, 'fraction_numerical': 0.004416886095302812, 'mean_word_length': 2.772508811278436, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 75, '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': '131948', 'n_tokens_mistral': 3809, 'n_tokens_neox': 3706, 'n_words': 949}