<commit_before>/* NSC -- new Scala compiler
 * Copyright 2006-2011 LAMP/EPFL
 * @author  <NAME>
 */

package scala.tools.nsc
package util

import scala.reflect.internal.Chars._

/** Utilitity methods for doc comment strings
 */
object DocStrings {

  /** Returns index of string `str` following `start` skipping longest
   *  sequence of whitespace characters characters (but no newlines)
   */
  def skipWhitespace(str: String, start: Int): Int =
    if (start < str.length && isWhitespace(str charAt start)) skipWhitespace(str, start + 1)
    else start

  /** Returns index of string `str` following `start` skipping
   *  sequence of identifier characters.
   */
  def skipIdent(str: String, start: Int): Int =
    if (start < str.length && isIdentifierPart(str charAt start)) skipIdent(str, start + 1)
    else start

  /** Returns index of string `str` after `start` skipping longest
   *  sequence of space and tab characters, possibly also containing
   *  a single `*` character or the `/``**` sequence.
   *  @pre  start == str.length || str(start) == `\n'
   */
  def skipLineLead(str: String, start: Int): Int =
    if (start == str.length) start
    else {
      val idx = skipWhitespace(str, start + 1)
      if (idx < str.length && (str charAt idx) == '*') skipWhitespace(str, idx + 1)
      else if (idx + 2 < str.length && (str charAt idx) == '/' && (str charAt (idx + 1)) == '*' && (str charAt (idx + 2)) == '*')
        skipWhitespace(str, idx + 3)
      else idx
    }

  /** Skips to next occurrence of `\n' or to the position after the `/``**` sequence following index `start`.
   */
  def skipToEol(str: String, start: Int): Int =
    if (start + 2 < str.length && (str charAt start) == '/' && (str charAt (start + 1)) == '*' && (str charAt (start + 2)) == '*') start + 3
    else if (start < str.length && (str charAt start) != '\n') skipToEol(str, start + 1)
    else start

  /** Returns first index following `start` and starting a line (i.e. after skipLineLead) or starting the comment
   *  which satisfies predicate `p`.
   */
  def findNext(str: String, start: Int)(p: Int => Boolean): Int = {
    val idx = skipLineLead(str, skipToEol(str, start))
    if (idx < str.length && !p(idx)) findNext(str, idx)(p)
    else idx
  }

  /** Return first index following `start` and starting a line (i.e. after skipLineLead)
   *  which satisfies predicate `p`.
   */
  def findAll(str: String, start: Int)(p: Int => Boolean): List[Int] = {
    val idx = findNext(str, start)(p)
    if (idx == str.length) List()
    else idx :: findAll(str, idx)(p)
  }

  /** Produces a string index, which is a list of ``sections'', i.e
   *  pairs of start/end positions of all tagged sections in the string.
   *  Every section starts with a `@` and extends to the next `@`, or
   *  to the end of the comment string, but excluding the final two
   *  characters which terminate the comment.
   *  
   *  Also take usecases into account - they need to expand until the next 
   *  @usecase or the end of the string, as they might include other sections 
   *  of their own 
   */
  def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] =
    findAll(str, 0) (idx => str(idx) == '@' && p(idx)) match {
      case List() => List()
      case idxs => {
        val idxs2 = mergeUsecaseSections(str, idxs)
        idxs2 zip (idxs2.tail ::: List(str.length - 2))
      }
    }
  
  /**
   * Merge sections following an @usecase into the usecase comment, so they 
   * can override the parent symbol's sections 
   */
  def mergeUsecaseSections(str: String, idxs: List[Int]): List[Int] = {
    idxs.find(str.substring(_).startsWith("@usecase")) match {
      case Some(firstUC) =>
        val commentSections = idxs.take(idxs.indexOf(firstUC))
        val usecaseSections = idxs.drop(idxs.indexOf(firstUC)).filter(str.substring(_).startsWith("@usecase"))
        commentSections ::: usecaseSections
      case None =>
        idxs
    }
  }
  
  /** Does interval `iv` start with given `tag`?
   */
  def startsWithTag(str: String, section: (Int, Int), tag: String): Boolean =
    startsWithTag(str, section._1, tag)

  def startsWithTag(str: String, start: Int, tag: String): Boolean =
    str.startsWith(tag, start) && !isIdentifierPart(str charAt (start + tag.length))<commit_msg>Fixed misplaced @usecase annotation<commit_after>/* NSC -- new Scala compiler
 * Copyright 2006-2011 LAMP/EPFL
 * @author  <NAME>
 */

