<commit_before>//
// AST.scala -- Scala class AST
// Project OrcScala
//
// $Id$
//
// Created by dkitchin on May 27, 2010.
//
// Copyright (c) 2010 The University of Texas at Austin. All rights reserved.
//
// Use and redistribution of this file is governed by the license terms in
// the LICENSE file found in the project's top-level directory and also found at
// URL: http://orc.csres.utexas.edu/license.shtml .
//

package orc

import orc.error.OrcException
import scala.util.parsing.input.Positional
import scala.util.parsing.input.Position
import scala.util.parsing.input.NoPosition

trait AST extends Positional {

  // Location-preserving transform
  def ->[B <: AST](f: this.type => B): B = {
      val location = this.pos
      val result = f(this)
      result.pushDownPosition(location)
      result
  }
  
  // Location transfer.
  // x ->> y  is equivalent to  x -> (_ => y)
  def ->>[B <: AST](that : B): B = { that.pushDownPosition(this.pos); that }

  def !!(exn : OrcException): Nothing = {
      exn.setPosition(this.pos)
      throw exn
  }
  
  // TODO: remove this overloading to uncover uses of !! that do not carry a specific exception type
  def !!(msg : String): Nothing = { 
    val exn = new OrcException(msg)
    this !! exn
  }
  
  // Emit a warning
  def emitWarning(msg : String): Unit = { 
    //FIXME: This should use the compile message recorder -- this is broken for GUI or Web Orc versions 
    Console.err.println("Warning " + this.pos + ": " + msg)
  }
  
  // Set source location at this node and propagate
  // the change to any children without source locations.
  def pushDownPosition(p : Position): Unit = {
    this.pos match {
      case NoPosition => {
        this.setPos(p)
        this.subtrees map { _.pushDownPosition(p) }
      }
      case _ => {  }
    }
  }
  
  // Used to propagate source location information
  // Currently only implemented for OIL
  val subtrees: List[AST] = Nil
  
  
}<commit_msg>Updated AST subtrees with a reflective implementation Fixed doc comments<commit_after>//
// AST.scala -- Scala class AST
// Project OrcScala
//
// $Id$
//
// Created by dkitchin on May 27, 2010.
//
// Copyright (c) 2010 The University of Texas at Austin. All rights reserved.
//
// Use and redistribution of this file is governed by the license terms in
// the LICENSE file found in the project's top-level directory and also found at
// URL: http://orc.csres.utexas.edu/license.shtml .
//

package orc

import orc.error.OrcException
import scala.util.parsing.input.Positional
import scala.util.parsing.input.Position
import scala.util.parsing.input.NoPosition

trait AST extends Positional {

  /**
   * Location-preserving transform
   */
  def ->[B <: AST](f: this.type => B): B = {
      val location = this.pos
      val result = f(this)
      result.pushDownPosition(location)
      result
  }
  
  /**
   * Location transfer.
   * x ->> y  is equivalent to  x -> (_ => y)
   */
  def ->>[B <: AST](that : B): B = { that.pushDownPosition(this.pos); that }

  /**
   */
  def !!(exn : OrcException): Nothing = {
      exn.setPosition(this.pos)
      throw exn
  }
  
  // TODO: remove this overloading to uncover uses of !! that do not carry a specific exception type
  def !!(msg : String): Nothing = { 
    val exn = new OrcException(msg)
    this !! exn
  }
  
  // Emit a warning
  def emitWarning(msg : String): Unit = { 
    //FIXME: This should use the compile message recorder -- this is broken for GUI or Web Orc versions 
    Console.err.println("Warning " + this.pos + ": " + msg)
  }
  
  /**
   * Set source location at this node and propagate
   * the change to any children without source locations.
   */
  def pushDownPosition(p : Position): Unit = {
    this.pos match {
      case NoPosition => {
        this.setPos(p)
        this.subtrees map { _.pushDownPosition(p) }
      }
      case _ => {  }
    }
  }
  
  /**
   * All AST node children of this node, as a single list
   */
  def subtrees: List[AST] = {
    import java.lang.reflect.InvocationTargetException
    import scala.collection.JavaConversions
    import scala.collection.mutable.MutableList

    def flatenAstNodes(x: Any, flatList: MutableList[AST]) {
      def isGood(y: Any): Boolean = y match {
        case _: AST => true
        case i: Iterable[_] => i.forall(isGood(_))
        case _ => false
      }
      def traverseAndAdd(z: Any) {
        z match {
          case a: AST => flatList += a
          case i: Iterable[_] => i.foreach(traverseAndAdd(_))
        }
      }
      if (isGood(x)) traverseAndAdd(x)
    }

    val goodKids = new MutableList[AST]();
    for (m <- this.getClass().getMethods()) {
      val retType = m.getReturnType();
      if (!m.getName().contains("$") && !m.getName.equals("subtrees") && m.getParameterTypes().length == 0 &&
          (classOf[AST].isAssignableFrom(retType) || classOf[java.lang.Iterable[_]].isAssignableFrom(retType) || classOf[scala.collection.Iterable[_]].isAssignableFrom(retType))) {
        try {
          flatenAstNodes(m.invoke(this), goodKids);
        } catch {
          case e: InvocationTargetException => { } // Disregard silently
        }
      }
    }
    goodKids.toList
  }
  
}
{'fraction_non_alphanumeric': 0.12454423335252351, 'fraction_numerical': 0.004029936672423719, 'mean_word_length': 2.502688172043011, 'pattern_counts': {'":': 2, '<': 8, '<?xml version=': 0, '>': 29, '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': '2456571', 'n_tokens_mistral': 1707, 'n_tokens_neox': 1627, 'n_words': 489}