xsbt.ClassName.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of compiler-bridge_2.13.0-M5 Show documentation
Show all versions of compiler-bridge_2.13.0-M5 Show documentation
Incremental compiler of Scala
The newest version!
/*
* Zinc - The incremental compiler for Scala.
* Copyright 2011 - 2017, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* This software is released under the terms written in LICENSE.
*/
package xsbt
import scala.tools.nsc.Global
/**
* Utility methods for creating (source|binary) class names for a Symbol.
*/
trait ClassName extends Compat {
val global: Global
import global._
/**
* Creates a flat (binary) name for a class symbol `s`.
*/
protected def flatname(s: Symbol, separator: Char) =
enteringPhase(currentRun.flattenPhase.next) { s fullName separator }
/**
* Create a (source) name for a class symbol `s`.
*/
protected def className(s: Symbol): Name = pickledName(s)
/**
* Create a String (source) name for a class symbol `s`.
*/
protected def classNameAsString(s: Symbol): String = pickledNameAsString(s)
/**
* Given a class symbol `cls`, construct a name representing this constructor.
* For a class:
*
* a.b.Foo
*
* this is:
*
* a;b;Foo;init;
*
* The prefix is important to avoid name hashing all constructors together
* (see #97), the weird format is necessary to avoid scalac or zinc trying to
* interpret this name (in particular we should not use '.' and we should not
* use ''), we use ';' because it is one of the few characters that
* cannot appear in a valid JVM name.
*/
protected def constructorName(cls: Symbol): Name =
newTermName(constructorNameAsString(cls))
protected def constructorNameAsString(cls: Symbol): String =
cls.fullName(';') ++ ";init;"
/**
* Mangle a JVM symbol name in a format better suited for internal uses by sbt.
*/
protected def mangledName(s: Symbol): Name =
if (s.name == nme.CONSTRUCTOR)
constructorName(s.enclClass)
else
s.name
/**
* Create a (source) name for the class symbol `s` with a prefix determined by the class symbol `in`.
*
* If `s` represents a package object `pkg3`, then the returned name will be `pkg1.pkg2.pkg3.package`.
* If `s` represents a class `Foo` nested in package object `pkg3` then the returned name is `pkg1.pkg2.pk3.Foo`.
*
* Note that some objects with special access rights are encoded in names
* (like qualified privates `private[qualifier]`). In order to get the right
* original names, we need to use `unexpandedName`.
*/
protected def classNameAsSeenIn(in: Symbol, s: Symbol): String =
enteringPhase(currentRun.picklerPhase.next) {
if (in.isRoot || in.isRootPackage || in == NoSymbol || in.isEffectiveRoot)
s.simpleName.toString
else if (in.isPackageObjectOrClass)
in.owner.fullName + "." + s.unexpandedName
else
in.fullName + "." + s.unexpandedName
}
private def pickledName(s: Symbol): Name =
enteringPhase(currentRun.picklerPhase.next) { s.fullNameAsName('.') }
private def pickledNameAsString(s: Symbol): String =
enteringPhase(currentRun.picklerPhase.next) { s.fullName }
protected def isTopLevelModule(sym: Symbol): Boolean =
enteringPhase(currentRun.picklerPhase.next) {
sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass
}
protected def flatclassName(s: Symbol, sep: Char, dollarRequired: Boolean): String =
flatname(s, sep) + (if (dollarRequired) "$" else "")
}