package scala.tools.nsc
package util

import scala.reflect.internal.Chars._

/** Utilitity methods for doc comment strings
 */
object DocStrings {

  /** Returns index of string `str` following `start` skipping longest
   *  sequence of whitespace characters characters (but no newlines)
   */
  def skipWhitespace(str: String, start: Int): Int =
    if (start < str.length && isWhitespace(str charAt start)) skipWhitespace(str, start + 1)
    else start

  /** Returns index of string `str` following `start` skipping
   *  sequence of identifier characters.
   */
  def skipIdent(str: String, start: Int): Int =
    if (start < str.length && isIdentifierPart(str charAt start)) skipIdent(str, start + 1)
    else start

  /** Returns index of string `str` after `start` skipping longest
   *  sequence of space and tab characters, possibly also containing
   *  a single `*` character or the `/``**` sequence.
   *  @pre  start == str.length || str(start) == `\n'
   */
  def skipLineLead(str: String, start: Int): Int =
    if (start == str.length) start
    else {
      val idx = skipWhitespace(str, start + 1)
      if (idx < str.length && (str charAt idx) == '*') skipWhitespace(str, idx + 1)
      else if (idx + 2 < str.length && (str charAt idx) == '/' && (str charAt (idx + 1)) == '*' && (str charAt (idx + 2)) == '*')
        skipWhitespace(str, idx + 3)
      else idx
    }

  /** Skips to next occurrence of `\n' or to the position after the `/``**` sequence following index `start`.
   */
  def skipToEol(str: String, start: Int): Int =
    if (start + 2 < str.length && (str charAt start) == '/' && (str charAt (start + 1)) == '*' && (str charAt (start + 2)) == '*') start + 3
    else if (start < str.length && (str charAt start) != '\n') skipToEol(str, start + 1)
    else start

  /** Returns first index following `start` and starting a line (i.e. after skipLineLead) or starting the comment
   *  which satisfies predicate `p`.
   */
  def findNext(str: String, start: Int)(p: Int => Boolean): Int = {
    val idx = skipLineLead(str, skipToEol(str, start))
    if (idx < str.length && !p(idx)) findNext(str, idx)(p)
    else idx
  }

  /** Return first index following `start` and starting a line (i.e. after skipLineLead)
   *  which satisfies predicate `p`.
   */
  def findAll(str: String, start: Int)(p: Int => Boolean): List[Int] = {
    val idx = findNext(str, start)(p)
    if (idx == str.length) List()
    else idx :: findAll(str, idx)(p)
  }

  /** Produces a string index, which is a list of ``sections'', i.e
   *  pairs of start/end positions of all tagged sections in the string.
   *  Every section starts with a `@` and extends to the next `@`, or
   *  to the end of the comment string, but excluding the final two
   *  characters which terminate the comment.
   *  
   *  Also take usecases into account - they need to expand until the next 
   *  usecase or the end of the string, as they might include other sections 
   *  of their own 
   */
  def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] =
    findAll(str, 0) (idx => str(idx) == '@' && p(idx)) match {
      case List() => List()
      case idxs => {
        val idxs2 = mergeUsecaseSections(str, idxs)
        idxs2 zip (idxs2.tail ::: List(str.length - 2))
      }
    }
  
  /**
   * Merge sections following an usecase into the usecase comment, so they 
   * can override the parent symbol's sections 
   */
  def mergeUsecaseSections(str: String, idxs: List[Int]): List[Int] = {
    idxs.find(str.substring(_).startsWith("@usecase")) match {
      case Some(firstUC) =>
        val commentSections = idxs.take(idxs.indexOf(firstUC))
        val usecaseSections = idxs.drop(idxs.indexOf(firstUC)).filter(str.substring(_).startsWith("@usecase"))
        commentSections ::: usecaseSections
      case None =>
        idxs
    }
  }
  
  /** Does interval `iv` start with given `tag`?
   */
  def startsWithTag(str: String, section: (Int, Int), tag: String): Boolean =
    startsWithTag(str, section._1, tag)

  def startsWithTag(str: String, start: Int, tag: String): Boolean =
    str.startsWith(tag, start) && !isIdentifierPart(str charAt (start + tag.length))
{'fraction_non_alphanumeric': 0.1396667438093034, 'fraction_numerical': 0.006248553575561213, 'mean_word_length': 3.0692090395480225, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 23, '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': '6981112', 'n_tokens_mistral': 2821, 'n_tokens_neox': 2746, 'n_words': 942}