tscfg.generators.scala.ScalaUtil.scala Maven / Gradle / Ivy
The 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"
)
}