mirror of https://github.com/sbt/sbt.git
77 lines
2.9 KiB
Scala
77 lines
2.9 KiB
Scala
package sbt.complete
|
|
|
|
import DefaultParsers._
|
|
import TypeString._
|
|
|
|
/** Basic representation of types parsed from Manifest.toString.
|
|
* This can only represent the structure of parameterized types.
|
|
* All other types are represented by a TypeString with an empty `args`. */
|
|
private[sbt] final class TypeString(val base: String, val args: List[TypeString])
|
|
{
|
|
override def toString =
|
|
if(base.startsWith(FunctionName))
|
|
args.dropRight(1).mkString("(", ",", ")") + " => " + args.last
|
|
else if(base.startsWith(TupleName))
|
|
args.mkString("(",",",")")
|
|
else
|
|
cleanupTypeName(base) + (if(args.isEmpty) "" else args.mkString("[", ",", "]"))
|
|
}
|
|
|
|
private[sbt] object TypeString
|
|
{
|
|
/** Makes the string representation of a type as returned by Manifest.toString more readable.*/
|
|
def cleanup(typeString: String): String =
|
|
parse(typeString, typeStringParser) match {
|
|
case Right(ts) => ts.toString
|
|
case Left(err) => typeString
|
|
}
|
|
|
|
/** Makes a fully qualified type name provided by Manifest.toString more readable.
|
|
* The argument should be just a name (like scala.Tuple2) and not a full type (like scala.Tuple2[Int,Boolean])*/
|
|
def cleanupTypeName(base: String): String =
|
|
dropPrefix(base).replace('$', '.')
|
|
|
|
/** Removes prefixes from a fully qualified type name that are unnecessary in the presence of standard imports for an sbt setting.
|
|
* This does not use the compiler and is therefore a conservative approximation.*/
|
|
def dropPrefix(base: String): String =
|
|
if(base.startsWith(SbtPrefix))
|
|
base.substring(SbtPrefix.length)
|
|
else if(base.startsWith(CollectionPrefix))
|
|
{
|
|
val simple = base.substring(CollectionPrefix.length)
|
|
if(ShortenCollection(simple)) simple else base
|
|
}
|
|
else if(base.startsWith(ScalaPrefix))
|
|
base.substring(ScalaPrefix.length)
|
|
else if(base.startsWith(JavaPrefix))
|
|
base.substring(JavaPrefix.length)
|
|
else
|
|
TypeMap.getOrElse(base, base)
|
|
|
|
final val CollectionPrefix = "scala.collection."
|
|
final val FunctionName = "scala.Function"
|
|
final val TupleName = "scala.Tuple"
|
|
final val SbtPrefix = "sbt."
|
|
final val ScalaPrefix = "scala."
|
|
final val JavaPrefix = "java.lang."
|
|
/* scala.collection.X -> X */
|
|
val ShortenCollection = Set("Seq", "List", "Set", "Map", "Iterable")
|
|
val TypeMap = Map(
|
|
"java.io.File" -> "File",
|
|
"java.net.URL" -> "URL",
|
|
"java.net.URI" -> "URI"
|
|
)
|
|
|
|
/** A Parser that extracts basic structure from the string representation of a type from Manifest.toString.
|
|
* This is rudimentary and essentially only decomposes the string into names and arguments for parameterized types.
|
|
* */
|
|
lazy val typeStringParser: Parser[TypeString] =
|
|
{
|
|
def isFullScalaIDChar(c: Char) = isScalaIDChar(c) || c == '.' || c == '$'
|
|
lazy val fullScalaID = identifier(IDStart, charClass(isFullScalaIDChar, "Scala identifier character") )
|
|
lazy val tpe: Parser[TypeString] =
|
|
for( id <- fullScalaID; args <- ('[' ~> rep1sep(tpe, ',') <~ ']').?) yield
|
|
new TypeString(id, args.toList.flatten)
|
|
tpe
|
|
}
|
|
} |