Skip to content

Instantly share code, notes, and snippets.

@bakenezumi
Created April 6, 2018 12:25
Show Gist options
  • Save bakenezumi/c8ab1dcd375643ff75caa49f66ce910b to your computer and use it in GitHub Desktop.
Save bakenezumi/c8ab1dcd375643ff75caa49f66ce910b to your computer and use it in GitHub Desktop.
package xsbt
import scala.reflect.NameTransformer
import scala.tools.nsc.Global
object SemanticDBHelper {
def semanticName[GlobalType <: Global](g: GlobalType)(sym: g.Symbol): String = {
var b: java.lang.StringBuffer = null
def loop(size: Int, _sym: g.Symbol): Unit = {
val symName = _sym.name
val nSize = symName.length - (if (symName.endsWith(NameTransformer.LOCAL_SUFFIX_STRING)) 1
else 0)
val prefix =
if (_sym.isTypeParameter || _sym.isTypeSkolem) "["
else if (_sym.isParameter) ".("
else if (_sym.isConstructor) "`"
else ""
@inline
def methodSuffix = {
(if (_sym.isConstructor) "`(" else "(") +
_sym.paramss.flatten
.map { p =>
if (p.isByNameParam) {
"=>" + p.tpe.typeArgs.head.nameAndArgsString
} else if (g.definitions.isRepeatedParamType(p.tpe)) {
p.tpe.typeArgs.head.nameAndArgsString + "*"
} else {
p.tpe.typeSymbol.name
}
}
.mkString(",") +
")" + (if (_sym == sym || sym.isConstructor) "." else "")
}
val suffix =
if (_sym.isTypeParameter || _sym.isTypeSkolem) "]"
else if (_sym.isParameter) ")"
else if (_sym.hasPackageFlag) "."
else if (_sym.isClass || _sym.isType) "#"
else if (_sym.isMethod) methodSuffix
else "."
if (_sym.isRoot || _sym.isRootPackage || _sym == g.NoSymbol || _sym.owner.isEmptyPackage || _sym.owner.isEffectiveRoot) {
val isRoot = _sym.owner.isRoot
val prePrefix = if (isRoot) "_root_." else "_empty_."
val capacity = size + nSize + prePrefix.length + prefix.length + suffix.length
b = new java.lang.StringBuffer(capacity)
b.append(prePrefix)
} else {
val owner =
if (_sym.isTypeParameter || _sym.isTypeSkolem || _sym.isParameter || _sym.owner.isConstructor)
_sym.owner
else _sym.effectiveOwner.enclClass
loop(size + nSize + prefix.length + suffix.length, owner)
}
b.append(prefix)
b.append(g.chrs, symName.start, nSize)
b.append(suffix)
()
}
def isLocal(sym: g.Symbol): Boolean =
sym.isLocalToBlock || sym.owner.isRefinementClass
if ((!sym.isTypeParameter && !sym.isParameter &&
sym.ownersIterator.exists(isLocal)) || sym.hasPackageFlag) {
"" // local definition
} else {
loop(0, sym)
b.toString
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment