All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tscfg.generators.scala.ScalaUtil.scala Maven / Gradle / Ivy

There is a newer version: 1.1.3
Show newest version
package tscfg.generators.scala

import tscfg.generators.java.javaUtil
import tscfg.util

/** By default [[scalaIdentifier]] uses underscores as needed for various cases
  * that need translation of the given identifier to make it valid Scala.
  * Similarly, [[getClassName]] also does some related logic.
  *
  * With this flag set to true, both methods will change their logic to use
  * backticks instead of replacing or removing the characters that would make
  * the resulting identifiers invalid.
  *
  * @param useBackticks
  *   False by default
  */
class ScalaUtil(useBackticks: Boolean = false) {

  import ScalaUtil._

  /** Returns a valid scala identifier from the given symbol:
    *
    *   - encloses the symbol in backticks if the symbol is a scala reserved
    *     word;
    *   - appends an underscore if the symbol corresponds to a no-arg method in
    *     scope;
    *   - otherwise:
    *     - returns symbol if it is a valid java identifier
    *     - otherwise: if useBackticks is true, encloses symbol in backticks
    *       otherwise, returns `javaGenerator.javaIdentifier(symbol)`
    */
  def scalaIdentifier(symbol: String): String = {
    if (scalaReservedWords.contains(symbol)) "`" + symbol + "`"
    else if (noArgMethodInScope.contains(symbol)) symbol + "_"
    else if (javaUtil.isJavaIdentifier(symbol)) symbol
    else if (useBackticks) "`" + symbol + "`"
    else javaUtil.javaIdentifier(symbol)
  }

  /** Returns a class name from the given symbol. If useBackticks: This is
    * basically capitalizing the first character that can be capitalized. If
    * none, then a `U` is prepended. Otherwise: Since underscores are specially
    * used in generated code, this method camelizes the symbol in case of any
    * underscores.
    */
  def getClassName(symbol: String): String = {
    if (useBackticks) {
      val scalaId = scalaIdentifier(symbol)
      val search  = scalaId.zipWithIndex.find { case (c, _) => c.toUpper != c }
      search match {
        case Some((c, index)) =>
          scalaId.substring(0, index) + c.toUpper + scalaId.substring(index + 1)

        case None =>
          if (scalaId.head == '`')
            "`U" + scalaId.substring(1)
          else
            "U" + scalaId
      }
    }
    else { // preserve behavior until v0.8.4
      // regular javaUtil.javaIdentifier as it might generate underscores:
      val id = javaUtil.javaIdentifier(symbol)
      // note: not scalaIdentifier because we are going to camelize anyway
      val parts = id.split("_")
      val name  = parts.map(util.upperFirst).mkString
      if (name.nonEmpty) scalaIdentifier(name)
      else "U" + id.count(_ == '_') // named based on # of underscores ;)
    }
  }
}

object ScalaUtil {

  /** The ones from Sect 1.1 of the Scala Language Spec, v2.9 plus `_`
    */
  val scalaReservedWords: List[String] = List(
    "_",
    "abstract",
    "case",
    "catch",
    "class",
    "def",
    "do",
    "else",
    "extends",
    "false",
    "final",
    "finally",
    "for",
    "forSome",
    "if",
    "implicit",
    "import",
    "lazy",
    "match",
    "new",
    "null",
    "object",
    "override",
    "package",
    "private",
    "protected",
    "return",
    "sealed",
    "super",
    "this",
    "throw",
    "trait",
    "try",
    "true",
    "type",
    "val",
    "var",
    "while",
    "with",
    "yield"
  )

  val noArgMethodInScope: List[String] = List(
    "clone",
    "finalize",
    "getClass",
    "notify",
    "notifyAll",
    "toString",
    "wait"
  )
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy