<commit_before>package io.joern.c2cpg.astcreation

import io.joern.c2cpg.utils.IOUtils
import io.shiftleft.codepropertygraph.generated.nodes.NewBlock
import io.shiftleft.codepropertygraph.generated.{DispatchTypes, Operators}
import io.shiftleft.x2cpg.Ast
import org.eclipse.cdt.core.dom.ast._
import org.eclipse.cdt.core.dom.ast.c.{ICASTArrayDesignator, ICASTDesignatedInitializer, ICASTFieldDesignator}
import org.eclipse.cdt.core.dom.ast.cpp._
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding
import org.eclipse.cdt.internal.core.dom.parser.cpp.{CPPASTIdExpression, CPPASTQualifiedName, CPPFunction}
import org.eclipse.cdt.internal.core.model.ASTStringUtil

trait AstCreatorHelper {

  this: AstCreator =>

  private var usedNames: Int = 0

  protected def uniqueName(target: String, name: String, fullName: String): (String, String) = {
    if (name.isEmpty && (fullName.isEmpty || fullName.endsWith("."))) {
      val newName = s"anonymous_${target}_$usedNames"
      val newFullName = s"${fullName}anonymous_${target}_$usedNames"
      usedNames = usedNames + 1
      (newName, newFullName)
    } else {
      (name, fullName)
    }
  }

  private def fileLines(node: IASTNode): Seq[Int] = {
    val f = fileName(node)
    global.file2LinesCache.computeIfAbsent(f, _ => IOUtils.readLinesInFile(f).map(_.length))
  }

  private def nullSafeFileLocation(node: IASTNode): Option[IASTFileLocation] =
    Option(parserResult.flattenLocationsToFile(node.getNodeLocations)).map(_.asFileLocation())

  protected def fileName(node: IASTNode): String = {
    nullSafeFileLocation(node).map(_.getFileName).getOrElse(filename)
  }

  protected def line(node: IASTNode): Option[Integer] = {
    nullSafeFileLocation(node).map(_.getStartingLineNumber)
  }

  protected def lineEnd(node: IASTNode): Option[Integer] = {
    nullSafeFileLocation(node).map(_.getEndingLineNumber)
  }

  protected def column(node: IASTNode): Option[Integer] = {
    if (line(node).isEmpty) None
    else {
      val l = line(node).get - 1
      val loc = nullSafeFileLocation(node)
      if (l == 0) {
        loc.map(_.getNodeOffset)
      } else if (loc.map(_.getNodeOffset).contains(0)) {<commit_msg>c2cpg: fix end line number (#685)<commit_after>package io.joern.c2cpg.astcreation

import io.joern.c2cpg.utils.IOUtils
import io.shiftleft.codepropertygraph.generated.nodes.NewBlock
import io.shiftleft.codepropertygraph.generated.{DispatchTypes, Operators}
import io.shiftleft.x2cpg.Ast
import org.eclipse.cdt.core.dom.ast._
import org.eclipse.cdt.core.dom.ast.c.{ICASTArrayDesignator, ICASTDesignatedInitializer, ICASTFieldDesignator}
import org.eclipse.cdt.core.dom.ast.cpp._
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding
import org.eclipse.cdt.internal.core.dom.parser.cpp.{CPPASTIdExpression, CPPASTQualifiedName, CPPFunction}
import org.eclipse.cdt.internal.core.model.ASTStringUtil

trait AstCreatorHelper {

  this: AstCreator =>

  private var usedNames: Int = 0

  protected def uniqueName(target: String, name: String, fullName: String): (String, String) = {
    if (name.isEmpty && (fullName.isEmpty || fullName.endsWith("."))) {
      val newName = s"anonymous_${target}_$usedNames"
      val newFullName = s"${fullName}anonymous_${target}_$usedNames"
      usedNames = usedNames + 1
      (newName, newFullName)
    } else {
      (name, fullName)
    }
  }

  private def fileLines(node: IASTNode): Seq[Int] = {
    val f = fileName(node)
    global.file2LinesCache.computeIfAbsent(f, _ => IOUtils.readLinesInFile(f).map(_.length))
  }

  private def nullSafeFileLocation(node: IASTNode): Option[IASTFileLocation] =
    Option(parserResult.flattenLocationsToFile(node.getNodeLocations)).map(_.asFileLocation())

  private def nullSafeFileLocationLast(node: IASTNode): Option[IASTFileLocation] =
    Option(parserResult.flattenLocationsToFile(node.getNodeLocations.lastOption.toArray)).map(_.asFileLocation())

  protected def fileName(node: IASTNode): String = {
    nullSafeFileLocation(node).map(_.getFileName).getOrElse(filename)
  }

  protected def line(node: IASTNode): Option[Integer] = {
    nullSafeFileLocation(node).map(_.getStartingLineNumber)
  }

  protected def lineEnd(node: IASTNode): Option[Integer] = {
    nullSafeFileLocationLast(node).map(_.getEndingLineNumber)
  }

  protected def column(node: IASTNode): Option[Integer] = {
    if (line(node).isEmpty) None
    else {
      val l = line(node).get - 1
      val loc = nullSafeFileLocation(node)
      if (l == 0) {
        loc.map(_.getNodeOffset)
      } else if (loc.map(_.getNodeOffset).contains(0)) {
{'fraction_non_alphanumeric': 0.12384356602186712, 'fraction_numerical': 0.004625735912531539, 'mean_word_length': 4.663095238095238, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '2281792', 'n_tokens_mistral': 1600, 'n_tokens_neox': 1585, 'n_words': 257}