aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2017-04-11 11:49:40 +0200
committerGitHub <noreply@github.com>2017-04-11 11:49:40 +0200
commit579571e05a08120133173933e7eaf2555846d1d7 (patch)
tree7b0c89291126e89a901a8ab1230f874e26e25515
parent4ff656138a2e4e127b763adeee3f0f72d515f6b6 (diff)
parent87608bded1fb23519a829fa7f6ee14d4b6a515dc (diff)
downloaddotty-579571e05a08120133173933e7eaf2555846d1d7.tar.gz
dotty-579571e05a08120133173933e7eaf2555846d1d7.tar.bz2
dotty-579571e05a08120133173933e7eaf2555846d1d7.zip
Merge pull request #2128 from dotty-staging/add-semantic-names
Delay name mangling
-rw-r--r--compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/FromTasty.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala17
-rw-r--r--compiler/src/dotty/tools/dotc/ast/TreeInfo.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Trees.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/ast/tpd.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/config/ScalaSettings.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/Contexts.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala42
-rw-r--r--compiler/src/dotty/tools/dotc/core/Denotations.scala46
-rw-r--r--compiler/src/dotty/tools/dotc/core/Flags.scala29
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameKinds.scala317
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala409
-rw-r--r--compiler/src/dotty/tools/dotc/core/Names.scala455
-rw-r--r--compiler/src/dotty/tools/dotc/core/Scopes.scala73
-rw-r--r--compiler/src/dotty/tools/dotc/core/Signature.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala101
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala110
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala75
-rw-r--r--compiler/src/dotty/tools/dotc/core/Symbols.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeApplications.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala13
-rw-r--r--compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala44
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala115
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyBuffer.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala35
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyName.scala30
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala26
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyReader.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala72
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala46
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala59
-rw-r--r--compiler/src/dotty/tools/dotc/core/unpickleScala2/PickleBuffer.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala41
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Scanners.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Tokens.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/package.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/printing/Formatting.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala13
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/transform/CapturedVars.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/Erasure.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/transform/FirstTransform.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/transform/LazyVals.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/transform/LiftTry.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/Mixin.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/MoveStatics.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala24
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala18
-rw-r--r--compiler/src/dotty/tools/dotc/transform/SymUtils.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TailRec.scala37
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TreeChecker.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ValueClasses.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Inliner.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Namer.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/typer/RefChecks.scala17
-rw-r--r--compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala17
-rw-r--r--compiler/src/dotty/tools/dotc/util/NameTransformer.scala5
-rw-r--r--compiler/test/dotc/tests.scala4
-rw-r--r--compiler/test/dotty/tools/DottyTypeStealer.scala2
-rw-r--r--compiler/test/dotty/tools/ShowClassTests.scala2
-rw-r--r--compiler/test/dotty/tools/dotc/ParallelTesting.scala3
81 files changed, 1471 insertions, 1112 deletions
diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
index 77e979e4d..8e054c9c2 100644
--- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
+++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
@@ -30,9 +30,9 @@ import Decorators._
import tpd._
import scala.tools.asm
-import NameOps._
import StdNames.nme
import NameOps._
+import NameKinds.DefaultGetterName
import dotty.tools.dotc.core
import dotty.tools.dotc.core.Names.TypeName
@@ -255,7 +255,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
val evalue = t.symbol.name.toString // value the actual enumeration value.
av.visitEnum(name, edesc, evalue)
} else {
- assert(toDenot(t.symbol).name.toTermName.defaultGetterIndex >= 0) // this should be default getter. do not emmit.
+ assert(toDenot(t.symbol).name.is(DefaultGetterName)) // this should be default getter. do not emmit.
}
case t: SeqLiteral =>
val arrAnnotV: AnnotationVisitor = av.visitArray(name)
@@ -421,7 +421,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
val Flag_METHOD: Flags = Flags.Method.bits
val ExcludedForwarderFlags: Flags = {
Flags.Specialized | Flags.Lifted | Flags.Protected | Flags.JavaStatic |
- Flags.ExpandedName | Flags.Bridge | Flags.VBridge | Flags.Private | Flags.Macro
+ Flags.Bridge | Flags.VBridge | Flags.Private | Flags.Macro
}.bits
@@ -544,8 +544,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def toTermName: Name = n.toTermName
def dropModule: Name = n.stripModuleClassSuffix
- def len: Int = n.length
- def offset: Int = n.start
+ def len: Int = n.toSimpleName.length
+ def offset: Int = n.toSimpleName.start
def isTermName: Boolean = n.isTermName
def startsWith(s: String): Boolean = n.startsWith(s)
}
@@ -557,7 +557,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def fullName: String = sym.showFullName
def simpleName: Name = sym.name
def javaSimpleName: Name = toDenot(sym).name // addModuleSuffix(simpleName.dropLocal)
- def javaBinaryName: Name = toDenot(sym).fullNameSeparated("/") // addModuleSuffix(fullNameInternal('/'))
+ def javaBinaryName: Name = javaClassName.replace('.', '/').toTypeName // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/'))
def javaClassName: String = toDenot(sym).fullName.toString// addModuleSuffix(fullNameInternal('.')).toString
def name: Name = sym.name
def rawname: Name = {
@@ -794,7 +794,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def memberInfo(s: Symbol): Type = tp.memberInfo(s)
- def decls: List[Symbol] = tp.decls.map(_.symbol).toList
+ def decls: List[Symbol] = tp.decls.toList
def members: List[Symbol] =
tp.memberDenots(takeAllFilter, (name, buf) => buf ++= tp.member(name).alternatives).map(_.symbol).toList
diff --git a/compiler/src/dotty/tools/dotc/FromTasty.scala b/compiler/src/dotty/tools/dotc/FromTasty.scala
index b060a2054..da0190fa1 100644
--- a/compiler/src/dotty/tools/dotc/FromTasty.scala
+++ b/compiler/src/dotty/tools/dotc/FromTasty.scala
@@ -17,6 +17,7 @@ import Decorators._
import dotty.tools.dotc.transform.Pickler
import tasty.DottyUnpickler
import ast.tpd._
+import NameKinds.QualifiedName
/** Compiler for TASTY files.
* Usage:
@@ -74,7 +75,7 @@ object FromTasty extends Driver {
case unit: TASTYCompilationUnit =>
val className = unit.className.toTypeName
val clsd =
- if (className.contains('.')) ctx.base.staticRef(className)
+ if (className.is(QualifiedName)) ctx.base.staticRef(className)
else defn.EmptyPackageClass.info.decl(className)
def cannotUnpickle(reason: String) = {
ctx.error(s"class $className cannot be unpickled because $reason")
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index 66fc6bf84..111382b18 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -6,6 +6,7 @@ import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
import Decorators._
+import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
import language.higherKinds
import typer.FrontEnd
import collection.mutable.ListBuffer
@@ -128,7 +129,7 @@ object desugar {
def makeImplicitParameters(tpts: List[Tree], forPrimaryConstructor: Boolean)(implicit ctx: Context) =
for (tpt <- tpts) yield {
val paramFlags: FlagSet = if (forPrimaryConstructor) PrivateLocalParamAccessor else Param
- val epname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX).toTermName
+ val epname = EvidenceParamName.fresh()
ValDef(epname, tpt, EmptyTree).withFlags(paramFlags | Implicit)
}
@@ -186,7 +187,7 @@ object desugar {
case (vparam :: vparams) :: vparamss1 =>
def defaultGetter: DefDef =
DefDef(
- name = meth.name.defaultGetterName(n),
+ name = DefaultGetterName(meth.name, n),
tparams = meth.tparams.map(tparam => dropContextBound(toDefParam(tparam))),
vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam), n),
tpt = TypeTree(),
@@ -230,7 +231,7 @@ object desugar {
private def evidenceParams(meth: DefDef)(implicit ctx: Context): List[ValDef] =
meth.vparamss.reverse match {
case (vparams @ (vparam :: _)) :: _ if vparam.mods is Implicit =>
- vparams.dropWhile(!_.name.startsWith(nme.EVIDENCE_PARAM_PREFIX))
+ vparams.dropWhile(!_.name.is(EvidenceParamName))
case _ =>
Nil
}
@@ -244,7 +245,7 @@ object desugar {
def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = {
if (tdef.mods is PrivateLocalParam) {
val tparam = cpy.TypeDef(tdef)(name = tdef.name.expandedName(ctx.owner))
- .withMods(tdef.mods &~ PrivateLocal | ExpandedName)
+ .withMods(tdef.mods &~ PrivateLocal)
val alias = cpy.TypeDef(tdef)(rhs = refOfDef(tparam))
.withMods(tdef.mods & VarianceFlags | PrivateLocalParamAccessor | Synthetic)
Thicket(tparam, alias)
@@ -402,7 +403,7 @@ object desugar {
def anyRef = ref(defn.AnyRefAlias.typeRef)
def productConstr(n: Int) = {
- val tycon = scalaDot((tpnme.Product.toString + n).toTypeName)
+ val tycon = scalaDot((str.Product + n).toTypeName)
val targs = constrVparamss.head map (_.tpt)
if (targs.isEmpty) tycon else AppliedTypeTree(tycon, targs)
}
@@ -635,7 +636,7 @@ object desugar {
case (named, tpt) :: Nil =>
derivedValDef(original, named, tpt, matchExpr, mods)
case _ =>
- val tmpName = ctx.freshName().toTermName
+ val tmpName = UniqueName.fresh()
val patMods =
mods & Lazy | Synthetic | (if (ctx.owner.isClass) PrivateLocal else EmptyFlags)
val firstDef =
@@ -810,7 +811,7 @@ object desugar {
val selectPos = Position(left.pos.start, op.pos.end, op.pos.start)
Apply(Select(left, op.name).withPos(selectPos), args)
} else {
- val x = ctx.freshName().toTermName
+ val x = UniqueName.fresh()
val selectPos = Position(op.pos.start, right.pos.end, op.pos.start)
new InfixOpBlock(
ValDef(x, TypeTree(), left).withMods(synthetic),
@@ -888,7 +889,7 @@ object desugar {
case id: Ident if isVarPattern(id) && id.name != nme.WILDCARD => (id, id)
case Typed(id: Ident, _) if isVarPattern(id) && id.name != nme.WILDCARD => (pat, id)
case _ =>
- val name = ctx.freshName().toTermName
+ val name = UniqueName.fresh()
(Bind(name, pat), Ident(name))
}
diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
index 037ab73af..f3bce4000 100644
--- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -157,7 +157,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
}
/** Is name a left-associative operator? */
- def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.last != ':')
+ def isLeftAssoc(operator: Name) = !operator.isEmpty && (operator.toSimpleName.last != ':')
/** can this type be a type pattern? */
def mayBeTypePat(tree: untpd.Tree): Boolean = unsplice(tree) match {
diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala
index 20d7c1458..0ff335e40 100644
--- a/compiler/src/dotty/tools/dotc/ast/Trees.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala
@@ -316,7 +316,7 @@ object Trees {
def namePos =
if (pos.exists)
if (rawMods.is(Synthetic)) Position(pos.point, pos.point)
- else Position(pos.point, pos.point + name.stripModuleClassSuffix.length, pos.point)
+ else Position(pos.point, pos.point + name.stripModuleClassSuffix.lastPart.length, pos.point)
else pos
}
diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala
index ff66c8c8e..cd0115a99 100644
--- a/compiler/src/dotty/tools/dotc/ast/tpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala
@@ -12,6 +12,7 @@ import Denotations._, Decorators._, DenotTransformers._
import collection.mutable
import util.{Property, SourceFile, NoSource}
import typer.ErrorReporting._
+import NameKinds.TempResultName
import scala.annotation.tailrec
import scala.io.Codec
@@ -897,7 +898,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def evalOnce(tree: Tree)(within: Tree => Tree)(implicit ctx: Context) = {
if (isIdempotentExpr(tree)) within(tree)
else {
- val vdef = SyntheticValDef(ctx.freshName("ev$").toTermName, tree)
+ val vdef = SyntheticValDef(TempResultName.fresh(), tree)
Block(vdef :: Nil, within(Ident(vdef.namedType)))
}
}
diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
index 49b64d869..63c3d5f74 100644
--- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
+++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -65,9 +65,9 @@ class ScalaSettings extends Settings.SettingGroup {
val YcheckMods = BooleanSetting("-Ycheck-mods", "Check that symbols and their defining trees have modifiers in sync")
val debug = BooleanSetting("-Ydebug", "Increase the quantity of debugging output.")
val debugAlias = BooleanSetting("-Ydebug-alias", "Never follow alias when printing types")
- val debugNames = BooleanSetting("-YdebugNames", "Show name-space indicators when printing names")
val debugTrace = BooleanSetting("-Ydebug-trace", "Trace core operations")
val debugFlags = BooleanSetting("-Ydebug-flags", "Print all flags of definitions")
+ val debugNames = BooleanSetting("-Ydebug-names", "Show internal representation of names")
val debugOwners = BooleanSetting("-Ydebug-owners", "Print all owners of definitions (requires -Yprint-syms)")
val termConflict = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
val log = PhasesSetting("-Ylog", "Log operations during")
diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala
index 8707b66f9..b299de434 100644
--- a/compiler/src/dotty/tools/dotc/core/Contexts.scala
+++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala
@@ -174,9 +174,6 @@ object Contexts {
protected def freshNames_=(freshNames: FreshNameCreator) = _freshNames = freshNames
def freshNames: FreshNameCreator = _freshNames
- def freshName(prefix: String = ""): String = freshNames.newName(prefix)
- def freshName(prefix: Name): String = freshName(prefix.toString)
-
/** A map in which more contextual properties can be stored */
private var _moreProperties: Map[Key[Any], Any] = _
protected def moreProperties_=(moreProperties: Map[Key[Any], Any]) = _moreProperties = moreProperties
@@ -297,7 +294,7 @@ object Contexts {
/** Is this a context that introduces a non-empty scope? */
def isNonEmptyScopeContext: Boolean =
- (this.scope ne outer.scope) && this.scope.nonEmpty
+ (this.scope ne outer.scope) && !this.scope.isEmpty
/** Leave message in diagnostics buffer if it exists */
def diagnose(str: => String) =
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index b70fcb093..c7b1538c7 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -67,7 +67,7 @@ class Definitions {
enterTypeField(cls, name, flags | ClassTypeParamCreationFlags, scope)
private def enterSyntheticTypeParam(cls: ClassSymbol, paramFlags: FlagSet, scope: MutableScope, suffix: String = "T0") =
- enterTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName | paramFlags, scope)
+ enterTypeParam(cls, suffix.toTypeName.expandedName(cls), paramFlags, scope)
// NOTE: Ideally we would write `parentConstrs: => Type*` but SIP-24 is only
// implemented in Dotty and not in Scala 2.
@@ -108,7 +108,7 @@ class Definitions {
* def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
* }
*/
- private def newFunctionNTrait(name: TypeName) = {
+ def newFunctionNTrait(name: TypeName) = {
val completer = new LazyType {
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
val cls = denot.asClass.classSymbol
@@ -119,7 +119,7 @@ class Definitions {
enterTypeParam(cls, name ++ "$T" ++ i.toString, Contravariant, decls)
val resParam = enterTypeParam(cls, name ++ "$R", Covariant, decls)
val (methodType, parentTraits) =
- if (name.startsWith(tpnme.ImplicitFunction)) {
+ if (name.firstPart.startsWith(str.ImplicitFunction)) {
val superTrait =
FunctionType(arity).appliedTo(argParams.map(_.typeRef) ::: resParam.typeRef :: Nil)
(ImplicitMethodType, ctx.normalizeToClassRefs(superTrait :: Nil, cls, decls))
@@ -723,12 +723,11 @@ class Definitions {
/** If type `ref` refers to a class in the scala package, its name, otherwise EmptyTypeName */
def scalaClassName(ref: Type)(implicit ctx: Context): TypeName = scalaClassName(ref.classSymbol)
- private def isVarArityClass(cls: Symbol, prefix: Name) = {
- val name = scalaClassName(cls)
- name.startsWith(prefix) &&
- name.length > prefix.length &&
- name.drop(prefix.length).forall(_.isDigit)
- }
+ private def isVarArityClass(cls: Symbol, prefix: String) =
+ scalaClassName(cls).testSimple(name =>
+ name.startsWith(prefix) &&
+ name.length > prefix.length &&
+ name.drop(prefix.length).forall(_.isDigit))
def isBottomClass(cls: Symbol) =
cls == NothingClass || cls == NullClass
@@ -758,9 +757,9 @@ class Definitions {
*/
def isSyntheticFunctionClass(cls: Symbol) = scalaClassName(cls).isSyntheticFunction
- def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)
- def isTupleClass(cls: Symbol) = isVarArityClass(cls, tpnme.Tuple)
- def isProductClass(cls: Symbol) = isVarArityClass(cls, tpnme.Product)
+ def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, str.AbstractFunction)
+ def isTupleClass(cls: Symbol) = isVarArityClass(cls, str.Tuple)
+ def isProductClass(cls: Symbol) = isVarArityClass(cls, str.Product)
/** Returns the erased class of the function class `cls`
* - FunctionN for N > 22 becomes FunctionXXL
@@ -933,23 +932,6 @@ class Definitions {
// ----- Initialization ---------------------------------------------------
- /** Give the scala package a scope where a FunctionN trait is automatically
- * added when someone looks for it.
- */
- private def makeScalaSpecial()(implicit ctx: Context) = {
- val oldInfo = ScalaPackageClass.classInfo
- val oldDecls = oldInfo.decls
- val newDecls = new MutableScope(oldDecls) {
- override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
- val res = super.lookupEntry(name)
- if (res == null && name.isTypeName && name.isSyntheticFunction)
- newScopeEntry(newFunctionNTrait(name.asTypeName))
- else res
- }
- }
- ScalaPackageClass.info = oldInfo.derivedClassInfo(decls = newDecls)
- }
-
/** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
lazy val syntheticScalaClasses = List(
AnyClass,
@@ -977,8 +959,6 @@ class Definitions {
def init()(implicit ctx: Context) = {
this.ctx = ctx
if (!_isInitialized) {
- makeScalaSpecial()
-
// force initialization of every symbol that is synthesized or hijacked by the compiler
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala
index 7341b96af..fd42bde36 100644
--- a/compiler/src/dotty/tools/dotc/core/Denotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala
@@ -4,8 +4,9 @@ package core
import SymDenotations.{ SymDenotation, ClassDenotation, NoDenotation }
import Contexts.{Context, ContextBase}
-import Names.{Name, PreName}
-import Names.TypeName
+import Names._
+import NameOps._
+import NameKinds._
import StdNames._
import Symbols.NoSymbol
import Symbols._
@@ -1171,27 +1172,42 @@ object Denotations {
* if generateStubs is set, generates stubs for missing top-level symbols
*/
def staticRef(path: Name, generateStubs: Boolean = true)(implicit ctx: Context): Denotation = {
- def recur(path: Name, len: Int): Denotation = {
- val point = path.lastIndexOf('.', len - 1)
- val owner =
- if (point > 0) recur(path.toTermName, point).disambiguate(_.info.isParameterless)
- else if (path.isTermName) defn.RootClass.denot
- else defn.EmptyPackageClass.denot
+ def select(prefix: Denotation, selector: Name): Denotation = {
+ val owner = prefix.disambiguate(_.info.isParameterless)
if (owner.exists) {
- val name = path slice (point + 1, len)
- val result = owner.info.member(name)
- if (result ne NoDenotation) result
+ val result = owner.info.member(selector)
+ if (result.exists) result
else {
val alt =
- if (generateStubs) missingHook(owner.symbol.moduleClass, name)
+ if (generateStubs) missingHook(owner.symbol.moduleClass, selector)
else NoSymbol
- if (alt.exists) alt.denot
- else MissingRef(owner, name)
+ if (alt.exists) alt.denot else MissingRef(owner, selector)
}
}
else owner
}
- recur(path, path.length)
+ def recur(path: Name, wrap: TermName => Name = identity): Denotation = path match {
+ case path: TypeName =>
+ recur(path.toTermName, n => n.toTypeName)
+ case ModuleClassName(underlying) =>
+ recur(underlying, n => wrap(ModuleClassName(n)))
+ case QualifiedName(prefix, selector) =>
+ select(recur(prefix), wrap(selector))
+ case qn @ AnyQualifiedName(prefix, _) =>
+ recur(prefix, n => wrap(qn.info.mkString(n).toTermName))
+ case path: SimpleTermName =>
+ def recurSimple(len: Int, wrap: TermName => Name): Denotation = {
+ val point = path.lastIndexOf('.', len - 1)
+ val selector = wrap(path.slice(point + 1, len).asTermName)
+ val prefix =
+ if (point > 0) recurSimple(point, identity)
+ else if (selector.isTermName) defn.RootClass.denot
+ else defn.EmptyPackageClass.denot
+ select(prefix, selector)
+ }
+ recurSimple(path.length, wrap)
+ }
+ recur(path)
}
/** If we are looking for a non-existing term name in a package,
diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala
index 29f1078a2..84072cd50 100644
--- a/compiler/src/dotty/tools/dotc/core/Flags.scala
+++ b/compiler/src/dotty/tools/dotc/core/Flags.scala
@@ -272,9 +272,6 @@ object Flags {
*/
final val Synthetic = commonFlag(18, "<synthetic>")
- /** Symbol's name is expanded */
- final val ExpandedName = commonFlag(19, "<expandedname>")
-
/** A covariant type variable / an outer accessor */
final val CovariantOrOuter = commonFlag(20, "")
final val Covariant = typeFlag(20, "<covariant>")
@@ -308,19 +305,18 @@ object Flags {
final val CaseAccessor = termFlag(25, "<caseaccessor>")
/** A binding for a type parameter of a base class or trait.
- * TODO: Replace with combination of isType, ExpandedName, and Override?
*/
final val BaseTypeArg = typeFlag(25, "<basetypearg>")
final val CaseAccessorOrBaseTypeArg = CaseAccessor.toCommonFlags
/** A super accessor */
- final val SuperAccessor = termFlag(26, "<superaccessor>")
+ final val Scala2SuperAccessor = termFlag(26, "<superaccessor>")
/** An unpickled Scala 2.x class */
final val Scala2x = typeFlag(26, "<scala-2.x>")
- final val SuperAccessorOrScala2x = SuperAccessor.toCommonFlags
+ final val SuperAccessorOrScala2x = Scala2x.toCommonFlags
/** A method that has default params */
final val DefaultParameterized = termFlag(27, "<defaultparam>")
@@ -409,9 +405,6 @@ object Flags {
final val Scala2ExistentialCommon = commonFlag(55, "<existential>")
final val Scala2Existential = Scala2ExistentialCommon.toTypeFlags
- /** An overloaded symbol (Scala 2.x only) */
- final val Scala2Overloaded = termFlag(56, "<overloaded>")
-
/** A module variable (Scala 2.x only) */
final val Scala2ModuleVar = termFlag(57, "<modulevar>")
@@ -424,6 +417,13 @@ object Flags {
/** A method that is known to have inherited default parameters */
final val InheritedDefaultParams = termFlag(60, "<inherited-default-param>")
+ /** Translation of Scala2's EXPANDEDNAME flag. This flag is never stored in
+ * symbols, is only used locally when reading the flags of a Scala2 symbol.
+ * It's therefore safe to share the code with `InheritedDefaultParams` because
+ * the latter is never present in Scala2 unpickle info.
+ */
+ final val Scala2ExpandedName = InheritedDefaultParams.toCommonFlags
+
/** A method that is known to have no default parameters */
final val NoDefaultParams = termFlag(61, "<no-default-param>")
@@ -452,7 +452,7 @@ object Flags {
final val FromStartFlags =
Module | Package | Deferred | MethodOrHKCommon | Param | ParamAccessor |
Scala2ExistentialCommon | Mutable.toCommonFlags | InSuperCall | Touched | JavaStatic |
- CovariantOrOuter | ContravariantOrLabel | ExpandedName | CaseAccessorOrBaseTypeArg |
+ CovariantOrOuter | ContravariantOrLabel | CaseAccessorOrBaseTypeArg |
Fresh | Frozen | Erroneous | ImplicitCommon | Permanent | Synthetic |
SuperAccessorOrScala2x | Inline
@@ -475,7 +475,7 @@ object Flags {
/** Flags that are passed from a type parameter of a class to a refinement symbol
* that sets the type parameter */
- final val RetainedTypeArgFlags = VarianceFlags | ExpandedName | Protected | Local
+ final val RetainedTypeArgFlags = VarianceFlags | Protected | Local
/** Modules always have these flags set */
final val ModuleCreationFlags = ModuleVal | Lazy | Final | Stable
@@ -502,7 +502,7 @@ object Flags {
*/
final val RetainedModuleValAndClassFlags: FlagSet =
AccessFlags | Package | Case |
- Synthetic | ExpandedName | JavaDefined | JavaStatic | Artifact |
+ Synthetic | JavaDefined | JavaStatic | Artifact |
Erroneous | Lifted | MixedIn | Specialized
/** Flags that can apply to a module val */
@@ -550,9 +550,6 @@ object Flags {
/** A private accessor */
final val PrivateAccessor = allOf(Private, Accessor)
- /** A type parameter with synthesized name */
- final val ExpandedTypeParam = allOf(ExpandedName, TypeParam)
-
/** An inline method */
final val InlineMethod = allOf(Inline, Method)
@@ -578,7 +575,7 @@ object Flags {
final val FinalOrInline = Final | Inline
/** If symbol of a type alias has these flags, prefer the alias */
- final val AliasPreferred = TypeParam | BaseTypeArg | ExpandedName
+ final val AliasPreferred = TypeParam | BaseTypeArg
/** A covariant type parameter instance */
final val LocalCovariant = allOf(Local, Covariant)
diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
new file mode 100644
index 000000000..0f08e4701
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
@@ -0,0 +1,317 @@
+package dotty.tools
+package dotc
+package core
+
+import Names._
+import NameOps._
+import StdNames._
+import util.DotClass
+import tasty.TastyFormat._
+import Decorators._
+import Contexts.Context
+import collection.mutable
+
+object NameKinds {
+
+ // These are sharable since all NameKinds are created eagerly at the start of the program
+ // before any concurrent threads are forked. for this to work, NameKinds should never
+ // be created lazily or in modules that start running after compilers are forked.
+ @sharable private val simpleNameKinds = new mutable.HashMap[Int, ClassifiedNameKind]
+ @sharable private val qualifiedNameKinds = new mutable.HashMap[Int, QualifiedNameKind]
+ @sharable private val uniqueNameKinds = new mutable.HashMap[String, UniqueNameKind]
+
+ abstract class NameInfo extends DotClass {
+ def kind: NameKind
+ def mkString(underlying: TermName): String
+ def map(f: SimpleTermName => SimpleTermName): NameInfo = this
+ }
+
+ abstract class NameKind(val tag: Int) extends DotClass { self =>
+ type ThisInfo <: Info
+ class Info extends NameInfo { this: ThisInfo =>
+ def kind = self
+ def mkString(underlying: TermName) = self.mkString(underlying, this)
+ override def toString = infoString
+ }
+ def definesNewName = false
+ def unmangle(name: SimpleTermName): TermName = name
+ def mkString(underlying: TermName, info: ThisInfo): String
+ def infoString: String
+ }
+
+ object SimpleTermNameKind extends NameKind(UTF8) { self =>
+ type ThisInfo = Info
+ val info = new Info
+ def mkString(underlying: TermName, info: ThisInfo) = unsupported("mkString")
+ def infoString = unsupported("infoString")
+ }
+
+ abstract class ClassifiedNameKind(tag: Int, val infoString: String) extends NameKind(tag) {
+ type ThisInfo = Info
+ val info = new Info
+ def apply(qual: TermName) =
+ qual.derived(info)
+ def unapply(name: DerivedTermName): Option[TermName] = name match {
+ case DerivedTermName(underlying, `info`) => Some(underlying)
+ case _ => None
+ }
+ simpleNameKinds(tag) = this
+ }
+
+ class PrefixNameKind(tag: Int, prefix: String, optInfoString: String = "")
+ extends ClassifiedNameKind(tag, if (optInfoString.isEmpty) s"Prefix $prefix" else optInfoString) {
+ def mkString(underlying: TermName, info: ThisInfo) =
+ underlying.mapLast(n => termName(prefix + n.toString)).toString
+ override def unmangle(name: SimpleTermName): TermName =
+ if (name.startsWith(prefix)) apply(name.drop(prefix.length).asSimpleName)
+ else name
+ }
+
+ class SuffixNameKind(tag: Int, suffix: String, optInfoString: String = "")
+ extends ClassifiedNameKind(tag, if (optInfoString.isEmpty) s"Suffix $suffix" else optInfoString) {
+ def mkString(underlying: TermName, info: ThisInfo) = underlying.toString ++ suffix
+ override def unmangle(name: SimpleTermName): TermName =
+ if (name.endsWith(suffix)) apply(name.take(name.length - suffix.length).asSimpleName)
+ else name
+ }
+
+ trait QualifiedInfo extends NameInfo {
+ val name: SimpleTermName
+ }
+
+ class QualifiedNameKind(tag: Int, val separator: String)
+ extends NameKind(tag) {
+ type ThisInfo = QualInfo
+ case class QualInfo(val name: SimpleTermName) extends Info with QualifiedInfo {
+ override def map(f: SimpleTermName => SimpleTermName): NameInfo = new QualInfo(f(name))
+ override def toString = s"$infoString $name"
+ }
+ def apply(qual: TermName, name: SimpleTermName): TermName =
+ qual.derived(new QualInfo(name))
+
+ /** Overloaded version used only for ExpandedName and TraitSetterName.
+ * Needed because the suffix of an expanded name may itself be expanded.
+ * For example, look at javap of scala.App.initCode
+ */
+ def apply(qual: TermName, name: TermName): TermName = name rewrite {
+ case name: SimpleTermName => apply(qual, name)
+ case AnyQualifiedName(_, _) => apply(qual, name.toSimpleName)
+ }
+
+ def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match {
+ case DerivedTermName(qual, info: this.QualInfo) => Some((qual, info.name))
+ case _ => None
+ }
+
+ override def definesNewName = true
+
+ def mkString(underlying: TermName, info: ThisInfo) =
+ s"$underlying$separator${info.name}"
+ def infoString = s"Qualified $separator"
+
+ qualifiedNameKinds(tag) = this
+ }
+
+ object AnyQualifiedName {
+ def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match {
+ case DerivedTermName(qual, info: QualifiedInfo) =>
+ Some((name.underlying, info.name))
+ case _ => None
+ }
+ }
+
+ trait NumberedInfo extends NameInfo {
+ def num: Int
+ }
+
+ abstract class NumberedNameKind(tag: Int, val infoString: String) extends NameKind(tag) { self =>
+ type ThisInfo = NumberedInfo
+ case class NumberedInfo(val num: Int) extends Info with NameKinds.NumberedInfo {
+ override def toString = s"$infoString $num"
+ }
+ def apply(qual: TermName, num: Int) =
+ qual.derived(new NumberedInfo(num))
+ def unapply(name: DerivedTermName): Option[(TermName, Int)] = name match {
+ case DerivedTermName(underlying, info: this.NumberedInfo) => Some((underlying, info.num))
+ case _ => None
+ }
+ protected def skipSeparatorAndNum(name: SimpleTermName, separator: String): Int = {
+ var i = name.length
+ while (i > 0 && name(i - 1).isDigit) i -= 1
+ if (i > separator.length && i < name.length &&
+ name.slice(i - separator.length, i).toString == separator) i
+ else -1
+ }
+ }
+
+ object AnyNumberedName {
+ def unapply(name: DerivedTermName): Option[(TermName, Int)] = name match {
+ case DerivedTermName(qual, info: NumberedInfo) => Some((qual, info.num))
+ case _ => None
+ }
+ }
+
+ case class UniqueNameKind(val separator: String)
+ extends NumberedNameKind(UNIQUE, s"Unique $separator") {
+ override def definesNewName = true
+ def mkString(underlying: TermName, info: ThisInfo) = {
+ val safePrefix = str.sanitize(underlying.toString + separator)
+ safePrefix + info.num
+ }
+
+ def fresh(prefix: TermName = EmptyTermName)(implicit ctx: Context): TermName =
+ ctx.freshNames.newName(prefix, this)
+
+ uniqueNameKinds(separator) = this
+ }
+
+ object AnyUniqueName {
+ def unapply(name: DerivedTermName): Option[(TermName, String, Int)] = name match {
+ case DerivedTermName(qual, info: NumberedInfo) =>
+ info.kind match {
+ case unique: UniqueNameKind => Some((qual, unique.separator, info.num))
+ case _ => None
+ }
+ case _ => None
+ }
+ }
+
+ val QualifiedName = new QualifiedNameKind(QUALIFIED, ".")
+ val FlatName = new QualifiedNameKind(FLATTENED, "$")
+ val ExpandPrefixName = new QualifiedNameKind(EXPANDPREFIX, "$")
+
+ val ExpandedName = new QualifiedNameKind(EXPANDED, str.EXPAND_SEPARATOR) {
+ private val FalseSuper = termName("$$super")
+ private val FalseSuperLength = FalseSuper.length
+
+ override def unmangle(name: SimpleTermName): TermName = {
+ var i = name.lastIndexOfSlice(str.EXPAND_SEPARATOR)
+ if (i < 0) name
+ else {
+ // Hack to make super accessors from traits work. They would otherwise fail because of #765
+ // The problem is that in `x$$super$$plus` the expansion prefix needs to be `x`
+ // instead of `x$$super`.
+ if (i > FalseSuperLength && name.slice(i - FalseSuperLength, i) == FalseSuper)
+ i -= FalseSuper.length
+
+ apply(name.take(i).asTermName, name.drop(i + str.EXPAND_SEPARATOR.length).asSimpleName)
+ }
+ }
+ }
+
+ val TraitSetterName = new QualifiedNameKind(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR)
+
+ val UniqueName = new UniqueNameKind("$") {
+ override def mkString(underlying: TermName, info: ThisInfo) =
+ if (underlying.isEmpty) "$" + info.num + "$" else super.mkString(underlying, info)
+ }
+
+ val InlineAccessorName = new UniqueNameKind("$_inlineAccessor_$")
+ val TempResultName = new UniqueNameKind("ev$")
+ val EvidenceParamName = new UniqueNameKind("evidence$")
+ val DepParamName = new UniqueNameKind("<param>")
+ val LazyImplicitName = new UniqueNameKind("$_lazy_implicit_$")
+ val LazyLocalName = new UniqueNameKind("$lzy")
+ val LazyLocalInitName = new UniqueNameKind("$lzyINIT")
+ val LazyFieldOffsetName = new UniqueNameKind("$OFFSET")
+ val LazyBitMapName = new UniqueNameKind(nme.BITMAP_PREFIX.toString)
+ val NonLocalReturnKeyName = new UniqueNameKind("nonLocalReturnKey")
+ val WildcardParamName = new UniqueNameKind("_$")
+ val TailLabelName = new UniqueNameKind("tailLabel")
+ val ExceptionBinderName = new UniqueNameKind("ex")
+ val SkolemName = new UniqueNameKind("?")
+ val LiftedTreeName = new UniqueNameKind("liftedTree")
+
+ val UniqueExtMethName = new UniqueNameKind("$extension") {
+ override def unmangle(name: SimpleTermName): TermName = {
+ val i = skipSeparatorAndNum(name, separator)
+ if (i > 0) {
+ val index = name.drop(i).toString.toInt
+ var original = name.take(i - separator.length).asTermName
+ apply(original, index)
+ }
+ else name
+ }
+ }
+
+ val PatMatStdBinderName = new UniqueNameKind("x")
+ val PatMatPiName = new UniqueNameKind("pi") // FIXME: explain what this is
+ val PatMatPName = new UniqueNameKind("p") // FIXME: explain what this is
+ val PatMatOName = new UniqueNameKind("o") // FIXME: explain what this is
+ val PatMatCaseName = new UniqueNameKind("case")
+ val PatMatMatchFailName = new UniqueNameKind("matchFail")
+ val PatMatSelectorName = new UniqueNameKind("selector")
+
+ object DefaultGetterName extends NumberedNameKind(DEFAULTGETTER, "DefaultGetter") {
+ def mkString(underlying: TermName, info: ThisInfo) = {
+ val prefix = if (underlying.isConstructorName) nme.DEFAULT_GETTER_INIT else underlying
+ prefix.toString + str.DEFAULT_GETTER + (info.num + 1)
+ }
+ // TODO: Reduce code duplication with UniqueExtMethName
+ override def unmangle(name: SimpleTermName): TermName = {
+ val i = skipSeparatorAndNum(name, str.DEFAULT_GETTER)
+ if (i > 0) {
+ val index = name.drop(i).toString.toInt - 1
+ var original = name.take(i - str.DEFAULT_GETTER.length).asTermName
+ if (original == nme.DEFAULT_GETTER_INIT) original = Names.CONSTRUCTOR
+ apply(original, index)
+ }
+ else name
+ }
+ }
+
+ object VariantName extends NumberedNameKind(VARIANT, "Variant") {
+ val varianceToPrefix = Map(-1 -> '-', 0 -> '=', 1 -> '+')
+ def mkString(underlying: TermName, info: ThisInfo) = {
+ varianceToPrefix(info.num).toString + underlying
+ }
+ }
+
+ /** Names of the form N_<outer>. Emitted by inliner, replaced by outer path
+ * in ExplicitOuter.
+ */
+ object OuterSelectName extends NumberedNameKind(OUTERSELECT, "OuterSelect") {
+ def mkString(underlying: TermName, info: ThisInfo) = {
+ assert(underlying.isEmpty)
+ info.num + "_<outer>"
+ }
+ }
+
+ val SuperAccessorName = new PrefixNameKind(SUPERACCESSOR, "super$")
+ val InitializerName = new PrefixNameKind(INITIALIZER, "initial$")
+ val ShadowedName = new PrefixNameKind(SHADOWED, "(shadowed)")
+ val ProtectedAccessorName = new PrefixNameKind(PROTECTEDACCESSOR, "protected$")
+ val ProtectedSetterName = new PrefixNameKind(PROTECTEDSETTER, "protected$set") // dubious encoding, kept for Scala2 compatibility
+ val AvoidClashName = new SuffixNameKind(AVOIDCLASH, "$_avoid_name_clash_$")
+ val DirectName = new SuffixNameKind(DIRECT, "$direct")
+ val FieldName = new SuffixNameKind(FIELD, "$$local")
+ val ExtMethName = new SuffixNameKind(EXTMETH, "$extension")
+ val ModuleVarName = new SuffixNameKind(OBJECTVAR, "$module")
+ val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass")
+
+ object SignedName extends NameKind(63) {
+
+ /** @param parts resultSig followed by paramsSig */
+ case class SignedInfo(sig: Signature) extends Info {
+ override def toString = s"$infoString $sig"
+ }
+ type ThisInfo = SignedInfo
+
+ def apply(qual: TermName, sig: Signature) =
+ qual.derived(new SignedInfo(sig))
+ def unapply(name: DerivedTermName): Option[(TermName, Signature)] = name match {
+ case DerivedTermName(underlying, info: SignedInfo) => Some((underlying, info.sig))
+ case _ => None
+ }
+
+ def mkString(underlying: TermName, info: ThisInfo): String = unsupported("mkString")
+ def infoString: String = "Signed"
+ }
+
+ val Scala2MethodNameKinds: List[NameKind] =
+ List(DefaultGetterName, ExtMethName, UniqueExtMethName, ProtectedAccessorName, ProtectedSetterName)
+
+ def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
+ def qualifiedNameKindOfTag : collection.Map[Int, QualifiedNameKind] = qualifiedNameKinds
+ def uniqueNameKindOfSeparator: collection.Map[String, UniqueNameKind] = uniqueNameKinds
+} \ No newline at end of file
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index 240ad359b..915bd52ab 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -4,11 +4,12 @@ package core
import java.security.MessageDigest
import scala.annotation.switch
import scala.io.Codec
-import Names._, StdNames._, Contexts._, Symbols._, Flags._
+import Names._, StdNames._, Contexts._, Symbols._, Flags._, NameKinds._
import Decorators.PreNamedString
import util.{Chars, NameTransformer}
import Chars.isOperatorPart
import Definitions._
+import config.Config
object NameOps {
@@ -48,212 +49,97 @@ object NameOps {
}
}
- class PrefixNameExtractor(pre: TermName) {
- def apply(name: TermName): TermName = pre ++ name
- def unapply(name: TermName): Option[TermName] =
- if (name startsWith pre) Some(name.drop(pre.length).asTermName) else None
- }
-
- object SuperAccessorName extends PrefixNameExtractor(nme.SUPER_PREFIX)
- object InitializerName extends PrefixNameExtractor(nme.INITIALIZER_PREFIX)
-
implicit class NameDecorator[N <: Name](val name: N) extends AnyVal {
import nme._
- def likeTyped(n: PreName): N =
+ def testSimple(f: SimpleTermName => Boolean): Boolean = name match {
+ case name: SimpleTermName => f(name)
+ case name: TypeName => name.toTermName.testSimple(f)
+ case _ => false
+ }
+
+ def likeSpaced(n: PreName): N =
(if (name.isTermName) n.toTermName else n.toTypeName).asInstanceOf[N]
def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR
def isStaticConstructorName = name == STATIC_CONSTRUCTOR
- def isExceptionResultName = name startsWith EXCEPTION_RESULT_PREFIX
- def isImplClassName = name endsWith IMPL_CLASS_SUFFIX
- def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
- def isLoopHeaderLabel = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
- def isProtectedAccessorName = name startsWith PROTECTED_PREFIX
- def isReplWrapperName = name containsSlice INTERPRETER_IMPORT_WRAPPER
- def isTraitSetterName = name containsSlice TRAIT_SETTER_SEPARATOR
- def isSetterName = name endsWith SETTER_SUFFIX
- def isSingletonName = name endsWith SINGLETON_SUFFIX
- def isModuleClassName = name endsWith MODULE_SUFFIX
- def isAvoidClashName = name endsWith AVOID_CLASH_SUFFIX
- def isImportName = name startsWith IMPORT
- def isFieldName = name endsWith LOCAL_SUFFIX
- def isShadowedName = name.length > 0 && name.head == '(' && name.startsWith(nme.SHADOWED)
- def isDefaultGetterName = name.isTermName && name.asTermName.defaultGetterIndex >= 0
- def isScala2LocalSuffix = name.endsWith(" ")
- def isModuleVarName(name: Name): Boolean =
- name.stripAnonNumberSuffix endsWith MODULE_VAR_SUFFIX
- def isSelectorName = name.startsWith(" ") && name.tail.forall(_.isDigit)
- def isLazyLocal = name.endsWith(nme.LAZY_LOCAL)
- def isOuterSelect = name.endsWith(nme.OUTER_SELECT)
- def isInlineAccessor = name.startsWith(nme.INLINE_ACCESSOR_PREFIX)
+ def isLocalDummyName = name startsWith str.LOCALDUMMY_PREFIX
+ def isReplWrapperName = name.toString contains str.INTERPRETER_IMPORT_WRAPPER
+ def isSetterName = name endsWith str.SETTER_SUFFIX
+ def isScala2LocalSuffix = testSimple(_.endsWith(" "))
+ def isSelectorName = testSimple(n => n.startsWith("_") && n.drop(1).forall(_.isDigit))
/** Is name a variable name? */
- def isVariableName: Boolean = name.length > 0 && {
- val first = name.head
- (((first.isLower && first.isLetter) || first == '_')
- && (name != false_)
- && (name != true_)
- && (name != null_))
+ def isVariableName: Boolean = testSimple { n =>
+ n.length > 0 && {
+ val first = n.head
+ (((first.isLower && first.isLetter) || first == '_')
+ && (n != false_)
+ && (n != true_)
+ && (n != null_))
+ }
}
def isOpAssignmentName: Boolean = name match {
case raw.NE | raw.LE | raw.GE | EMPTY =>
false
- case _ =>
+ case name: SimpleTermName =>
name.length > 0 && name.last == '=' && name.head != '=' && isOperatorPart(name.head)
- }
-
- /** If the name ends with $nn where nn are
- * all digits, strip the $ and the digits.
- * Otherwise return the argument.
- */
- def stripAnonNumberSuffix: Name = {
- var pos = name.length
- while (pos > 0 && name(pos - 1).isDigit)
- pos -= 1
-
- if (pos > 0 && pos < name.length && name(pos - 1) == '$')
- name take (pos - 1)
- else
- name
+ case _ =>
+ false
}
/** Convert this module name to corresponding module class name */
- def moduleClassName: TypeName = (name ++ tpnme.MODULE_SUFFIX).toTypeName
+ def moduleClassName: TypeName = name.derived(ModuleClassName).toTypeName
/** Convert this module class name to corresponding source module name */
- def sourceModuleName: TermName = stripModuleClassSuffix.toTermName
-
- /** If name ends in module class suffix, drop it */
- def stripModuleClassSuffix: Name =
- if (isModuleClassName) name dropRight MODULE_SUFFIX.length else name
-
- /** Append a suffix so that this name does not clash with another name in the same scope */
- def avoidClashName: TermName = (name ++ AVOID_CLASH_SUFFIX).toTermName
+ def sourceModuleName: TermName = name.toTermName.exclude(ModuleClassName)
- /** If name ends in "avoid clash" suffix, drop it */
- def stripAvoidClashSuffix: Name =
- if (isAvoidClashName) name dropRight AVOID_CLASH_SUFFIX.length else name
+ /** If name ends in module class suffix, drop it. This
+ * method needs to work on mangled as well as unmangled names because
+ * it is also called from the backend.
+ */
+ def stripModuleClassSuffix: N = likeSpaced {
+ val semName =
+ if (name.isSimple && name.endsWith("$")) name.unmangleClassName else name
+ semName.exclude(ModuleClassName)
+ }
/** If flags is a ModuleClass but not a Package, add module class suffix */
- def adjustIfModuleClass(flags: Flags.FlagSet): N = {
+ def adjustIfModuleClass(flags: Flags.FlagSet): N = likeSpaced {
if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName
- else stripAvoidClashSuffix
- }.asInstanceOf[N]
-
- /** The superaccessor for method with given name */
- def superName: TermName = (nme.SUPER_PREFIX ++ name).toTermName
-
- /** The expanded name of `name` relative to given class `base`.
- */
- def expandedName(base: Symbol, separator: Name)(implicit ctx: Context): N =
- expandedName(if (base is Flags.ExpandedName) base.name else base.fullNameSeparated("$"), separator)
-
- def expandedName(base: Symbol)(implicit ctx: Context): N = expandedName(base, nme.EXPAND_SEPARATOR)
-
- /** The expanded name of `name` relative to `basename` with given `separator`
- */
- def expandedName(prefix: Name, separator: Name = nme.EXPAND_SEPARATOR): N =
- name.fromName(prefix ++ separator ++ name).asInstanceOf[N]
-
- def expandedName(prefix: Name): N = expandedName(prefix, nme.EXPAND_SEPARATOR)
-
- /** Revert the expanded name. Note: This currently gives incorrect results
- * if the normal name contains `nme.EXPAND_SEPARATOR`, i.e. two consecutive '$'
- * signs. This can happen for instance if a super accessor is paired with
- * an encoded name, e.g. super$$plus$eq. See #765.
- */
- def unexpandedName: N = {
- var idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
-
- // Hack to make super accessors from traits work. They would otherwise fail because of #765
- // TODO: drop this once we have more robust name handling
- if (idx > FalseSuperLength && name.slice(idx - FalseSuperLength, idx) == FalseSuper)
- idx -= FalseSuper.length
-
- if (idx < 0) name else (name drop (idx + nme.EXPAND_SEPARATOR.length)).asInstanceOf[N]
+ else name.toTermName.exclude(AvoidClashName)
}
- def expandedPrefix: N = {
- val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
- assert(idx >= 0)
- name.take(idx).asInstanceOf[N]
+ def expandedName(base: Symbol, kind: QualifiedNameKind = ExpandedName)(implicit ctx: Context): N = {
+ val prefix =
+ if (base.name.is(ExpandedName)) base.name else base.fullNameSeparated(ExpandPrefixName)
+ likeSpaced { kind(prefix.toTermName, name.toTermName) }
}
- def shadowedName: N = likeTyped(nme.SHADOWED ++ name)
-
- def revertShadowed: N = likeTyped(name.drop(nme.SHADOWED.length))
-
- def implClassName: N = likeTyped(name ++ tpnme.IMPL_CLASS_SUFFIX)
+ /** Revert the expanded name. */
+ def unexpandedName: N = likeSpaced {
+ name.rewrite { case ExpandedName(_, unexp) => unexp }
+ }
- def errorName: N = likeTyped(name ++ nme.ERROR)
+ def implClassName: N = likeSpaced(name ++ tpnme.IMPL_CLASS_SUFFIX)
- def directName: N = likeTyped(name ++ DIRECT_SUFFIX)
+ def errorName: N = likeSpaced(name ++ nme.ERROR)
- def freshened(implicit ctx: Context): N =
- likeTyped(
- if (name.isModuleClassName) name.stripModuleClassSuffix.freshened.moduleClassName
- else likeTyped(ctx.freshName(name ++ NameTransformer.NAME_JOIN_STRING)))
/** Name with variance prefix: `+` for covariant, `-` for contravariant */
def withVariance(v: Int): N =
- if (hasVariance) dropVariance.withVariance(v)
- else v match {
- case -1 => likeTyped('-' +: name)
- case 1 => likeTyped('+' +: name)
- case 0 => name
- }
-
- /** Does name have a `+`/`-` variance prefix? */
- def hasVariance: Boolean =
- name.nonEmpty && name.head == '+' || name.head == '-'
-
- /** Drop variance prefix if name has one */
- def dropVariance: N = if (hasVariance) likeTyped(name.tail) else name
+ likeSpaced { VariantName(name.exclude(VariantName).toTermName, v) }
/** The variance as implied by the variance prefix, or 0 if there is
* no variance prefix.
*/
- def variance = name.head match {
- case '-' => -1
- case '+' => 1
- case _ => 0
- }
+ def variance = name.collect { case VariantName(_, n) => n }.getOrElse(0)
- /** Translate a name into a list of simple TypeNames and TermNames.
- * In all segments before the last, type/term is determined by whether
- * the following separator char is '.' or '#'. The last segment
- * is of the same type as the original name.
- *
- * Examples:
- *
- * package foo {
- * object Lorax { object Wog ; class Wog }
- * class Lorax { object Zax ; class Zax }
- * }
- *
- * f("foo.Lorax".toTermName) == List("foo": Term, "Lorax": Term) // object Lorax
- * f("foo.Lorax".toTypeName) == List("foo": Term, "Lorax": Type) // class Lorax
- * f("Lorax.Wog".toTermName) == List("Lorax": Term, "Wog": Term) // object Wog
- * f("Lorax.Wog".toTypeName) == List("Lorax": Term, "Wog": Type) // class Wog
- * f("Lorax#Zax".toTermName) == List("Lorax": Type, "Zax": Term) // object Zax
- * f("Lorax#Zax".toTypeName) == List("Lorax": Type, "Zax": Type) // class Zax
- *
- * Note that in actual scala syntax you cannot refer to object Zax without an
- * instance of Lorax, so Lorax#Zax could only mean the type. One might think
- * that Lorax#Zax.type would work, but this is not accepted by the parser.
- * For the purposes of referencing that object, the syntax is allowed.
- */
- def segments: List[Name] = {
- def mkName(name: Name, follow: Char): Name =
- if (follow == '.') name.toTermName else name.toTypeName
-
- name.indexWhere(ch => ch == '.' || ch == '#') match {
- case -1 =>
- if (name.isEmpty) scala.Nil else name :: scala.Nil
- case idx =>
- mkName(name take idx, name(idx)) :: (name drop (idx + 1)).segments
+ def freshened(implicit ctx: Context): N = likeSpaced {
+ name.toTermName match {
+ case ModuleClassName(original) => ModuleClassName(original.freshened)
+ case name => UniqueName.fresh(name)
}
}
@@ -263,7 +149,7 @@ object NameOps {
* - (-1) otherwise
*/
def functionArity: Int =
- functionArityFor(tpnme.Function) max functionArityFor(tpnme.ImplicitFunction)
+ functionArityFor(str.Function) max functionArityFor(str.ImplicitFunction)
/** Is a function name
* - FunctionN for N >= 0
@@ -276,7 +162,7 @@ object NameOps {
* - ImplicitFunctionN for N >= 0
* - false otherwise
*/
- def isImplicitFunction: Boolean = functionArityFor(tpnme.ImplicitFunction) >= 0
+ def isImplicitFunction: Boolean = functionArityFor(str.ImplicitFunction) >= 0
/** Is a synthetic function name
* - FunctionN for N > 22
@@ -284,24 +170,18 @@ object NameOps {
* - false otherwise
*/
def isSyntheticFunction: Boolean = {
- functionArityFor(tpnme.Function) > MaxImplementedFunctionArity ||
- functionArityFor(tpnme.ImplicitFunction) >= 0
+ functionArityFor(str.Function) > MaxImplementedFunctionArity ||
+ functionArityFor(str.ImplicitFunction) >= 0
}
/** Parsed function arity for function with some specific prefix */
- private def functionArityFor(prefix: Name): Int = {
+ private def functionArityFor(prefix: String): Int = {
if (name.startsWith(prefix))
try name.toString.substring(prefix.length).toInt
catch { case _: NumberFormatException => -1 }
else -1
}
- /** The number of hops specified in an outer-select name */
- def outerSelectHops: Int = {
- require(isOuterSelect)
- name.dropRight(nme.OUTER_SELECT.length).toString.toInt
- }
-
/** The name of the generic runtime operation corresponding to an array operation */
def genericArrayOp: TermName = name match {
case nme.apply => nme.array_apply
@@ -338,100 +218,61 @@ object NameOps {
val methodTags: Seq[Name] = (methodTargs zip methodTarsNames).sortBy(_._2).map(x => typeToTag(x._1))
val classTags: Seq[Name] = (classTargs zip classTargsNames).sortBy(_._2).map(x => typeToTag(x._1))
- name.fromName(name ++ nme.specializedTypeNames.prefix ++
+ name.likeSpaced(name ++ nme.specializedTypeNames.prefix ++
methodTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.separator ++
classTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.suffix)
}
/** If name length exceeds allowable limit, replace part of it by hash */
def compactified(implicit ctx: Context): TermName = termName(compactify(name.toString))
- }
- // needed???
- private val Boxed = Map[TypeName, TypeName](
- tpnme.Boolean -> jtpnme.BoxedBoolean,
- tpnme.Byte -> jtpnme.BoxedByte,
- tpnme.Char -> jtpnme.BoxedCharacter,
- tpnme.Short -> jtpnme.BoxedShort,
- tpnme.Int -> jtpnme.BoxedInteger,
- tpnme.Long -> jtpnme.BoxedLong,
- tpnme.Float -> jtpnme.BoxedFloat,
- tpnme.Double -> jtpnme.BoxedDouble)
+ def unmangleClassName: N = name.toTermName match {
+ case name: SimpleTermName
+ if name.endsWith(str.MODULE_SUFFIX) && !nme.falseModuleClassNames.contains(name) =>
+ likeSpaced(name.dropRight(str.MODULE_SUFFIX.length).moduleClassName)
+ case _ => name
+ }
+
+ def unmangle(kind: NameKind): N = likeSpaced {
+ name rewrite {
+ case unmangled: SimpleTermName =>
+ kind.unmangle(unmangled)
+ case ExpandedName(prefix, last) =>
+ kind.unmangle(last) rewrite {
+ case kernel: SimpleTermName =>
+ ExpandedName(prefix, kernel)
+ }
+ }
+ }
+
+ def unmangle(kinds: List[NameKind]): N = {
+ val unmangled = (name /: kinds)(_.unmangle(_))
+ if (unmangled eq name) name else unmangled.unmangle(kinds)
+ }
+ }
implicit class TermNameDecorator(val name: TermName) extends AnyVal {
import nme._
- def setterName: TermName =
- if (name.isFieldName) name.fieldToGetter.setterName
- else name ++ SETTER_SUFFIX
+ def setterName: TermName = name.exclude(FieldName) ++ str.SETTER_SUFFIX
def getterName: TermName =
- if (name.isFieldName) fieldToGetter
- else setterToGetter
+ name.exclude(FieldName).mapLast(n =>
+ if (n.endsWith(str.SETTER_SUFFIX)) n.take(n.length - str.SETTER_SUFFIX.length).asSimpleName
+ else n)
def fieldName: TermName =
if (name.isSetterName) {
- if (name.isTraitSetterName) {
- // has form <$-separated-trait-name>$_setter_$ `name`_$eq
- val start = name.indexOfSlice(TRAIT_SETTER_SEPARATOR) + TRAIT_SETTER_SEPARATOR.length
- val end = name.indexOfSlice(SETTER_SUFFIX)
- name.slice(start, end) ++ LOCAL_SUFFIX
- } else getterName.fieldName
+ if (name.is(TraitSetterName)) {
+ val TraitSetterName(_, original) = name
+ original.fieldName
+ }
+ else getterName.fieldName
}
- else name ++ LOCAL_SUFFIX
-
- private def setterToGetter: TermName = {
- assert(name.endsWith(SETTER_SUFFIX), name + " is referenced as a setter but has wrong name format")
- name.take(name.length - SETTER_SUFFIX.length).asTermName
- }
-
- def fieldToGetter: TermName = {
- assert(name.isFieldName)
- name.take(name.length - LOCAL_SUFFIX.length).asTermName
- }
-
- /** Nominally, name$default$N, encoded for <init>
- * @param Post the parameters position.
- * @note Default getter name suffixes start at 1, so `pos` has to be adjusted by +1
- */
- def defaultGetterName(pos: Int): TermName = {
- val prefix = if (name.isConstructorName) DEFAULT_GETTER_INIT else name
- prefix ++ DEFAULT_GETTER ++ (pos + 1).toString
- }
-
- /** Nominally, name from name$default$N, CONSTRUCTOR for <init> */
- def defaultGetterToMethod: TermName = {
- val p = name.indexOfSlice(DEFAULT_GETTER)
- if (p >= 0) {
- val q = name.take(p).asTermName
- // i.e., if (q.decoded == CONSTRUCTOR.toString) CONSTRUCTOR else q
- if (q == DEFAULT_GETTER_INIT) CONSTRUCTOR else q
- } else name
- }
-
- /** If this is a default getter, its index (starting from 0), else -1 */
- def defaultGetterIndex: Int = {
- var i = name.length
- while (i > 0 && name(i - 1).isDigit) i -= 1
- if (i > 0 && i < name.length && name.take(i).endsWith(DEFAULT_GETTER))
- name.drop(i).toString.toInt - 1
- else
- -1
- }
+ else FieldName(name)
def stripScala2LocalSuffix: TermName =
- if (name.isScala2LocalSuffix) name.init.asTermName else name
-
- /** The name of an accessor for protected symbols. */
- def protectedAccessorName: TermName =
- PROTECTED_PREFIX ++ name.unexpandedName
-
- /** The name of a setter for protected symbols. Used for inherited Java fields. */
- def protectedSetterName: TermName =
- PROTECTED_SET_PREFIX ++ name.unexpandedName
-
- def moduleVarName: TermName =
- name ++ MODULE_VAR_SUFFIX
+ if (name.isScala2LocalSuffix) name.asSimpleName.dropRight(1) else name
/** The name unary_x for a prefix operator x */
def toUnaryName: TermName = name match {
@@ -441,65 +282,5 @@ object NameOps {
case raw.BANG => UNARY_!
case _ => name
}
-
- /** The name of a method which stands in for a primitive operation
- * during structural type dispatch.
- */
- def primitiveInfixMethodName: TermName = name match {
- case OR => takeOr
- case XOR => takeXor
- case AND => takeAnd
- case EQ => testEqual
- case NE => testNotEqual
- case ADD => add
- case SUB => subtract
- case MUL => multiply
- case DIV => divide
- case MOD => takeModulo
- case LSL => shiftSignedLeft
- case LSR => shiftLogicalRight
- case ASR => shiftSignedRight
- case LT => testLessThan
- case LE => testLessOrEqualThan
- case GE => testGreaterOrEqualThan
- case GT => testGreaterThan
- case ZOR => takeConditionalOr
- case ZAND => takeConditionalAnd
- case _ => NO_NAME
- }
-
- /** Postfix/prefix, really.
- */
- def primitivePostfixMethodName: TermName = name match {
- case UNARY_! => takeNot
- case UNARY_+ => positive
- case UNARY_- => negate
- case UNARY_~ => complement
- case `toByte` => toByte
- case `toShort` => toShort
- case `toChar` => toCharacter
- case `toInt` => toInteger
- case `toLong` => toLong
- case `toFloat` => toFloat
- case `toDouble` => toDouble
- case _ => NO_NAME
- }
-
- def primitiveMethodName: TermName =
- primitiveInfixMethodName match {
- case NO_NAME => primitivePostfixMethodName
- case name => name
- }
-
- def lazyLocalName = name ++ nme.LAZY_LOCAL
- def nonLazyName = {
- assert(name.isLazyLocal)
- name.dropRight(nme.LAZY_LOCAL.length)
- }
-
- def inlineAccessorName = nme.INLINE_ACCESSOR_PREFIX ++ name ++ "$"
}
-
- private final val FalseSuper = "$$super".toTermName
- private val FalseSuperLength = FalseSuper.length
}
diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala
index 11f0b55a8..a72a02844 100644
--- a/compiler/src/dotty/tools/dotc/core/Names.scala
+++ b/compiler/src/dotty/tools/dotc/core/Names.scala
@@ -10,13 +10,16 @@ import Decorators._
import Contexts.Context
import collection.IndexedSeqOptimized
import collection.generic.CanBuildFrom
-import collection.mutable.{ Builder, StringBuilder }
+import collection.mutable.{ Builder, StringBuilder, AnyRefMap }
import collection.immutable.WrappedString
import collection.generic.CanBuildFrom
-import util.DotClass
+import util.{DotClass, SimpleMap}
+import java.util.HashMap
+
//import annotation.volatile
object Names {
+ import NameKinds._
/** A common class for things that can be turned into names.
* Instances are both names and strings, the latter via a decorator.
@@ -37,20 +40,11 @@ object Names {
* 3. Names are intended to be encoded strings. @see dotc.util.NameTransformer.
* The encoding will be applied when converting a string to a name.
*/
- abstract class Name extends DotClass
- with PreName
- with collection.immutable.Seq[Char]
- with IndexedSeqOptimized[Char, Name] {
+ abstract class Name extends DotClass with PreName {
/** A type for names of the same kind as this name */
type ThisName <: Name
- /** The start index in the character array */
- val start: Int
-
- /** The length of the names */
- override val length: Int
-
/** Is this name a type name? */
def isTypeName: Boolean
@@ -69,120 +63,244 @@ object Names {
/** This name downcasted to a term name */
def asTermName: TermName
- /** Create a new name of same kind as this one, in the given
- * basis, with `len` characters taken from `cs` starting at `offset`.
- */
- def fromChars(cs: Array[Char], offset: Int, len: Int): ThisName
+ def isSimple: Boolean
+ def asSimpleName: SimpleTermName
+ def toSimpleName: SimpleTermName
+ def mangled: Name
- /** Create new name of same kind as this name and with same
- * characters as given `name`.
- */
- def fromName(name: Name): ThisName = fromChars(chrs, name.start, name.length)
+ def rewrite(f: PartialFunction[Name, Name]): ThisName
+ def collect[T](f: PartialFunction[Name, T]): Option[T]
+ def mapLast(f: SimpleTermName => SimpleTermName): ThisName
+ def mapParts(f: SimpleTermName => SimpleTermName): ThisName
- /** Create new name of same kind as this name with characters from
- * the given string
+ /** A name in the same (term or type) namespace as this name and
+ * with same characters as given `name`.
*/
- def fromString(str: String): ThisName = {
- val cs = str.toCharArray
- fromChars(cs, 0, cs.length)
- }
+ def likeSpaced(name: Name): ThisName
- override def toString =
- if (length == 0) "" else new String(chrs, start, length)
+ def derived(info: NameInfo): ThisName
+ def derived(kind: ClassifiedNameKind): ThisName = derived(kind.info)
+ def exclude(kind: NameKind): ThisName
+ def is(kind: NameKind): Boolean
+ def debugString: String
def toText(printer: Printer): Text = printer.toText(this)
- /** Write to UTF8 representation of this name to given character array.
- * Start copying to index `to`. Return index of next free byte in array.
- * Array must have enough remaining space for all bytes
- * (i.e. maximally 3*length bytes).
- */
- final def copyUTF8(bs: Array[Byte], offset: Int): Int = {
- val bytes = Codec.toUTF8(chrs, start, length)
- scala.compat.Platform.arraycopy(bytes, 0, bs, offset, bytes.length)
- offset + bytes.length
- }
-
/** Replace \$op_name's by corresponding operator symbols. */
- def decode: Name =
- if (contains('$')) fromString(NameTransformer.decode(toString))
- else this
+ def decode: Name
/** Replace operator symbols by corresponding \$op_name's. */
- def encode: Name =
- if (dontEncode(toTermName)) this else NameTransformer.encode(this)
+ def encode: Name
+
+ def firstPart: SimpleTermName
+ def lastPart: SimpleTermName
/** A more efficient version of concatenation */
def ++ (other: Name): ThisName = ++ (other.toString)
+ def ++ (other: String): ThisName = mapLast(n => termName(n.toString + other))
+ def replace(from: Char, to: Char): ThisName = mapParts(_.replace(from, to))
+
+ def isEmpty: Boolean
+
+ def startsWith(str: String): Boolean = firstPart.startsWith(str)
+ def endsWith(str: String): Boolean = lastPart.endsWith(str)
+
+ override def hashCode = System.identityHashCode(this)
+ override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
+ }
- def ++ (other: String): ThisName = {
- val s = toString + other
- fromChars(s.toCharArray, 0, s.length)
+ abstract class TermName extends Name {
+ type ThisName = TermName
+ def isTypeName = false
+ def isTermName = true
+ def toTermName = this
+ def asTypeName = throw new ClassCastException(this + " is not a type name")
+ def asTermName = this
+
+ @sharable // because it is only modified in the synchronized block of toTypeName.
+ @volatile private[this] var _typeName: TypeName = null
+
+ def toTypeName: TypeName = {
+ if (_typeName == null)
+ synchronized {
+ if (_typeName == null)
+ _typeName = new TypeName(this)
+ }
+ _typeName
}
- def replace(from: Char, to: Char): ThisName = {
- val cs = new Array[Char](length)
- Array.copy(chrs, start, cs, 0, length)
- for (i <- 0 until length) {
- if (cs(i) == from) cs(i) = to
+ def likeSpaced(name: Name): TermName = name.toTermName
+
+ def info: NameInfo = SimpleTermNameKind.info
+ def underlying: TermName = unsupported("underlying")
+
+ @sharable // because of synchronized block in `and`
+ private var derivedNames: AnyRef /* SimpleMap | j.u.HashMap */ =
+ SimpleMap.Empty[NameInfo]
+
+ private def getDerived(info: NameInfo): DerivedTermName /* | Null */= derivedNames match {
+ case derivedNames: SimpleMap[NameInfo, DerivedTermName] @unchecked =>
+ derivedNames(info)
+ case derivedNames: HashMap[NameInfo, DerivedTermName] @unchecked =>
+ derivedNames.get(info)
+ }
+
+ private def putDerived(info: NameInfo, name: DerivedTermName): name.type = {
+ derivedNames match {
+ case derivedNames: SimpleMap[NameInfo, DerivedTermName] @unchecked =>
+ if (derivedNames.size < 4)
+ this.derivedNames = derivedNames.updated(info, name)
+ else {
+ val newMap = new HashMap[NameInfo, DerivedTermName]
+ derivedNames.foreachBinding(newMap.put(_, _))
+ newMap.put(info, name)
+ this.derivedNames = newMap
+ }
+ case derivedNames: HashMap[NameInfo, DerivedTermName] @unchecked =>
+ derivedNames.put(info, name)
+ }
+ name
+ }
+
+ private def add(info: NameInfo): TermName = synchronized {
+ getDerived(info) match {
+ case null => putDerived(info, new DerivedTermName(this, info))
+ case derivedName => derivedName
+ }
+ }
+
+ private def rewrap(underlying: TermName) =
+ if (underlying eq this.underlying) this else underlying.add(info)
+
+ /** Return derived name with given `info` and the current
+ * name as underlying name.
+ */
+ def derived(info: NameInfo): TermName = {
+ val thisKind = this.info.kind
+ val thatKind = info.kind
+ if (thisKind.tag < thatKind.tag || thatKind.definesNewName) add(info)
+ else if (thisKind.tag > thatKind.tag) rewrap(underlying.derived(info))
+ else {
+ assert(info == this.info)
+ this
}
- fromChars(cs, 0, length)
}
+ def exclude(kind: NameKind): TermName = {
+ val thisKind = this.info.kind
+ if (thisKind.tag < kind.tag || thisKind.definesNewName) this
+ else if (thisKind.tag > kind.tag) rewrap(underlying.exclude(kind))
+ else underlying
+ }
+
+ def is(kind: NameKind): Boolean = {
+ val thisKind = this.info.kind
+ thisKind == kind ||
+ !thisKind.definesNewName && thisKind.tag > kind.tag && underlying.is(kind)
+ }
+ }
+
+ class SimpleTermName(val start: Int, val length: Int, @sharable private[Names] var next: SimpleTermName) extends TermName {
+ // `next` is @sharable because it is only modified in the synchronized block of termName.
+
+ def apply(n: Int) = chrs(start + n)
+
+ def exists(p: Char => Boolean): Boolean = {
+ var i = 0
+ while (i < length && !p(chrs(start + i))) i += 1
+ i < length
+ }
+
+ def forall(p: Char => Boolean) = !exists(!p(_))
+
def contains(ch: Char): Boolean = {
var i = 0
while (i < length && chrs(start + i) != ch) i += 1
i < length
}
- def firstChar = chrs(start)
+ def isEmpty = length == 0
+
+ override def startsWith(str: String): Boolean = {
+ var i = 0
+ while (i < str.length && i < length && apply(i) == str(i)) i += 1
+ i == str.length
+ }
+
+ override def endsWith(str: String): Boolean = {
+ var i = 1
+ while (i <= str.length && i <= length && apply(length - i) == str(str.length - i)) i += 1
+ i > str.length
+ }
- // ----- Collections integration -------------------------------------
+ def lastIndexOf(ch: Char, start: Int = length - 1): Int = {
+ var i = start
+ while (i >= 0 && apply(i) != ch) i -= 1
+ i
+ }
- override protected[this] def thisCollection: WrappedString = new WrappedString(repr.toString)
- override protected[this] def toCollection(repr: Name): WrappedString = new WrappedString(repr.toString)
+ def lastIndexOfSlice(str: String): Int = toString.lastIndexOfSlice(str)
- override protected[this] def newBuilder: Builder[Char, Name] = unsupported("newBuilder")
+ override def replace(from: Char, to: Char): SimpleTermName = {
+ val cs = new Array[Char](length)
+ Array.copy(chrs, start, cs, 0, length)
+ for (i <- 0 until length) {
+ if (cs(i) == from) cs(i) = to
+ }
+ termName(cs, 0, length)
+ }
- override def apply(index: Int): Char = chrs(start + index)
+ def slice(from: Int, until: Int): SimpleTermName = {
+ assert(0 <= from && from <= until && until <= length)
+ termName(chrs, start + from, until - from)
+ }
- override def slice(from: Int, until: Int): ThisName =
- fromChars(chrs, start + from, until - from)
+ def drop(n: Int) = slice(n, length)
+ def take(n: Int) = slice(0, n)
+ def dropRight(n: Int) = slice(0, length - n)
+ def takeRight(n: Int) = slice(length - n, length)
- override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
+ def head = apply(0)
+ def last = apply(length - 1)
- override def seq = toCollection(this)
- }
+ def isSimple = true
+ def asSimpleName = this
+ def toSimpleName = this
+ def mangled = this
- class TermName(val start: Int, val length: Int, @sharable private[Names] var next: TermName) extends Name {
- // `next` is @sharable because it is only modified in the synchronized block of termName.
- type ThisName = TermName
- def isTypeName = false
- def isTermName = true
+ def rewrite(f: PartialFunction[Name, Name]): ThisName =
+ if (f.isDefinedAt(this)) likeSpaced(f(this)) else this
+ def collect[T](f: PartialFunction[Name, T]): Option[T] = f.lift(this)
+ def mapLast(f: SimpleTermName => SimpleTermName) = f(this)
+ def mapParts(f: SimpleTermName => SimpleTermName) = f(this)
- @sharable // because it is only modified in the synchronized block of toTypeName.
- @volatile private[this] var _typeName: TypeName = null
+ def encode: SimpleTermName =
+ if (dontEncode(toTermName)) this else NameTransformer.encode(this)
- def toTypeName: TypeName = {
- if (_typeName == null)
- synchronized {
- if (_typeName == null)
- _typeName = new TypeName(start, length, this)
- }
- _typeName
- }
- def toTermName = this
- def asTypeName = throw new ClassCastException(this + " is not a type name")
- def asTermName = this
+ /** Replace \$op_name's by corresponding operator symbols. */
+ def decode: SimpleTermName =
+ if (contains('$')) termName(NameTransformer.decode(toString)) else this
+
+ def firstPart = this
+ def lastPart = this
override def hashCode: Int = start
- override protected[this] def newBuilder: Builder[Char, Name] = termNameBuilder
+ override def toString =
+ if (length == 0) "" else new String(chrs, start, length)
- def fromChars(cs: Array[Char], offset: Int, len: Int): TermName = termName(cs, offset, len)
+ def debugString: String = toString
}
- class TypeName(val start: Int, val length: Int, val toTermName: TermName) extends Name {
+ class TypeName(val toTermName: TermName) extends Name {
+
+ def isEmpty = toTermName.isEmpty
+
+ def encode = toTermName.encode.toTypeName
+ def decode = toTermName.decode.toTypeName
+ def firstPart = toTermName.firstPart
+ def lastPart = toTermName.lastPart
+
type ThisName = TypeName
def isTypeName = true
def isTermName = false
@@ -190,12 +308,77 @@ object Names {
def asTypeName = this
def asTermName = throw new ClassCastException(this + " is not a term name")
- override def hashCode: Int = -start
+ def isSimple = toTermName.isSimple
+ def asSimpleName = toTermName.asSimpleName
+ def toSimpleName = toTermName.toSimpleName
+ def mangled = toTermName.toSimpleName.toTypeName
- override protected[this] def newBuilder: Builder[Char, Name] =
- termNameBuilder.mapResult(_.toTypeName)
+ def rewrite(f: PartialFunction[Name, Name]): ThisName = toTermName.rewrite(f).toTypeName
+ def collect[T](f: PartialFunction[Name, T]): Option[T] = toTermName.collect(f)
+ def mapLast(f: SimpleTermName => SimpleTermName) = toTermName.mapLast(f).toTypeName
+ def mapParts(f: SimpleTermName => SimpleTermName) = toTermName.mapParts(f).toTypeName
- def fromChars(cs: Array[Char], offset: Int, len: Int): TypeName = typeName(cs, offset, len)
+ def likeSpaced(name: Name): TypeName = name.toTypeName
+
+ def derived(info: NameInfo): TypeName = toTermName.derived(info).toTypeName
+ def exclude(kind: NameKind): TypeName = toTermName.exclude(kind).toTypeName
+ def is(kind: NameKind) = toTermName.is(kind)
+
+ override def toString = toTermName.toString
+ override def debugString = toTermName.debugString + "/T"
+ }
+
+ /** A term name that's derived from an `underlying` name and that
+ * adds `info` to it.
+ */
+ case class DerivedTermName(override val underlying: TermName, override val info: NameInfo)
+ extends TermName {
+ def isEmpty = false
+ def encode: Name = underlying.encode.derived(info.map(_.encode))
+ def decode: Name = underlying.decode.derived(info.map(_.decode))
+ def firstPart = underlying.firstPart
+ def lastPart = info match {
+ case qual: QualifiedInfo => qual.name
+ case _ => underlying.lastPart
+ }
+ override def toString = info.mkString(underlying)
+ override def debugString = s"${underlying.debugString}[$info]"
+
+ def isSimple = false
+ def asSimpleName = throw new UnsupportedOperationException(s"$debugString is not a simple name")
+
+ private[this] var simpleName: SimpleTermName = null
+ def toSimpleName = {
+ if (simpleName == null) simpleName = termName(toString)
+ simpleName
+ }
+ def mangled = toSimpleName
+
+ def rewrite(f: PartialFunction[Name, Name]): ThisName =
+ if (f.isDefinedAt(this)) likeSpaced(f(this))
+ else info match {
+ case qual: QualifiedInfo => this
+ case _ => underlying.rewrite(f).derived(info)
+ }
+
+ def collect[T](f: PartialFunction[Name, T]): Option[T] =
+ if (f.isDefinedAt(this)) Some(f(this))
+ else info match {
+ case qual: QualifiedInfo => None
+ case _ => underlying.collect(f)
+ }
+
+ def mapLast(f: SimpleTermName => SimpleTermName): ThisName =
+ info match {
+ case qual: QualifiedInfo => underlying.derived(qual.map(f))
+ case _ => underlying.mapLast(f).derived(info)
+ }
+
+ def mapParts(f: SimpleTermName => SimpleTermName): ThisName =
+ info match {
+ case qual: QualifiedInfo => underlying.mapParts(f).derived(qual.map(f))
+ case _ => underlying.mapParts(f).derived(info)
+ }
}
// Nametable
@@ -214,7 +397,7 @@ object Names {
/** Hashtable for finding term names quickly. */
@sharable // because it's only mutated in synchronized block of termName
- private var table = new Array[TermName](InitialHashSize)
+ private var table = new Array[SimpleTermName](InitialHashSize)
/** The number of defined names. */
@sharable // because it's only mutated in synchronized block of termName
@@ -242,7 +425,7 @@ object Names {
/** Create a term name from the characters in cs[offset..offset+len-1].
* Assume they are already encoded.
*/
- def termName(cs: Array[Char], offset: Int, len: Int): TermName = synchronized {
+ def termName(cs: Array[Char], offset: Int, len: Int): SimpleTermName = synchronized {
util.Stats.record("termName")
val h = hashValue(cs, offset, len) & (table.size - 1)
@@ -266,7 +449,7 @@ object Names {
}
/** Rehash chain of names */
- def rehash(name: TermName): Unit =
+ def rehash(name: SimpleTermName): Unit =
if (name != null) {
val oldNext = name.next
val h = hashValue(chrs, name.start, name.length) & (table.size - 1)
@@ -280,7 +463,7 @@ object Names {
size += 1
if (size.toDouble / table.size > fillFactor) {
val oldTable = table
- table = new Array[TermName](table.size * 2)
+ table = new Array[SimpleTermName](table.size * 2)
for (i <- 0 until oldTable.size) rehash(oldTable(i))
}
}
@@ -292,7 +475,7 @@ object Names {
return name
name = name.next
}
- name = new TermName(nc, len, next)
+ name = new SimpleTermName(nc, len, next)
enterChars()
table(h) = name
incTableSize()
@@ -308,7 +491,7 @@ object Names {
/** Create a term name from the UTF8 encoded bytes in bs[offset..offset+len-1].
* Assume they are already encoded.
*/
- def termName(bs: Array[Byte], offset: Int, len: Int): TermName = {
+ def termName(bs: Array[Byte], offset: Int, len: Int): SimpleTermName = {
val chars = Codec.fromUTF8(bs, offset, len)
termName(chars, 0, chars.length)
}
@@ -320,53 +503,75 @@ object Names {
termName(bs, offset, len).toTypeName
/** Create a term name from a string, without encoding operators */
- def termName(s: String): TermName = termName(s.toCharArray, 0, s.length)
+ def termName(s: String): SimpleTermName = termName(s.toCharArray, 0, s.length)
/** Create a type name from a string, without encoding operators */
def typeName(s: String): TypeName = typeName(s.toCharArray, 0, s.length)
- /** The term name represented by the empty string */
- val EmptyTermName = new TermName(-1, 0, null)
+ table(0) = new SimpleTermName(-1, 0, null)
- table(0) = EmptyTermName
+ /** The term name represented by the empty string */
+ val EmptyTermName: TermName = table(0)
/** The type name represented by the empty string */
val EmptyTypeName = EmptyTermName.toTypeName
// can't move CONSTRUCTOR/EMPTY_PACKAGE to `nme` because of bootstrap failures in `encode`.
- val CONSTRUCTOR = termName("<init>")
- val STATIC_CONSTRUCTOR = termName("<clinit>")
- val EMPTY_PACKAGE = termName("<empty>")
-
- val dontEncode = Set(CONSTRUCTOR, EMPTY_PACKAGE)
+ val CONSTRUCTOR: TermName = termName("<init>")
+ val STATIC_CONSTRUCTOR: TermName = termName("<clinit>")
+ val EMPTY_PACKAGE: TermName = termName("<empty>")
+ val REFINEMENT: TermName = termName("<refinement>")
- def termNameBuilder: Builder[Char, TermName] =
- StringBuilder.newBuilder.mapResult(termName)
-
- implicit val nameCanBuildFrom: CanBuildFrom[Name, Char, Name] = new CanBuildFrom[Name, Char, Name] {
- def apply(from: Name): Builder[Char, Name] =
- StringBuilder.newBuilder.mapResult(s => from.fromChars(s.toCharArray, 0, s.length))
- def apply(): Builder[Char, Name] = termNameBuilder
- }
+ val dontEncode = Set(CONSTRUCTOR, EMPTY_PACKAGE, REFINEMENT)
implicit val NameOrdering: Ordering[Name] = new Ordering[Name] {
+ private def compareInfos(x: NameInfo, y: NameInfo): Int =
+ if (x.kind.tag != y.kind.tag) x.kind.tag - y.kind.tag
+ else x match {
+ case x: QualifiedInfo =>
+ y match {
+ case y: QualifiedInfo =>
+ compareSimpleNames(x.name, y.name)
+ }
+ case x: NumberedInfo =>
+ y match {
+ case y: NumberedInfo =>
+ x.num - y.num
+ }
+ case _ =>
+ assert(x == y)
+ 0
+ }
+ private def compareSimpleNames(x: SimpleTermName, y: SimpleTermName): Int = {
+ val until = x.length min y.length
+ var i = 0
+ while (i < until && x(i) == y(i)) i = i + 1
+ if (i < until) {
+ if (x(i) < y(i)) -1
+ else /*(x(i) > y(i))*/ 1
+ } else {
+ x.length - y.length
+ }
+ }
+ private def compareTermNames(x: TermName, y: TermName): Int = x match {
+ case x: SimpleTermName =>
+ y match {
+ case y: SimpleTermName => compareSimpleNames(x, y)
+ case _ => -1
+ }
+ case DerivedTermName(xPre, xInfo) =>
+ y match {
+ case DerivedTermName(yPre, yInfo) =>
+ val s = compareInfos(xInfo, yInfo)
+ if (s == 0) compareTermNames(xPre, yPre) else s
+ case _ => 1
+ }
+ }
def compare(x: Name, y: Name): Int = {
if (x.isTermName && y.isTypeName) 1
else if (x.isTypeName && y.isTermName) -1
else if (x eq y) 0
- else {
- val until = x.length min y.length
- var i = 0
-
- while (i < until && x(i) == y(i)) i = i + 1
-
- if (i < until) {
- if (x(i) < y(i)) -1
- else /*(x(i) > y(i))*/ 1
- } else {
- x.length - y.length
- }
- }
+ else compareTermNames(x.toTermName, y.toTermName)
}
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala
index 6090079e5..205798474 100644
--- a/compiler/src/dotty/tools/dotc/core/Scopes.scala
+++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala
@@ -32,7 +32,7 @@ object Scopes {
* This value must be a power of two, so that the index of an element can
* be computed as element.hashCode & (hashTable.length - 1)
*/
- private final val MinHash = 8
+ final val MinHashedScopeSize = 8
/** The maximal permissible number of recursions when creating
* a hashtable
@@ -60,7 +60,7 @@ object Scopes {
* or to delete them. These methods are provided by subclass
* MutableScope.
*/
- abstract class Scope extends DotClass with printing.Showable with Iterable[Symbol] {
+ abstract class Scope extends DotClass with printing.Showable {
/** The last scope-entry from which all others are reachable via `prev` */
private[dotc] def lastEntry: ScopeEntry
@@ -76,18 +76,37 @@ object Scopes {
/** The symbols in this scope in the order they were entered;
* inherited from outer ones first.
*/
- def toList: List[Symbol]
+ def toList(implicit ctx: Context): List[Symbol]
/** Return all symbols as an iterator in the order they were entered in this scope.
*/
- def iterator: Iterator[Symbol] = toList.iterator
+ def iterator(implicit ctx: Context): Iterator[Symbol] = toList.iterator
+
+ /** Is the scope empty? */
+ def isEmpty: Boolean = lastEntry eq null
+
+ def foreach[U](p: Symbol => U)(implicit ctx: Context): Unit = toList foreach p
+
+ def filter(p: Symbol => Boolean)(implicit ctx: Context): List[Symbol] = {
+ ensureComplete()
+ var syms: List[Symbol] = Nil
+ var e = lastEntry
+ while ((e ne null) && e.owner == this) {
+ val sym = e.sym
+ if (p(sym)) syms = sym :: syms
+ e = e.prev
+ }
+ syms
+ }
+
+ def find(p: Symbol => Boolean)(implicit ctx: Context): Symbol = filter(p) match {
+ case sym :: _ => sym
+ case _ => NoSymbol
+ }
/** Returns a new mutable scope with the same content as this one. */
def cloneScope(implicit ctx: Context): MutableScope
- /** Is the scope empty? */
- override def isEmpty: Boolean = lastEntry eq null
-
/** Lookup a symbol entry matching given name. */
def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry
@@ -144,6 +163,12 @@ object Scopes {
final def toText(printer: Printer): Text = printer.toText(this)
def checkConsistent()(implicit ctx: Context) = ()
+
+ /** Ensure that all elements of this scope have been entered.
+ * Overridden by SymbolLoaders.PackageLoader#PackageScope, where it
+ * makes sure that all names with `$`'s have been added.
+ */
+ protected def ensureComplete()(implicit ctx: Context): Unit = ()
}
/** A subclass of Scope that defines methods for entering and
@@ -155,9 +180,10 @@ object Scopes {
class MutableScope protected[Scopes](initElems: ScopeEntry, initSize: Int, val nestingLevel: Int = 0)
extends Scope {
+ /** Scope shares elements with `base` */
protected[Scopes] def this(base: Scope)(implicit ctx: Context) = {
this(base.lastEntry, base.size, base.nestingLevel + 1)
- ensureCapacity(MinHash)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call.
+ ensureCapacity(MinHashedScopeSize)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call.
}
def this() = this(null, 0, 0)
@@ -178,6 +204,8 @@ object Scopes {
*/
private var elemsCache: List[Symbol] = null
+ protected def newScopeLikeThis() = new MutableScope()
+
/** Clone scope, taking care not to force the denotations of any symbols in the scope.
*/
def cloneScope(implicit ctx: Context): MutableScope = {
@@ -187,7 +215,7 @@ object Scopes {
entries += e
e = e.prev
}
- val scope = newScope
+ val scope = newScopeLikeThis()
for (i <- entries.length - 1 to 0 by -1) {
val e = entries(i)
scope.newScopeEntry(e.name, e.sym)
@@ -197,7 +225,7 @@ object Scopes {
/** create and enter a scope entry with given name and symbol */
protected def newScopeEntry(name: Name, sym: Symbol)(implicit ctx: Context): ScopeEntry = {
- ensureCapacity(if (hashTable ne null) hashTable.length else MinHash)
+ ensureCapacity(if (hashTable ne null) hashTable.length else MinHashedScopeSize)
val e = new ScopeEntry(name, sym, this)
e.prev = lastEntry
lastEntry = e
@@ -338,8 +366,9 @@ object Scopes {
/** Returns all symbols as a list in the order they were entered in this scope.
* Does _not_ include the elements of inherited scopes.
*/
- override final def toList: List[Symbol] = {
+ override final def toList(implicit ctx: Context): List[Symbol] = {
if (elemsCache eq null) {
+ ensureComplete()
elemsCache = Nil
var e = lastEntry
while ((e ne null) && e.owner == this) {
@@ -351,6 +380,7 @@ object Scopes {
}
override def implicitDecls(implicit ctx: Context): List[TermRef] = {
+ ensureComplete()
var irefs = new mutable.ListBuffer[TermRef]
var e = lastEntry
while (e ne null) {
@@ -365,25 +395,13 @@ object Scopes {
/** Vanilla scope - symbols are stored in declaration order.
*/
- final def sorted: List[Symbol] = toList
-
- override def foreach[U](p: Symbol => U): Unit = toList foreach p
-
- override def filter(p: Symbol => Boolean): List[Symbol] = {
- var syms: List[Symbol] = Nil
- var e = lastEntry
- while ((e ne null) && e.owner == this) {
- val sym = e.sym
- if (p(sym)) syms = sym :: syms
- e = e.prev
- }
- syms
- }
+ final def sorted(implicit ctx: Context): List[Symbol] = toList
override def openForMutations: MutableScope = this
/** Check that all symbols in this scope are in their correct hashtable buckets. */
override def checkConsistent()(implicit ctx: Context) = {
+ ensureComplete()
var e = lastEntry
while (e != null) {
var e1 = lookupEntry(e.name)
@@ -407,9 +425,6 @@ object Scopes {
scope
}
- /** Create new scope for the members of package `pkg` */
- def newPackageScope(pkgClass: Symbol): MutableScope = newScope
-
/** Transform scope of members of `owner` using operation `op`
* This is overridden by the reflective compiler to avoid creating new scopes for packages
*/
@@ -425,7 +440,7 @@ object Scopes {
override private[dotc] def lastEntry = null
override def size = 0
override def nestingLevel = 0
- override def toList = Nil
+ override def toList(implicit ctx: Context) = Nil
override def cloneScope(implicit ctx: Context): MutableScope = unsupported("cloneScope")
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = null
override def lookupNextEntry(entry: ScopeEntry)(implicit ctx: Context): ScopeEntry = null
diff --git a/compiler/src/dotty/tools/dotc/core/Signature.scala b/compiler/src/dotty/tools/dotc/core/Signature.scala
index fcd1e2376..4699cecf2 100644
--- a/compiler/src/dotty/tools/dotc/core/Signature.scala
+++ b/compiler/src/dotty/tools/dotc/core/Signature.scala
@@ -34,6 +34,14 @@ import scala.annotation.tailrec
case class Signature(paramsSig: List[TypeName], resSig: TypeName) {
import Signature._
+/* FIXME does not compile under dotty, we get a missing param error
+ def checkUnqual(name: TypeName) = name mapParts { part =>
+ assert(!part.contains('.'), name)
+ part
+ }
+ paramsSig.foreach(checkUnqual)
+ checkUnqual(resSig)
+*/
/** Two names are consistent if they are the same or one of them is tpnme.Uninstantiated */
private def consistent(name1: TypeName, name2: TypeName) =
name1 == name2 || name1 == tpnme.Uninstantiated || name2 == tpnme.Uninstantiated
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index e7928fd09..92befdacb 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -15,6 +15,34 @@ object StdNames {
/** Base strings from which synthetic names are derived. */
+ object str {
+ final val SETTER_SUFFIX = "_$eq"
+ final val EXPAND_SEPARATOR = "$$"
+ final val TRAIT_SETTER_SEPARATOR = "$_setter_$"
+ final val SUPER_PREFIX = "super$"
+ final val INITIALIZER_PREFIX = "initial$"
+ final val SHADOWED_PREFIX = "(shadowed)"
+ final val AVOID_CLASH_SUFFIX = "$_avoid_name_clash_$"
+ final val MODULE_SUFFIX = NameTransformer.MODULE_SUFFIX_STRING
+ final val DEFAULT_GETTER = "$default$"
+ final val LOCALDUMMY_PREFIX = "<local " // owner of local blocks
+ final val ANON_CLASS = "$anon"
+ final val ANON_FUN = "$anonfun"
+
+ final val INTERPRETER_IMPORT_WRAPPER = "$iw"
+ final val INTERPRETER_LINE_PREFIX = "line"
+ final val INTERPRETER_VAR_PREFIX = "res"
+ final val INTERPRETER_WRAPPER_SUFFIX = "$object"
+
+ final val Function = "Function"
+ final val ImplicitFunction = "ImplicitFunction"
+ final val AbstractFunction = "AbstractFunction"
+ final val Tuple = "Tuple"
+ final val Product = "Product"
+
+ def sanitize(str: String) = str.replaceAll("""[<>]""", """\$""")
+ }
+
abstract class DefinedNames[N <: Name] {
protected implicit def fromString(s: String): N
protected def fromName(name: Name): N = fromString(name.toString)
@@ -84,44 +112,30 @@ object StdNames {
final val HASHkw: N = kw("#")
final val ATkw: N = kw("@")
- val ANON_CLASS: N = "$anon"
- val ANON_FUN: N = "$anonfun"
- val BITMAP_PREFIX: N = "bitmap$"
+ val ANON_CLASS: N = str.ANON_CLASS
+ val ANON_FUN: N = str.ANON_FUN
+ val BITMAP_PREFIX: N = "bitmap$" // @darkdimius: $bitmap? Also, the next 4 names are unused.
val BITMAP_NORMAL: N = BITMAP_PREFIX // initialization bitmap for public/protected lazy vals
val BITMAP_TRANSIENT: N = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals
val BITMAP_CHECKINIT: N = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values
val BITMAP_CHECKINIT_TRANSIENT: N = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values
- val DEFAULT_GETTER: N = "$default$"
- val DEFAULT_GETTER_INIT: N = NameTransformer.encode("<init>")
+ val DEFAULT_GETTER: N = str.DEFAULT_GETTER
+ val DEFAULT_GETTER_INIT: N = "$lessinit$greater"
val DO_WHILE_PREFIX: N = "doWhile$"
+ val DOLLAR_VALUES: N = "$values"
+ val DOLLAR_NEW: N = "$new"
val EMPTY: N = ""
val EMPTY_PACKAGE: N = Names.EMPTY_PACKAGE.toString
- val EVIDENCE_PARAM_PREFIX: N = "evidence$"
- val DEP_PARAM_PREFIX = "<param>"
val EXCEPTION_RESULT_PREFIX: N = "exceptionResult"
- val EXPAND_SEPARATOR: N = "$$"
+ val EXPAND_SEPARATOR: N = str.EXPAND_SEPARATOR
val IMPL_CLASS_SUFFIX: N = "$class"
val IMPORT: N = "<import>"
- val INLINE_ACCESSOR_PREFIX = "$inlineAccessor$"
- val INTERPRETER_IMPORT_WRAPPER: N = "$iw"
- val INTERPRETER_LINE_PREFIX: N = "line"
- val INTERPRETER_VAR_PREFIX: N = "res"
- val INTERPRETER_WRAPPER_SUFFIX: N = "$object"
- val LOCALDUMMY_PREFIX: N = "<local " // owner of local blocks
val MODULE_SUFFIX: N = NameTransformer.MODULE_SUFFIX_STRING
- val AVOID_CLASH_SUFFIX: N = "$_avoid_name_clash_$"
- val MODULE_VAR_SUFFIX: N = "$module"
val NAME_JOIN: N = NameTransformer.NAME_JOIN_STRING
- val USCORE_PARAM_PREFIX: N = "_$"
val OPS_PACKAGE: N = "<special-ops>"
val OVERLOADED: N = "<overloaded>"
val PACKAGE: N = "package"
- val PACKAGE_CLS: N = "package$"
- val PROTECTED_PREFIX: N = "protected$"
- val PROTECTED_SET_PREFIX: N = PROTECTED_PREFIX + "set"
val ROOT: N = "<root>"
- val SHADOWED: N = "(shadowed)" // tag to be used until we have proper name kinds
- val SINGLETON_SUFFIX: N = ".type"
val SPECIALIZED_SUFFIX: N = "$sp"
val SUPER_PREFIX: N = "super$"
val WHILE_PREFIX: N = "while$"
@@ -129,11 +143,7 @@ object StdNames {
val INITIALIZER_PREFIX: N = "initial$"
val COMPANION_MODULE_METHOD: N = "companion$module"
val COMPANION_CLASS_METHOD: N = "companion$class"
- val TRAIT_SETTER_SEPARATOR: N = "$_setter_$"
- val DIRECT_SUFFIX: N = "$direct"
- val LAZY_IMPLICIT_PREFIX: N = "$lazy_implicit$"
- val DOLLAR_VALUES: N = "$values"
- val DOLLAR_NEW: N = "$new"
+ val TRAIT_SETTER_SEPARATOR: N = str.TRAIT_SETTER_SEPARATOR
// value types (and AnyRef) are all used as terms as well
// as (at least) arguments to the @specialize annotation.
@@ -167,7 +177,6 @@ object StdNames {
// fictions we use as both types and terms
final val ERROR: N = "<error>"
- final val ERRORenc: N = encode("<error>")
final val NO_NAME: N = "<none>" // formerly NOSYMBOL
final val WILDCARD: N = "_"
@@ -181,23 +190,18 @@ object StdNames {
final val REIFY_TREECREATOR_PREFIX: N = "$treecreator"
final val REIFY_TYPECREATOR_PREFIX: N = "$typecreator"
- final val AbstractFunction: N = "AbstractFunction"
final val Any: N = "Any"
final val AnyVal: N = "AnyVal"
final val ExprApi: N = "ExprApi"
- final val Function: N = "Function"
- final val ImplicitFunction: N = "ImplicitFunction"
final val Mirror: N = "Mirror"
final val Nothing: N = "Nothing"
final val Null: N = "Null"
final val Object: N = "Object"
final val PartialFunction: N = "PartialFunction"
final val PrefixType: N = "PrefixType"
- final val Product: N = "Product"
final val Serializable: N = "Serializable"
final val Singleton: N = "Singleton"
final val Throwable: N = "Throwable"
- final val Tuple: N = "Tuple"
final val ClassfileAnnotation: N = "ClassfileAnnotation"
final val ClassManifest: N = "ClassManifest"
@@ -241,11 +245,8 @@ object StdNames {
val EVT2U: N = "evt2u$"
val EQEQ_LOCAL_VAR: N = "eqEqTemp$"
val FAKE_LOCAL_THIS: N = "this$"
- val LAZY_LOCAL: N = "$lzy"
- val LAZY_LOCAL_INIT: N = "$lzyINIT"
val LAZY_FIELD_OFFSET: N = "OFFSET$"
val LAZY_SLOW_SUFFIX: N = "$lzycompute"
- val LOCAL_SUFFIX: N = "$$local"
val UNIVERSE_BUILD_PREFIX: N = "$u.build."
val UNIVERSE_BUILD: N = "$u.build"
val UNIVERSE_PREFIX: N = "$u."
@@ -259,13 +260,10 @@ object StdNames {
val REIFY_SYMDEF_PREFIX: N = "symdef$"
val MODULE_INSTANCE_FIELD: N = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
val OUTER: N = "$outer"
- val OUTER_LOCAL: N = "$outer "
- val OUTER_SELECT: N = "_<outer>" // emitted by inliner, replaced by outer path in explicitouter
val REFINE_CLASS: N = "<refinement>"
val ROOTPKG: N = "_root_"
val SELECTOR_DUMMY: N = "<unapply-selector>"
val SELF: N = "$this"
- val SETTER_SUFFIX: N = encode("_=")
val SKOLEM: N = "<skolem>"
val SPECIALIZED_INSTANCE: N = "specInstance$"
val THIS: N = "_$this"
@@ -440,7 +438,6 @@ object StdNames {
val lang: N = "lang"
val length: N = "length"
val lengthCompare: N = "lengthCompare"
- val liftedTree: N = "liftedTree"
val `macro` : N = "macro"
val macroThis : N = "_this"
val macroContext : N = "c"
@@ -458,7 +455,6 @@ object StdNames {
val ne: N = "ne"
val newFreeTerm: N = "newFreeTerm"
val newFreeType: N = "newFreeType"
- val newNestedSymbol: N = "newNestedSymbol"
val newScopeWith: N = "newScopeWith"
val next: N = "next"
val nmeNewTermName: N = "newTermName"
@@ -541,6 +537,11 @@ object StdNames {
val synthSwitch: N = "$synthSwitch"
val _scope: N = "$scope"
+ val nothingClass: N = "Nothing$"
+ val nullClass: N = "Null$"
+
+ val falseModuleClassNames = Set(nothingClass, nullClass, nothingRuntimeClass, nullRuntimeClass)
+
// unencoded operators
object raw {
final val AMP : N = "&"
@@ -661,22 +662,6 @@ object StdNames {
val isBoxedNumberOrBoolean: N = "isBoxedNumberOrBoolean"
val isBoxedNumber: N = "isBoxedNumber"
-
- val reflPolyCacheName: N = "reflPoly$Cache"
- val reflClassCacheName: N = "reflClass$Cache"
- val reflParamsCacheName: N = "reflParams$Cache"
- val reflMethodCacheName: N = "reflMethod$Cache"
- val reflMethodName: N = "reflMethod$Method"
-
- private val reflectionCacheNames = Set[N](
- reflPolyCacheName,
- reflClassCacheName,
- reflParamsCacheName,
- reflMethodCacheName,
- reflMethodName
- )
-
- def isReflectionCacheName(name: Name) = reflectionCacheNames exists (name startsWith _)
}
class ScalaTermNames extends ScalaNames[TermName] {
@@ -723,7 +708,7 @@ object StdNames {
}
def localDummyName(clazz: Symbol)(implicit ctx: Context): TermName =
- LOCALDUMMY_PREFIX ++ clazz.name ++ ">"
+ termName(str.LOCALDUMMY_PREFIX + clazz.name + ">")
def newBitmapName(bitmapPrefix: TermName, n: Int): TermName = bitmapPrefix ++ n.toString
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index 6d1a006ed..1e0beb5f3 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -4,7 +4,7 @@ package core
import Periods._, Contexts._, Symbols._, Denotations._, Names._, NameOps._, Annotations._
import Types._, Flags._, Decorators._, DenotTransformers._, StdNames._, Scopes._, Comments._
-import NameOps._
+import NameOps._, NameKinds._
import Scopes.Scope
import collection.mutable
import collection.immutable.BitSet
@@ -107,7 +107,7 @@ object SymDenotations {
class SymDenotation private[SymDenotations] (
symbol: Symbol,
ownerIfExists: Symbol,
- final val name: Name,
+ initName: Name,
initFlags: FlagSet,
initInfo: Type,
initPrivateWithin: Symbol = NoSymbol) extends SingleDenotation(symbol) {
@@ -125,11 +125,18 @@ object SymDenotations {
// ------ Getting and setting fields -----------------------------
+ private[this] var myName = initName
private[this] var myFlags: FlagSet = adaptFlags(initFlags)
private[this] var myInfo: Type = initInfo
private[this] var myPrivateWithin: Symbol = initPrivateWithin
private[this] var myAnnotations: List[Annotation] = Nil
+ /** The name of the symbol */
+ def name = myName
+
+ /** Update the name; only called when unpickling top-level classes */
+ def name_=(n: Name) = myName = n
+
/** The owner of the symbol; overridden in NoDenotation */
def owner: Symbol = ownerIfExists
@@ -252,7 +259,7 @@ object SymDenotations {
*/
def effectiveName(implicit ctx: Context) =
if (this is ModuleClass) name.stripModuleClassSuffix
- else name.stripAvoidClashSuffix
+ else name.exclude(AvoidClashName)
/** The privateWithin boundary, NoSymbol if no boundary is given.
*/
@@ -367,7 +374,7 @@ object SymDenotations {
/** The expanded name of this denotation. */
final def expandedName(implicit ctx: Context) =
- if (is(ExpandedName) || isConstructor) name
+ if (name.is(ExpandedName) || isConstructor) name
else {
def legalize(name: Name): Name = // JVM method names may not contain `<' or `>' characters
if (is(Method)) name.replace('<', '(').replace('>', ')') else name
@@ -377,49 +384,50 @@ object SymDenotations {
// might have been moved from different origins into the same class
/** The name with which the denoting symbol was created */
- final def originalName(implicit ctx: Context) = {
- val d = initial
- if (d is ExpandedName) d.name.unexpandedName else d.name // !!!DEBUG, was: effectiveName
- }
+ final def originalName(implicit ctx: Context) =
+ initial.effectiveName
/** The encoded full path name of this denotation, where outer names and inner names
* are separated by `separator` strings.
* Never translates expansions of operators back to operator symbol.
- * Drops package objects. Represents terms in the owner chain by a simple `~`.
+ * Drops package objects. Represents each term in the owner chain by a simple `~`.
* (Note: scalac uses nothing to represent terms, which can cause name clashes
* between same-named definitions in different enclosing methods. Before this commit
* we used `$' but this can cause ambiguities with the class separator '$').
* A separator "" means "flat name"; the real separator in this case is "$" and
* enclosing packages do not form part of the name.
*/
- def fullNameSeparated(separator: String)(implicit ctx: Context): Name = {
- var sep = separator
- var stopAtPackage = false
- if (sep.isEmpty) {
- sep = "$"
- stopAtPackage = true
- }
+ def fullNameSeparated(kind: QualifiedNameKind)(implicit ctx: Context): Name =
if (symbol == NoSymbol ||
owner == NoSymbol ||
owner.isEffectiveRoot ||
- stopAtPackage && owner.is(PackageClass)) name
+ kind == FlatName && owner.is(PackageClass)) name
else {
+ var filler = ""
var encl = owner
while (!encl.isClass && !encl.isPackageObject) {
encl = encl.owner
- sep += "~"
+ filler += "~"
+ }
+ var prefix = encl.fullNameSeparated(kind)
+ if (kind.separator == "$")
+ // duplicate scalac's behavior: don't write a double '$$' for module class members.
+ prefix = prefix.exclude(ModuleClassName)
+ def qualify(n: SimpleTermName) =
+ kind(prefix.toTermName, if (filler.isEmpty) n else termName(filler + n))
+ val fn = name rewrite {
+ case name: SimpleTermName => qualify(name)
+ case name @ AnyQualifiedName(_, _) => qualify(name.toSimpleName)
}
- if (owner.is(ModuleClass, butNot = Package) && sep == "$") sep = "" // duplicate scalac's behavior: don't write a double '$$' for module class members.
- val fn = encl.fullNameSeparated(separator) ++ sep ++ name
if (isType) fn.toTypeName else fn.toTermName
}
- }
+
/** The encoded flat name of this denotation, where joined names are separated by `separator` characters. */
- def flatName(implicit ctx: Context): Name = fullNameSeparated("")
+ def flatName(implicit ctx: Context): Name = fullNameSeparated(FlatName)
/** `fullName` where `.' is the separator character */
- def fullName(implicit ctx: Context): Name = fullNameSeparated(".")
+ def fullName(implicit ctx: Context): Name = fullNameSeparated(QualifiedName)
// ----- Tests -------------------------------------------------
@@ -460,13 +468,13 @@ object SymDenotations {
/** Is this symbol an anonymous class? */
final def isAnonymousClass(implicit ctx: Context): Boolean =
- isClass && (initial.name startsWith tpnme.ANON_CLASS)
+ isClass && (initial.name startsWith str.ANON_CLASS)
final def isAnonymousFunction(implicit ctx: Context) =
- this.symbol.is(Method) && (initial.name startsWith nme.ANON_FUN)
+ this.symbol.is(Method) && (initial.name startsWith str.ANON_FUN)
final def isAnonymousModuleVal(implicit ctx: Context) =
- this.symbol.is(ModuleVal) && (initial.name startsWith nme.ANON_CLASS)
+ this.symbol.is(ModuleVal) && (initial.name startsWith str.ANON_CLASS)
/** Is this a companion class method or companion object method?
* These methods are generated by Symbols#synthesizeCompanionMethod
@@ -505,8 +513,10 @@ object SymDenotations {
/** Is this symbol a package object or its module class? */
def isPackageObject(implicit ctx: Context): Boolean = {
- val poName = if (isType) nme.PACKAGE_CLS else nme.PACKAGE
- (name.toTermName == poName) && (owner is Package) && (this is Module)
+ val nameMatches =
+ if (isType) name == tpnme.PACKAGE.moduleClassName
+ else name == nme.PACKAGE
+ nameMatches && (owner is Package) && (this is Module)
}
/** Is this symbol an abstract type? */
@@ -922,14 +932,15 @@ object SymDenotations {
* and which is also defined in the same scope and compilation unit.
* NoSymbol if this class does not exist.
*/
- final def companionClass(implicit ctx: Context): Symbol = {
- val companionMethod = info.decls.denotsNamed(nme.COMPANION_CLASS_METHOD, selectPrivate).first
-
- if (companionMethod.exists)
- companionMethod.info.resultType.classSymbol
- else
- NoSymbol
- }
+ final def companionClass(implicit ctx: Context): Symbol =
+ if (is(Package)) NoSymbol
+ else {
+ val companionMethod = info.decls.denotsNamed(nme.COMPANION_CLASS_METHOD, selectPrivate).first
+ if (companionMethod.exists)
+ companionMethod.info.resultType.classSymbol
+ else
+ NoSymbol
+ }
final def scalacLinkedClass(implicit ctx: Context): Symbol =
if (this is ModuleClass) companionNamed(effectiveName.toTypeName)
@@ -1198,9 +1209,7 @@ object SymDenotations {
/** If denotation is private, remove the Private flag and expand the name if necessary */
def ensureNotPrivate(implicit ctx: Context) =
if (is(Private))
- copySymDenotation(
- name = expandedName,
- initFlags = this.flags &~ Private | ExpandedName)
+ copySymDenotation(name = expandedName, initFlags = this.flags &~ Private)
else this
}
@@ -1209,18 +1218,19 @@ object SymDenotations {
class ClassDenotation private[SymDenotations] (
symbol: Symbol,
ownerIfExists: Symbol,
- name: Name,
+ initName: Name,
initFlags: FlagSet,
initInfo: Type,
initPrivateWithin: Symbol,
initRunId: RunId)
- extends SymDenotation(symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) {
+ extends SymDenotation(symbol, ownerIfExists, initName, initFlags, initInfo, initPrivateWithin) {
import util.LRUCache
// ----- denotation fields and accessors ------------------------------
- if (initFlags is (Module, butNot = Package)) assert(name.isModuleClassName, s"module naming inconsistency: $name")
+ if (initFlags is (Module, butNot = Package))
+ assert(name.is(ModuleClassName), s"module naming inconsistency: ${name.debugString}")
/** The symbol asserted to have type ClassSymbol */
def classSymbol: ClassSymbol = symbol.asInstanceOf[ClassSymbol]
@@ -1530,7 +1540,7 @@ object SymDenotations {
!(this is Frozen) ||
(scope ne this.unforcedDecls) ||
sym.hasAnnotation(defn.ScalaStaticAnnot) ||
- sym.name.isInlineAccessor ||
+ sym.name.is(InlineAccessorName) ||
isUsecase, i"trying to enter $sym in $this, frozen = ${this is Frozen}")
scope.enter(sym)
@@ -1752,13 +1762,13 @@ object SymDenotations {
}
}
- private[this] var fullNameCache: SimpleMap[String, Name] = SimpleMap.Empty
- override final def fullNameSeparated(separator: String)(implicit ctx: Context): Name = {
- val cached = fullNameCache(separator)
+ private[this] var fullNameCache: SimpleMap[QualifiedNameKind, Name] = SimpleMap.Empty
+ override final def fullNameSeparated(kind: QualifiedNameKind)(implicit ctx: Context): Name = {
+ val cached = fullNameCache(kind)
if (cached != null) cached
else {
- val fn = super.fullNameSeparated(separator)
- fullNameCache = fullNameCache.updated(separator, fn)
+ val fn = super.fullNameSeparated(kind)
+ fullNameCache = fullNameCache.updated(kind, fn)
fn
}
}
@@ -1770,8 +1780,8 @@ object SymDenotations {
def constrNamed(cname: TermName) = info.decls.denotsNamed(cname).last.symbol
// denotsNamed returns Symbols in reverse order of occurrence
if (this.is(ImplClass)) constrNamed(nme.TRAIT_CONSTRUCTOR) // ignore normal constructor
- else
- constrNamed(nme.CONSTRUCTOR).orElse(constrNamed(nme.TRAIT_CONSTRUCTOR))
+ else if (this.is(Package)) NoSymbol
+ else constrNamed(nme.CONSTRUCTOR).orElse(constrNamed(nme.TRAIT_CONSTRUCTOR))
}
/** The parameter accessors of this class. Term and type accessors,
diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 79f8a6a45..e4d2d446f 100644
--- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -14,6 +14,7 @@ import Contexts._, Symbols._, Flags._, SymDenotations._, Types._, Scopes._, util
import StdNames._, NameOps._
import Decorators.{PreNamedString, StringInterpolators}
import classfile.ClassfileParser
+import util.Stats
import scala.util.control.NonFatal
object SymbolLoaders {
@@ -148,23 +149,79 @@ class SymbolLoaders {
override def sourceModule(implicit ctx: Context) = _sourceModule
def description = "package loader " + classpath.name
- private[core] val currentDecls: MutableScope = newScope
+ private var enterFlatClasses: Option[Context => Unit] = None
+
+ Stats.record("package scopes")
+
+ /** The scope of a package. This is different from a normal scope
+ * in three aspects:
+ *
+ * 1. Names of scope entries are kept in mangled form.
+ * 2. Some function types in the `scala` package are synthesized.
+ */
+ final class PackageScope extends MutableScope {
+ override def newScopeEntry(name: Name, sym: Symbol)(implicit ctx: Context): ScopeEntry =
+ super.newScopeEntry(name.mangled, sym)
+
+ override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
+ val mangled = name.mangled
+ val e = super.lookupEntry(mangled)
+ if (e != null) e
+ else if (_sourceModule.initialDenot.name == nme.scala_ && _sourceModule == defn.ScalaPackageVal &&
+ name.isTypeName && name.isSyntheticFunction)
+ newScopeEntry(defn.newFunctionNTrait(name.asTypeName))
+ else if (isFlatName(mangled.toSimpleName) && enterFlatClasses.isDefined) {
+ Stats.record("package scopes with flatnames entered")
+ enterFlatClasses.get(ctx)
+ lookupEntry(name)
+ }
+ else e
+ }
+
+ override def ensureComplete()(implicit ctx: Context) =
+ for (enter <- enterFlatClasses) enter(ctx)
+
+ override def newScopeLikeThis() = new PackageScope
+ }
+
+ private[core] val currentDecls: MutableScope = new PackageScope()
+
+ def isFlatName(name: SimpleTermName) = name.lastIndexOf('$', name.length - 2) >= 0
+
+ def isFlatName(classRep: ClassPath#ClassRep) = {
+ val idx = classRep.name.indexOf('$')
+ idx >= 0 && idx < classRep.name.length - 1
+ }
+
+ def maybeModuleClass(classRep: ClassPath#ClassRep) = classRep.name.last == '$'
+
+ private def enterClasses(root: SymDenotation, flat: Boolean)(implicit ctx: Context) = {
+ def isAbsent(classRep: ClassPath#ClassRep) =
+ !root.unforcedDecls.lookup(classRep.name.toTypeName).exists
+
+ if (!root.isRoot) {
+ for (classRep <- classpath.classes)
+ if (!maybeModuleClass(classRep) && isFlatName(classRep) == flat &&
+ (!flat || isAbsent(classRep))) // on 2nd enter of flat names, check that the name has not been entered before
+ initializeFromClassPath(root.symbol, classRep)
+ for (classRep <- classpath.classes)
+ if (maybeModuleClass(classRep) && isFlatName(classRep) == flat &&
+ isAbsent(classRep))
+ initializeFromClassPath(root.symbol, classRep)
+ }
+ }
def doComplete(root: SymDenotation)(implicit ctx: Context): Unit = {
assert(root is PackageClass, root)
- def maybeModuleClass(classRep: ClassPath#ClassRep) = classRep.name.last == '$'
val pre = root.owner.thisType
root.info = ClassInfo(pre, root.symbol.asClass, Nil, currentDecls, pre select sourceModule)
if (!sourceModule.isCompleted)
sourceModule.completer.complete(sourceModule)
- if (!root.isRoot) {
- for (classRep <- classpath.classes)
- if (!maybeModuleClass(classRep))
- initializeFromClassPath(root.symbol, classRep)
- for (classRep <- classpath.classes)
- if (maybeModuleClass(classRep) && !root.unforcedDecls.lookup(classRep.name.toTypeName).exists)
- initializeFromClassPath(root.symbol, classRep)
+ enterFlatClasses = Some { ctx =>
+ enterFlatClasses = None
+ enterClasses(root, flat = true)(ctx)
}
+ enterClasses(root, flat = false)
if (!root.isEmptyPackage)
for (pkg <- classpath.packages)
enterPackage(root.symbol, pkg)
diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala
index 95ff1cb75..e0d9aca2b 100644
--- a/compiler/src/dotty/tools/dotc/core/Symbols.scala
+++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala
@@ -19,6 +19,7 @@ import util.Positions._
import DenotTransformers._
import StdNames._
import NameOps._
+import NameKinds.LazyImplicitName
import ast.tpd.Tree
import ast.TreeTypeMap
import Constants.Constant
@@ -260,7 +261,7 @@ trait Symbols { this: Context =>
/** Create a synthetic lazy implicit value */
def newLazyImplicit(info: Type) =
- newSymbol(owner, freshName(nme.LAZY_IMPLICIT_PREFIX).toTermName, Lazy, info)
+ newSymbol(owner, LazyImplicitName.fresh(), Lazy, info)
/** Create a symbol representing a selftype declaration for class `cls`. */
def newSelfSym(cls: ClassSymbol, name: TermName = nme.WILDCARD, selfInfo: Type = NoType): TermSymbol =
diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
index 94b726491..82051b66c 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -11,6 +11,7 @@ import util.Stats._
import util.common._
import Names._
import NameOps._
+import NameKinds._
import Flags._
import StdNames.tpnme
import util.Positions.Position
@@ -464,11 +465,6 @@ class TypeApplications(val self: Type) extends AnyVal {
self
case _ =>
val v = tparam.paramVariance
- /* Not neeeded.
- if (v > 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.upper(self)
- else if (v < 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.lower(self)
- else
- */
TypeAlias(self, v)
}
@@ -510,13 +506,14 @@ class TypeApplications(val self: Type) extends AnyVal {
*/
final def baseTypeWithArgs(base: Symbol)(implicit ctx: Context): Type = ctx.traceIndented(s"btwa ${self.show} wrt $base", core, show = true) {
def default = self.baseTypeRef(base).appliedTo(baseArgInfos(base))
+ def isExpandedTypeParam(sym: Symbol) = sym.is(TypeParam) && sym.name.is(ExpandedName)
self match {
case tp: TypeRef =>
tp.info match {
case TypeBounds(_, hi) => hi.baseTypeWithArgs(base)
case _ => default
}
- case tp @ RefinedType(parent, name, _) if !tp.member(name).symbol.is(ExpandedTypeParam) =>
+ case tp @ RefinedType(parent, name, _) if !isExpandedTypeParam(tp.member(name).symbol) =>
tp.wrapIfMember(parent.baseTypeWithArgs(base))
case tp: TermRef =>
tp.underlying.baseTypeWithArgs(base)
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index 4c69c9484..c8c1886cc 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -7,6 +7,7 @@ import Symbols._
import Flags._
import Names._
import StdNames._, NameOps._
+import NameKinds.{ShadowedName, SkolemName}
import Scopes._
import Constants._
import Contexts._
@@ -1594,7 +1595,7 @@ object Types {
}
protected def asMemberOf(prefix: Type, allowPrivate: Boolean)(implicit ctx: Context): Denotation =
- if (name.isShadowedName) prefix.nonPrivateMember(name.revertShadowed)
+ if (name.is(ShadowedName)) prefix.nonPrivateMember(name.exclude(ShadowedName))
else if (!allowPrivate) prefix.nonPrivateMember(name)
else prefix.member(name)
@@ -1730,7 +1731,7 @@ object Types {
* the public name.
*/
def shadowed(implicit ctx: Context): NamedType =
- NamedType(prefix, name.shadowedName)
+ NamedType(prefix, name.derived(ShadowedName))
override def equals(that: Any) = that match {
case that: NamedType =>
@@ -1804,7 +1805,7 @@ object Types {
fixDenot(TermRef.withSig(prefix, name, sig), prefix)
override def shadowed(implicit ctx: Context): NamedType =
- fixDenot(TermRef.withSig(prefix, name.shadowedName, sig), prefix)
+ fixDenot(TermRef.withSig(prefix, name.derived(ShadowedName), sig), prefix)
override def equals(that: Any) = that match {
case that: TermRefWithSignature =>
@@ -3000,9 +3001,9 @@ object Types {
override def hashCode: Int = identityHash
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
- private var myRepr: String = null
- def repr(implicit ctx: Context) = {
- if (myRepr == null) myRepr = ctx.freshName("?")
+ private var myRepr: Name = null
+ def repr(implicit ctx: Context): Name = {
+ if (myRepr == null) myRepr = SkolemName.fresh()
myRepr
}
diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
index da875c906..27afa4d09 100644
--- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
+++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
@@ -5,6 +5,7 @@ package classfile
import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, Decorators._
import SymDenotations._, unpickleScala2.Scala2Unpickler._, Constants._, Annotations._, util.Positions._
+import NameKinds.{ModuleClassName, DefaultGetterName}
import ast.tpd._
import java.io.{ File, IOException }
import java.lang.Integer.toHexString
@@ -25,6 +26,8 @@ class ClassfileParser(
classRoot: ClassDenotation,
moduleRoot: ClassDenotation)(ictx: Context) {
+ //println(s"parsing ${classRoot.name.debugString} ${moduleRoot.name.debugString}")
+
import ClassfileConstants._
import ClassfileParser._
@@ -36,7 +39,7 @@ class ClassfileParser(
protected val staticScope: MutableScope = newScope // the scope of all static definitions
protected var pool: ConstantPool = _ // the classfile's constant pool
- protected var currentClassName: Name = _ // JVM name of the current class
+ protected var currentClassName: SimpleTermName = _ // JVM name of the current class
protected var classTParams = Map[Name,Symbol]()
classRoot.info = (new NoCompleter).withDecls(instanceScope)
@@ -44,8 +47,8 @@ class ClassfileParser(
private def currentIsTopLevel(implicit ctx: Context) = classRoot.owner is Flags.PackageClass
- private def mismatchError(c: Symbol) =
- throw new IOException(s"class file '${in.file}' has location not matching its contents: contains $c")
+ private def mismatchError(className: SimpleTermName) =
+ throw new IOException(s"class file '${in.file}' has location not matching its contents: contains class $className")
def run()(implicit ctx: Context): Option[Embedded] = try {
ctx.debuglog("[class] >> " + classRoot.fullName)
@@ -89,10 +92,8 @@ class ClassfileParser(
val nameIdx = in.nextChar
currentClassName = pool.getClassName(nameIdx)
- if (currentIsTopLevel) {
- val c = pool.getClassSymbol(nameIdx)
- if (c != classRoot.symbol) mismatchError(c)
- }
+ if (currentIsTopLevel && currentClassName != classRoot.fullName.toSimpleName)
+ mismatchError(currentClassName)
addEnclosingTParams()
@@ -239,21 +240,21 @@ class ClassfileParser(
final def objToAny(tp: Type)(implicit ctx: Context) =
if (tp.isDirectRef(defn.ObjectClass) && !ctx.phase.erasedTypes) defn.AnyType else tp
- private def sigToType(sig: TermName, owner: Symbol = null)(implicit ctx: Context): Type = {
+ private def sigToType(sig: SimpleTermName, owner: Symbol = null)(implicit ctx: Context): Type = {
var index = 0
val end = sig.length
def accept(ch: Char): Unit = {
assert(sig(index) == ch, (sig(index), ch))
index += 1
}
- def subName(isDelimiter: Char => Boolean): TermName = {
+ def subName(isDelimiter: Char => Boolean): SimpleTermName = {
val start = index
while (!isDelimiter(sig(index))) { index += 1 }
sig.slice(start, index)
}
// Warning: sigToType contains nested completers which might be forced in a later run!
// So local methods need their own ctx parameters.
- def sig2type(tparams: immutable.Map[Name,Symbol], skiptvs: Boolean)(implicit ctx: Context): Type = {
+ def sig2type(tparams: immutable.Map[Name, Symbol], skiptvs: Boolean)(implicit ctx: Context): Type = {
val tag = sig(index); index += 1
(tag: @switch) match {
case BYTE_TAG => defn.ByteType
@@ -590,7 +591,7 @@ class ClassfileParser(
def addDefaultGetter(attr: Symbol, n: Int) =
ctx.newSymbol(
owner = moduleRoot.symbol,
- name = nme.CONSTRUCTOR.defaultGetterName(n),
+ name = DefaultGetterName(nme.CONSTRUCTOR, n),
flags = attr.flags & Flags.AccessFlags,
info = defn.NothingType).entered
@@ -647,7 +648,10 @@ class ClassfileParser(
* and implicitly current class' superclasses.
*/
private def enterOwnInnerClasses()(implicit ctx: Context): Unit = {
- def className(name: Name): Name = name.drop(name.lastIndexOf('.') + 1)
+ def className(name: Name): Name = {
+ val name1 = name.toSimpleName
+ name1.drop(name1.lastIndexOf('.') + 1)
+ }
def enterClassAndModule(entry: InnerClassEntry, file: AbstractFile, jflags: Int) = {
ctx.base.loaders.enterClassAndModule(
@@ -883,7 +887,7 @@ class ClassfileParser(
private val len = in.nextChar
private val starts = new Array[Int](len)
private val values = new Array[AnyRef](len)
- private val internalized = new Array[TermName](len)
+ private val internalized = new Array[SimpleTermName](len)
{ var i = 1
while (i < starts.length) {
@@ -910,12 +914,12 @@ class ClassfileParser(
}
/** Return the name found at given index. */
- def getName(index: Int): TermName = {
+ def getName(index: Int): SimpleTermName = {
if (index <= 0 || len <= index)
errorBadIndex(index)
values(index) match {
- case name: TermName => name
+ case name: SimpleTermName => name
case null =>
val start = starts(index)
if (in.buf(start).toInt != CONSTANT_UTF8) errorBadTag(start)
@@ -926,7 +930,7 @@ class ClassfileParser(
}
/** Return the name found at given index in the constant pool, with '/' replaced by '.'. */
- def getExternalName(index: Int): TermName = {
+ def getExternalName(index: Int): SimpleTermName = {
if (index <= 0 || len <= index)
errorBadIndex(index)
@@ -943,9 +947,9 @@ class ClassfileParser(
val start = starts(index)
if (in.buf(start).toInt != CONSTANT_CLASS) errorBadTag(start)
val name = getExternalName(in.getChar(start + 1))
- if (name.isModuleClassName && (name ne nme.nothingRuntimeClass) && (name ne nme.nullRuntimeClass))
+ if (name.endsWith("$") && (name ne nme.nothingRuntimeClass) && (name ne nme.nullRuntimeClass))
// Null$ and Nothing$ ARE classes
- c = ctx.requiredModule(name.sourceModuleName)
+ c = ctx.requiredModule(name.dropRight(1))
else c = classNameToSymbol(name)
values(index) = c
}
@@ -955,7 +959,7 @@ class ClassfileParser(
/** Return the external name of the class info structure found at 'index'.
* Use 'getClassSymbol' if the class is sure to be a top-level class.
*/
- def getClassName(index: Int): TermName = {
+ def getClassName(index: Int): SimpleTermName = {
val start = starts(index)
if (in.buf(start).toInt != CONSTANT_CLASS) errorBadTag(start)
getExternalName(in.getChar(start + 1))
@@ -995,7 +999,7 @@ class ClassfileParser(
val start = starts(index)
if (in.buf(start).toInt != CONSTANT_CLASS) errorBadTag(start)
val name = getExternalName(in.getChar(start + 1))
- if (name(0) == ARRAY_TAG) {
+ if (name.firstPart(0) == ARRAY_TAG) {
c = sigToType(name)
values(index) = c
} else {
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala
index 2c93819d5..28916a781 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala
@@ -19,12 +19,12 @@ object DottyUnpickler {
class TreeSectionUnpickler(posUnpickler: Option[PositionUnpickler])
extends SectionUnpickler[TreeUnpickler]("ASTs") {
- def unpickle(reader: TastyReader, tastyName: TastyName.Table) =
- new TreeUnpickler(reader, tastyName, posUnpickler)
+ def unpickle(reader: TastyReader, nameAtRef: NameTable) =
+ new TreeUnpickler(reader, nameAtRef, posUnpickler)
}
class PositionsSectionUnpickler extends SectionUnpickler[PositionUnpickler]("Positions") {
- def unpickle(reader: TastyReader, tastyName: TastyName.Table) =
+ def unpickle(reader: TastyReader, nameAtRef: NameTable) =
new PositionUnpickler(reader)
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala b/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
index 3ff7298ce..270d6be56 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
@@ -4,84 +4,83 @@ package core
package tasty
import collection.mutable
-import Names.{Name, chrs}
-import Decorators._, NameOps._
+import Names.{Name, chrs, SimpleTermName, DerivedTermName}
+import NameOps.NameDecorator
+import NameKinds._
+import Decorators._
import TastyBuffer._
import scala.io.Codec
-import TastyName._
import TastyFormat._
class NameBuffer extends TastyBuffer(10000) {
import NameBuffer._
- private val nameRefs = new mutable.LinkedHashMap[TastyName, NameRef]
+ private val nameRefs = new mutable.LinkedHashMap[Name, NameRef]
- def nameIndex(name: TastyName): NameRef = nameRefs.get(name) match {
- case Some(ref) =>
- ref
- case None =>
- val ref = NameRef(nameRefs.size)
- nameRefs(name) = ref
- ref
- }
def nameIndex(name: Name): NameRef = {
- val tname =
- if (name.isShadowedName) Shadowed(nameIndex(name.revertShadowed))
- else Simple(name.toTermName)
- nameIndex(tname)
- }
-
- def nameIndex(str: String): NameRef = nameIndex(str.toTermName)
-
- def fullNameIndex(name: Name): NameRef = {
- val pos = name.lastIndexOf('.')
- if (pos > 0)
- nameIndex(Qualified(fullNameIndex(name.take(pos)), nameIndex(name.drop(pos + 1))))
- else
- nameIndex(name)
+ val name1 = name.toTermName
+ nameRefs.get(name1) match {
+ case Some(ref) =>
+ ref
+ case None =>
+ name1 match {
+ case SignedName(original, Signature(params, result)) =>
+ nameIndex(original); nameIndex(result); params.foreach(nameIndex)
+ case AnyQualifiedName(prefix, name) =>
+ nameIndex(prefix); nameIndex(name)
+ case AnyUniqueName(original, separator, num) =>
+ nameIndex(separator.toTermName)
+ if (!original.isEmpty) nameIndex(original)
+ case DerivedTermName(original, _) =>
+ nameIndex(original)
+ case _ =>
+ }
+ val ref = NameRef(nameRefs.size)
+ nameRefs(name1) = ref
+ ref
+ }
}
private def withLength(op: => Unit, lengthWidth: Int = 1): Unit = {
val lengthAddr = currentAddr
for (i <- 0 until lengthWidth) writeByte(0)
op
- val length = currentAddr.index - lengthAddr.index - 1
+ val length = currentAddr.index - lengthAddr.index - lengthWidth
putNat(lengthAddr, length, lengthWidth)
}
- def writeNameRef(ref: NameRef) = writeNat(ref.index)
+ def writeNameRef(ref: NameRef): Unit = writeNat(ref.index)
+ def writeNameRef(name: Name): Unit = writeNameRef(nameRefs(name.toTermName))
- def pickleName(name: TastyName): Unit = name match {
- case Simple(name) =>
- val bytes =
- if (name.length == 0) new Array[Byte](0)
- else Codec.toUTF8(chrs, name.start, name.length)
- writeByte(UTF8)
- writeNat(bytes.length)
- writeBytes(bytes, bytes.length)
- case Qualified(qualified, selector) =>
- writeByte(QUALIFIED)
- withLength { writeNameRef(qualified); writeNameRef(selector) }
- case Signed(original, params, result) =>
- writeByte(SIGNED)
- withLength(
+ def pickleNameContents(name: Name): Unit = {
+ val tag = name.toTermName.info.kind.tag
+ writeByte(tag)
+ name.toTermName match {
+ case name: SimpleTermName =>
+ val bytes =
+ if (name.length == 0) new Array[Byte](0)
+ else Codec.toUTF8(chrs, name.start, name.length)
+ writeNat(bytes.length)
+ writeBytes(bytes, bytes.length)
+ case AnyQualifiedName(prefix, name) =>
+ withLength { writeNameRef(prefix); writeNameRef(name) }
+ case AnyUniqueName(original, separator, num) =>
+ withLength {
+ writeNameRef(separator.toTermName)
+ writeNat(num)
+ if (!original.isEmpty) writeNameRef(original)
+ }
+ case VariantName(original, sign) =>
+ withLength { writeNameRef(original); writeNat(sign + 1) }
+ case AnyNumberedName(original, num) =>
+ withLength { writeNameRef(original); writeNat(num) }
+ case SignedName(original, Signature(params, result)) =>
+ withLength(
{ writeNameRef(original); writeNameRef(result); params.foreach(writeNameRef) },
if ((params.length + 2) * maxIndexWidth <= maxNumInByte) 1 else 2)
- case Expanded(prefix, original) =>
- writeByte(EXPANDED)
- withLength { writeNameRef(prefix); writeNameRef(original) }
- case ModuleClass(module) =>
- writeByte(OBJECTCLASS)
- withLength { writeNameRef(module) }
- case SuperAccessor(accessed) =>
- writeByte(SUPERACCESSOR)
- withLength { writeNameRef(accessed) }
- case DefaultGetter(method, paramNumber) =>
- writeByte(DEFAULTGETTER)
- withLength { writeNameRef(method); writeNat(paramNumber) }
- case Shadowed(original) =>
- writeByte(SHADOWED)
- withLength { writeNameRef(original) }
+ case DerivedTermName(original, _) =>
+ withLength { writeNameRef(original) }
+ }
}
override def assemble(): Unit = {
@@ -89,7 +88,7 @@ class NameBuffer extends TastyBuffer(10000) {
for ((name, ref) <- nameRefs) {
assert(ref.index == i)
i += 1
- pickleName(name)
+ pickleNameContents(name)
}
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyBuffer.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyBuffer.scala
index 13bc95028..40782f534 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyBuffer.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyBuffer.scala
@@ -26,6 +26,9 @@ object TastyBuffer {
* the value of 4 gives a maximal array size of 256M.
*/
final val AddrWidth = 4
+
+ /** An address referring to a serialized name */
+ case class NameRef(index: Int) extends AnyVal
}
import TastyBuffer._
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index 8b2255e94..f03e279c6 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -33,11 +33,11 @@ Macro-format:
QUALIFIED Length qualified_NameRef selector_NameRef
SIGNED Length original_NameRef resultSig_NameRef paramSig_NameRef*
EXPANDED Length original_NameRef
+ UNIQUE Length separator_NameRef num_Nat original_NameRef?
OBJECTCLASS Length module_NameRef
SUPERACCESSOR Length accessed_NameRef
DEFAULTGETTER Length method_NameRef paramNumber_Nat
SHADOWED Length original_NameRef
- MANGLED Length mangle_NameRef name_NameRef
...
NameRef = Nat // ordinal number of name in name table, starting from 1.
@@ -222,12 +222,30 @@ object TastyFormat {
final val UTF8 = 1
final val QUALIFIED = 2
- final val SIGNED = 3
+ final val FLATTENED = 3
final val EXPANDED = 4
- final val OBJECTCLASS = 5
- final val SUPERACCESSOR = 6
- final val DEFAULTGETTER = 7
- final val SHADOWED = 8
+ final val EXPANDPREFIX = 5
+ final val TRAITSETTER = 6
+ final val UNIQUE = 10
+ final val DEFAULTGETTER = 11
+ final val VARIANT = 12
+ final val OUTERSELECT = 13
+
+ final val SUPERACCESSOR = 20
+ final val PROTECTEDACCESSOR = 21
+ final val PROTECTEDSETTER = 22
+ final val INITIALIZER = 23
+ final val SHADOWED = 24
+ final val AVOIDCLASH = 30
+ final val DIRECT = 31
+ final val FIELD = 32
+ final val SETTER = 33
+ final val EXTMETH = 34
+ final val OBJECTVAR = 39
+ final val OBJECTCLASS = 40
+
+ final val SIGNED = 63
+ final val firstInternalTag = 64
// AST tags
@@ -411,11 +429,14 @@ object TastyFormat {
def nameTagToString(tag: Int): String = tag match {
case UTF8 => "UTF8"
case QUALIFIED => "QUALIFIED"
- case SIGNED => "SIGNED"
+ case FLATTENED => "FLATTENED"
case EXPANDED => "EXPANDED"
+ case SIGNED => "SIGNED"
case OBJECTCLASS => "OBJECTCLASS"
case SUPERACCESSOR => "SUPERACCESSOR"
case DEFAULTGETTER => "DEFAULTGETTER"
+ case SHADOWED => "SHADOWED"
+ case VARIANT => "VARIANT"
}
def astTagToString(tag: Int): String = tag match {
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyName.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyName.scala
deleted file mode 100644
index 26807115c..000000000
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyName.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-package dotty.tools
-package dotc
-package core
-package tasty
-
-import core.Names.TermName
-import collection.mutable
-
-abstract class TastyName
-
-object TastyName {
-
- case class NameRef(index: Int) extends AnyVal
-
- case class Simple(name: TermName) extends TastyName
- case class Qualified(qualified: NameRef, selector: NameRef) extends TastyName
- case class Signed(original: NameRef, params: List[NameRef], result: NameRef) extends TastyName
- case class Expanded(prefix: NameRef, original: NameRef) extends TastyName
- case class ModuleClass(module: NameRef) extends TastyName
- case class SuperAccessor(accessed: NameRef) extends TastyName
- case class DefaultGetter(method: NameRef, num: Int) extends TastyName
- case class Shadowed(original: NameRef) extends TastyName
-
- class Table extends (NameRef => TastyName) {
- private val names = new mutable.ArrayBuffer[TastyName]
- def add(name: TastyName) = names += name
- def apply(ref: NameRef) = names(ref.index)
- def contents: Iterable[TastyName] = names
- }
-}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala
index c844d522e..cc2e4dd58 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala
@@ -9,10 +9,11 @@ import TastyBuffer._
import java.util.UUID
import core.Symbols.Symbol
import ast.tpd
+import Decorators._
class TastyPickler {
- private val sections = new mutable.ArrayBuffer[(TastyName.NameRef, TastyBuffer)]
+ private val sections = new mutable.ArrayBuffer[(NameRef, TastyBuffer)]
val uuid = UUID.randomUUID()
private val headerBuffer = {
@@ -28,7 +29,7 @@ class TastyPickler {
val nameBuffer = new NameBuffer
def newSection(name: String, buf: TastyBuffer) =
- sections += ((nameBuffer.nameIndex(name), buf))
+ sections += ((nameBuffer.nameIndex(name.toTermName), buf))
def assembleParts(): Array[Byte] = {
def lengthWithLength(buf: TastyBuffer) = {
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala
index ce3722ff1..a5c870881 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala
@@ -4,34 +4,24 @@ package tasty
import Contexts._, Decorators._
import printing.Texts._
-import TastyName._
+import Names.Name
import StdNames._
import TastyUnpickler._
-import TastyBuffer.Addr
+import TastyBuffer.{Addr, NameRef}
import util.Positions.{Position, offsetToInt}
import collection.mutable
class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
val unpickler = new TastyUnpickler(bytes)
- import unpickler.{tastyName, unpickle}
+ import unpickler.{nameAtRef, unpickle}
- def nameToString(name: TastyName): String = name match {
- case Simple(name) => name.toString
- case Qualified(qual, name) => nameRefToString(qual) + "." + nameRefToString(name)
- case Signed(original, params, result) =>
- i"${nameRefToString(original)}@${params.map(nameRefToString)}%,%:${nameRefToString(result)}"
- case Expanded(prefix, original) => s"$prefix${nme.EXPAND_SEPARATOR}$original"
- case ModuleClass(original) => nameRefToString(original) + "/MODULECLASS"
- case SuperAccessor(accessed) => nameRefToString(accessed) + "/SUPERACCESSOR"
- case DefaultGetter(meth, num) => nameRefToString(meth) + "/DEFAULTGETTER" + num
- case Shadowed(original) => nameRefToString(original) + "/SHADOWED"
- }
+ def nameToString(name: Name): String = name.debugString
- def nameRefToString(ref: NameRef): String = nameToString(tastyName(ref))
+ def nameRefToString(ref: NameRef): String = nameToString(nameAtRef(ref))
def printNames() =
- for ((name, idx) <- tastyName.contents.zipWithIndex) {
+ for ((name, idx) <- nameAtRef.contents.zipWithIndex) {
val index = "%4d: ".format(idx)
println(index + nameToString(name))
}
@@ -46,7 +36,7 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
class TreeSectionUnpickler extends SectionUnpickler[Unit]("ASTs") {
import TastyFormat._
- def unpickle(reader: TastyReader, tastyName: TastyName.Table): Unit = {
+ def unpickle(reader: TastyReader, tastyName: NameTable): Unit = {
import reader._
var indent = 0
def newLine() = {
@@ -116,7 +106,7 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
}
class PositionSectionUnpickler extends SectionUnpickler[Unit]("Positions") {
- def unpickle(reader: TastyReader, tastyName: TastyName.Table): Unit = {
+ def unpickle(reader: TastyReader, tastyName: NameTable): Unit = {
print(s"${reader.endAddr.index - reader.currentAddr.index}")
val positions = new PositionUnpickler(reader).positions
println(s" position bytes:")
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyReader.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyReader.scala
index e583c4793..af5e78891 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyReader.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyReader.scala
@@ -4,7 +4,6 @@ package core
package tasty
import TastyBuffer._
-import TastyName.NameRef
import collection.mutable
/** A byte array buffer that can be filled with bytes or natural numbers in TASTY format,
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
index 8a1f58acd..37a3c2e76 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
@@ -4,14 +4,23 @@ package tasty
import scala.collection.mutable
import TastyFormat._
-import Names.{Name, termName}
+import TastyBuffer.NameRef
+import Names.{Name, TermName, termName, EmptyTermName}
+import NameKinds._
import java.util.UUID
object TastyUnpickler {
class UnpickleException(msg: String) extends Exception(msg)
abstract class SectionUnpickler[R](val name: String) {
- def unpickle(reader: TastyReader, tastyName: TastyName.Table): R
+ def unpickle(reader: TastyReader, nameAtRef: NameTable): R
+ }
+
+ class NameTable extends (NameRef => TermName) {
+ private val names = new mutable.ArrayBuffer[TermName]
+ def add(name: TermName) = names += name
+ def apply(ref: NameRef) = names(ref.index)
+ def contents: Iterable[TermName] = names
}
}
@@ -23,18 +32,15 @@ class TastyUnpickler(reader: TastyReader) {
def this(bytes: Array[Byte]) = this(new TastyReader(bytes))
private val sectionReader = new mutable.HashMap[String, TastyReader]
- val tastyName = new TastyName.Table
+ val nameAtRef = new NameTable
- def check(cond: Boolean, msg: => String) =
+ private def check(cond: Boolean, msg: => String) =
if (!cond) throw new UnpickleException(msg)
- def readString(): String = {
- val TastyName.Simple(name) = tastyName(readNameRef())
- name.toString
- }
+ private def readName(): TermName = nameAtRef(readNameRef())
+ private def readString(): String = readName().toString
- def readName(): TastyName = {
- import TastyName._
+ private def readNameContents(): TermName = {
val tag = readByte()
val length = readNat()
val start = currentAddr
@@ -42,24 +48,30 @@ class TastyUnpickler(reader: TastyReader) {
val result = tag match {
case UTF8 =>
goto(end)
- Simple(termName(bytes, start.index, length))
- case QUALIFIED =>
- Qualified(readNameRef(), readNameRef())
- case SIGNED =>
- val original = readNameRef()
- val result = readNameRef()
- val params = until(end)(readNameRef())
- Signed(original, params, result)
- case EXPANDED =>
- Expanded(readNameRef(), readNameRef())
- case OBJECTCLASS =>
- ModuleClass(readNameRef())
- case SUPERACCESSOR =>
- SuperAccessor(readNameRef())
+ termName(bytes, start.index, length)
+ case QUALIFIED | FLATTENED | EXPANDED | EXPANDPREFIX =>
+ qualifiedNameKindOfTag(tag)(readName(), readName().asSimpleName)
+ case UNIQUE =>
+ val separator = readName().toString
+ val num = readNat()
+ val originals = until(end)(readName())
+ val original = if (originals.isEmpty) EmptyTermName else originals.head
+ uniqueNameKindOfSeparator(separator)(original, num)
case DEFAULTGETTER =>
- DefaultGetter(readNameRef(), readNat())
- case SHADOWED =>
- Shadowed(readNameRef())
+ DefaultGetterName(readName(), readNat())
+ case VARIANT =>
+ VariantName(readName(), readNat() - 1)
+ case OUTERSELECT =>
+ OuterSelectName(readName(), readNat())
+ case SIGNED =>
+ val original = readName()
+ val result = readName().toTypeName
+ val params = until(end)(readName().toTypeName)
+ var sig = Signature(params, result)
+ if (sig == Signature.NotAMethod) sig = Signature.NotAMethod
+ SignedName(original, sig)
+ case _ =>
+ simpleNameKindOfTag(tag)(readName())
}
assert(currentAddr == end, s"bad name $result $start $currentAddr $end")
result
@@ -77,10 +89,10 @@ class TastyUnpickler(reader: TastyReader) {
new UUID(readUncompressedLong(), readUncompressedLong())
}
- val uuid = readHeader()
+ private val uuid = readHeader()
locally {
- until(readEnd()) { tastyName.add(readName()) }
+ until(readEnd()) { nameAtRef.add(readNameContents()) }
while (!isAtEnd) {
val secName = readString()
val secEnd = readEnd()
@@ -91,5 +103,5 @@ class TastyUnpickler(reader: TastyReader) {
def unpickle[R](sec: SectionUnpickler[R]): Option[R] =
for (reader <- sectionReader.get(sec.name)) yield
- sec.unpickle(reader, tastyName)
+ sec.unpickle(reader, nameAtRef)
}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
index 902d01c21..5d33738c2 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
@@ -9,16 +9,18 @@ import TastyFormat._
import Contexts._, Symbols._, Types._, Names._, Constants._, Decorators._, Annotations._, StdNames.tpnme, NameOps._
import collection.mutable
import typer.Inliner
-import NameOps._
+import NameOps._, NameKinds._
import StdNames.nme
import TastyBuffer._
import TypeApplications._
+import transform.SymUtils._
+import config.Config
class TreePickler(pickler: TastyPickler) {
val buf = new TreeBuffer
pickler.newSection("ASTs", buf)
import buf._
- import pickler.nameBuffer.{nameIndex, fullNameIndex}
+ import pickler.nameBuffer.nameIndex
import ast.tpd._
private val symRefs = new mutable.HashMap[Symbol, Addr]
@@ -52,28 +54,8 @@ class TreePickler(pickler: TastyPickler) {
}
private def pickleName(name: Name): Unit = writeNat(nameIndex(name).index)
- private def pickleName(name: TastyName): Unit = writeNat(nameIndex(name).index)
- private def pickleNameAndSig(name: Name, sig: Signature) = {
- val Signature(params, result) = sig
- pickleName(TastyName.Signed(nameIndex(name), params.map(fullNameIndex), fullNameIndex(result)))
- }
-
- private def pickleName(sym: Symbol)(implicit ctx: Context): Unit = {
- def encodeSuper(name: Name): TastyName.NameRef =
- if (sym is Flags.SuperAccessor) {
- val SuperAccessorName(n) = name
- nameIndex(TastyName.SuperAccessor(nameIndex(n)))
- }
- else nameIndex(name)
- val nameRef =
- if (sym is Flags.ExpandedName)
- nameIndex(
- TastyName.Expanded(
- nameIndex(sym.name.expandedPrefix),
- encodeSuper(sym.name.unexpandedName)))
- else encodeSuper(sym.name)
- writeNat(nameRef.index)
- }
+ private def pickleNameAndSig(name: Name, sig: Signature) =
+ pickleName(SignedName(name.toTermName, sig))
private def pickleSymRef(sym: Symbol)(implicit ctx: Context) = symRefs.get(sym) match {
case Some(label) =>
@@ -126,7 +108,7 @@ class TreePickler(pickler: TastyPickler) {
writeLongInt(java.lang.Double.doubleToRawLongBits(c.doubleValue))
case StringTag =>
writeByte(STRINGconst)
- writeNat(nameIndex(c.stringValue).index)
+ pickleName(c.stringValue.toTermName)
case NullTag =>
writeByte(NULLconst)
case ClazzTag =>
@@ -160,7 +142,7 @@ class TreePickler(pickler: TastyPickler) {
withLength { pickleType(tycon); args.foreach(pickleType(_)) }
case ConstantType(value) =>
pickleConstant(value)
- case tpe: TypeRef if tpe.info.isAlias && tpe.symbol.is(Flags.AliasPreferred) =>
+ case tpe: TypeRef if tpe.info.isAlias && tpe.symbol.isAliasPreferred =>
pickleType(tpe.superType)
case tpe: WithFixedSym =>
val sym = tpe.symbol
@@ -178,7 +160,7 @@ class TreePickler(pickler: TastyPickler) {
}
if (sym.is(Flags.Package)) {
writeByte(if (tpe.isType) TYPEREFpkg else TERMREFpkg)
- pickleName(qualifiedName(sym))
+ pickleName(sym.fullName)
}
else if (sym is Flags.BindDefinedType) {
registerDef(sym)
@@ -278,7 +260,7 @@ class TreePickler(pickler: TastyPickler) {
def picklePackageRef(pkg: Symbol)(implicit ctx: Context): Unit = {
writeByte(TERMREFpkg)
- pickleName(qualifiedName(pkg))
+ pickleName(pkg.fullName)
}
def pickleMethodic(tag: Int, tpe: LambdaType)(implicit ctx: Context) = {
@@ -312,7 +294,7 @@ class TreePickler(pickler: TastyPickler) {
registerDef(sym)
writeByte(tag)
withLength {
- pickleName(sym)
+ pickleName(sym.name)
pickleParams
tpt match {
case templ: Template => pickleTree(tpt)
@@ -370,7 +352,7 @@ class TreePickler(pickler: TastyPickler) {
case Select(qual, name) =>
writeByte(if (name.isTypeName) SELECTtpt else SELECT)
val realName = tree.tpe match {
- case tp: NamedType if tp.name.isShadowedName => tp.name
+ case tp: NamedType if tp.name.is(ShadowedName) => tp.name
case _ => name
}
val sig = tree.tpe.signature
@@ -575,10 +557,6 @@ class TreePickler(pickler: TastyPickler) {
pickleName(id.name)
}
- def qualifiedName(sym: Symbol)(implicit ctx: Context): TastyName =
- if (sym.isRoot || sym.owner.isRoot) TastyName.Simple(sym.name.toTermName)
- else TastyName.Qualified(nameIndex(qualifiedName(sym.owner)), nameIndex(sym.name))
-
def pickleModifiers(sym: Symbol)(implicit ctx: Context): Unit = {
import Flags._
val flags = sym.flags
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
index a186d1ce4..2908c541e 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
@@ -5,6 +5,7 @@ package tasty
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._
import StdNames._, Denotations._, Flags._, Constants._, Annotations._
+import NameKinds._
import util.Positions._
import ast.{tpd, Trees, untpd}
import Trees._
@@ -15,15 +16,15 @@ import scala.collection.mutable.ListBuffer
import scala.collection.{ mutable, immutable }
import config.Printers.pickling
import typer.Checking
+import config.Config
/** Unpickler for typed trees
* @param reader the reader from which to unpickle
* @param tastyName the nametable
* @param posUNpicklerOpt the unpickler for positions, if it exists
*/
-class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpicklerOpt: Option[PositionUnpickler]) {
+class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpicklerOpt: Option[PositionUnpickler]) {
import TastyFormat._
- import TastyName._
import TreeUnpickler._
import tpd._
@@ -74,20 +75,6 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
new TreeReader(reader).readTopLevel()(ctx.addMode(Mode.AllowDependentFunctions))
}
- def toTermName(tname: TastyName): TermName = tname match {
- case Simple(name) => name
- case Qualified(qual, name) => toTermName(qual) ++ "." ++ toTermName(name)
- case Signed(original, params, result) => toTermName(original)
- case Shadowed(original) => toTermName(original).shadowedName
- case Expanded(prefix, original) => toTermName(original).expandedName(toTermName(prefix))
- case ModuleClass(original) => toTermName(original).moduleClassName.toTermName
- case SuperAccessor(accessed) => toTermName(accessed).superName
- case DefaultGetter(meth, num) => ???
- }
-
- def toTermName(ref: NameRef): TermName = toTermName(tastyName(ref))
- def toTypeName(ref: NameRef): TypeName = toTermName(ref).toTypeName
-
class Completer(owner: Symbol, reader: TastyReader) extends LazyType {
import reader._
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
@@ -165,17 +152,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
else tag
}
- def readName(): TermName = toTermName(readNameRef())
-
- def readNameSplitSig()(implicit ctx: Context): Any /* TermName | (TermName, Signature) */ =
- tastyName(readNameRef()) match {
- case Signed(original, params, result) =>
- var sig = Signature(params map toTypeName, toTypeName(result))
- if (sig == Signature.NotAMethod) sig = Signature.NotAMethod
- (toTermName(original), sig)
- case name =>
- toTermName(name)
- }
+ def readName(): TermName = nameAtRef(readNameRef())
// ------ Reading types -----------------------------------------------------
@@ -305,9 +282,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
val name = readName().toTypeName
TypeRef(readType(), name)
case TERMREF =>
- readNameSplitSig() match {
- case name: TermName => TermRef.all(readType(), name)
- case (name: TermName, sig: Signature) => TermRef.withSig(readType(), name, sig)
+ readName() match {
+ case SignedName(name, sig) => TermRef.withSig(readType(), name, sig)
+ case name => TermRef.all(readType(), name)
}
case THIS =>
ThisType.raw(readType().asInstanceOf[TypeRef])
@@ -438,9 +415,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
val start = currentAddr
val tag = readByte()
val end = readEnd()
- val rawName = tastyName(readNameRef())
- var name: Name = toTermName(rawName)
+ var name: Name = readName()
if (tag == TYPEDEF || tag == TYPEPARAM) name = name.toTypeName
+ val mname = name.mangled
skipParams()
val ttag = nextUnsharedTag
val isAbsType = isAbstractType(ttag)
@@ -451,19 +428,15 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
val rhsIsEmpty = noRhs(end)
if (!rhsIsEmpty) skipTree()
val (givenFlags, annots, privateWithin) = readModifiers(end)
- def nameFlags(tname: TastyName): FlagSet = tname match {
- case TastyName.Expanded(_, original) => ExpandedName | nameFlags(tastyName(original))
- case TastyName.SuperAccessor(_) => Flags.SuperAccessor
- case _ => EmptyFlags
- }
pickling.println(i"creating symbol $name at $start with flags $givenFlags")
- val flags = normalizeFlags(tag, givenFlags | nameFlags(rawName), name, isAbsType, rhsIsEmpty)
+ val flags = normalizeFlags(tag, givenFlags, name, isAbsType, rhsIsEmpty)
def adjustIfModule(completer: LazyType) =
if (flags is Module) ctx.adjustModuleCompleter(completer, name) else completer
val sym =
- roots.find(root => (root.owner eq ctx.owner) && root.name == name) match {
+ roots.find(root => (root.owner eq ctx.owner) && root.name.mangled == mname) match {
case Some(rootd) =>
pickling.println(i"overwriting ${rootd.symbol} # ${rootd.hashCode}")
+ rootd.name = name
rootd.info = adjustIfModule(
new Completer(ctx.owner, subReader(start, end)) with SymbolLoaders.SecondCompleter)
rootd.flags = flags &~ Touched // allow one more completion
@@ -886,7 +859,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
val localCtx =
if (name == nme.CONSTRUCTOR) ctx.addMode(Mode.InSuperCall) else ctx
val qual = readTerm()(localCtx)
- val unshadowed = if (name.isShadowedName) name.revertShadowed else name
+ val unshadowed = name.exclude(ShadowedName)
untpd.Select(qual, unshadowed).withType(tpf(qual.tpe.widenIfUnstable))
}
@@ -905,9 +878,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
case SELECT =>
def readRest(name: Name, sig: Signature) =
completeSelect(name, TermRef.withSig(_, name.asTermName, sig))
- readNameSplitSig match {
- case name: Name => readRest(name, Signature.NotAMethod)
- case (name: Name, sig: Signature) => readRest(name, sig)
+ readName() match {
+ case SignedName(name, sig) => readRest(name, sig)
+ case name => readRest(name, Signature.NotAMethod)
}
case SELECTtpt =>
val name = readName().toTypeName
diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/PickleBuffer.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/PickleBuffer.scala
index 6ee9f1f9e..2a789dca9 100644
--- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/PickleBuffer.scala
+++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/PickleBuffer.scala
@@ -224,12 +224,12 @@ object PickleBuffer {
DEFAULTPARAM -> (DefaultParameterized, Trait),
BRIDGE -> Bridge,
ACCESSOR -> Accessor,
- SUPERACCESSOR -> SuperAccessor,
+ SUPERACCESSOR -> Scala2SuperAccessor,
PARAMACCESSOR -> ParamAccessor,
MODULEVAR -> Scala2ModuleVar,
LAZY -> Lazy,
MIXEDIN -> (MixedIn, Scala2Existential),
- EXPANDEDNAME -> ExpandedName,
+ EXPANDEDNAME -> Scala2ExpandedName,
IMPLCLASS -> (Scala2PreSuper, ImplClass),
SPECIALIZED -> Specialized,
VBRIDGE -> VBridge,
diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index cf99bb022..1db3ebcb0 100644
--- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -9,6 +9,7 @@ import java.lang.Double.longBitsToDouble
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
+import NameKinds.{Scala2MethodNameKinds, SuperAccessorName, ExpandedName}
import dotty.tools.dotc.typer.ProtoTypes.{FunProtoTyped, FunProto}
import util.Positions._
import dotty.tools.dotc.ast.{tpd, Trees, untpd}, ast.tpd._
@@ -18,6 +19,7 @@ import printing.Printer
import io.AbstractFile
import util.common._
import typer.Checking.checkNonCyclic
+import transform.SymUtils._
import PickleBuffer._
import PickleFormat._
import Decorators._
@@ -361,7 +363,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
}
def slowSearch(name: Name): Symbol =
- owner.info.decls.find(_.name == name).getOrElse(NoSymbol)
+ owner.info.decls.find(_.name == name)
def nestedObjectSymbol: Symbol = {
// If the owner is overloaded (i.e. a method), it's not possible to select the
@@ -420,10 +422,10 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
// symbols that were pickled with Pickler.writeSymInfo
val nameref = readNat()
- val name0 = at(nameref, readName)
+ var name = at(nameref, readName)
val owner = readSymbolRef()
- var flags = unpickleScalaFlags(readLongNat(), name0.isTypeName)
+ var flags = unpickleScalaFlags(readLongNat(), name.isTypeName)
if (flags is DefaultParameter) {
// DefaultParameterized flag now on method, not parameter
//assert(flags is Param, s"$name0 in $owner")
@@ -431,18 +433,33 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
owner.setFlag(DefaultParameterized)
}
- val name1 = name0.adjustIfModuleClass(flags)
- val name = if (name1 == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR else name1
+ name = name.adjustIfModuleClass(flags)
+ if (flags is Method) {
+ name =
+ if (name == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR
+ else name.asTermName.unmangle(Scala2MethodNameKinds)
+ }
+ if ((flags is Scala2ExpandedName) && name.isSimple) {
+ name = name.unmangle(ExpandedName)
+ flags = flags &~ Scala2ExpandedName
+ }
+ if (flags is Scala2SuperAccessor) {
+ name = name.asTermName.unmangle(SuperAccessorName)
+ flags = flags &~ Scala2SuperAccessor
+ }
- def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass)
- def isModuleClassRoot = (name == moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module)
- def isModuleRoot = (name == moduleClassRoot.name.sourceModuleName) && (owner == moduleClassRoot.owner) && (flags is Module)
+ val mname = name.mangled
+ def nameMatches(rootName: Name) = mname == rootName.mangled
+ def isClassRoot = nameMatches(classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass)
+ def isModuleClassRoot = nameMatches(moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module)
+ def isModuleRoot = nameMatches(moduleClassRoot.name.sourceModuleName) && (owner == moduleClassRoot.owner) && (flags is Module)
//if (isClassRoot) println(s"classRoot of $classRoot found at $readIndex, flags = $flags") // !!! DEBUG
//if (isModuleRoot) println(s"moduleRoot of $moduleRoot found at $readIndex, flags = $flags") // !!! DEBUG
//if (isModuleClassRoot) println(s"moduleClassRoot of $moduleClassRoot found at $readIndex, flags = $flags") // !!! DEBUG
def completeRoot(denot: ClassDenotation, completer: LazyType): Symbol = {
+ denot.name = name
denot.setFlag(flags)
denot.resetFlag(Touched) // allow one more completion
denot.info = completer
@@ -470,7 +487,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
var flags1 = flags
if (flags is TypeParam) {
name1 = name1.expandedName(owner)
- flags1 |= owner.typeParamCreationFlags | ExpandedName
+ flags1 |= owner.typeParamCreationFlags
}
ctx.newSymbol(owner, name1, flags1, localMemberUnpickler, coord = start)
case CLASSsym =>
@@ -546,9 +563,9 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
else tp1
if (denot.isConstructor) addConstructorTypeParams(denot)
if (atEnd) {
- assert(!(denot is SuperAccessor), denot)
+ assert(!denot.isSuperAccessor, denot)
} else {
- assert(denot is (SuperAccessor | ParamAccessor), denot)
+ assert(denot.is(ParamAccessor) || denot.isSuperAccessor, denot)
def disambiguate(alt: Symbol) = { // !!! DEBUG
ctx.debugTraceIndented(s"disambiguating ${denot.info} =:= ${denot.owner.thisType.memberInfo(alt)} ${denot.owner}") {
denot.info matches denot.owner.thisType.memberInfo(alt)
@@ -1022,7 +1039,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
val rhs = readTreeRef()
val params = until(end, readIdentRef)
val ldef = DefDef(symbol.asTerm, rhs)
- def isCaseLabel(sym: Symbol) = sym.name.startsWith(nme.CASEkw)
+ def isCaseLabel(sym: Symbol) = sym.name.startsWith(nme.CASEkw.toString)
if (isCaseLabel(symbol)) ldef
else Block(ldef :: Nil, Apply(Ident(symbol.termRef), Nil))
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 3e3673e5e..3112be659 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -12,6 +12,7 @@ import core._
import Flags._
import Contexts._
import Names._
+import NameKinds.WildcardParamName
import ast.{Positioned, Trees, untpd}
import ast.Trees._
import Decorators._
@@ -20,7 +21,6 @@ import util.Positions._
import Constants._
import ScriptParsers._
import Comments._
-
import scala.annotation.{tailrec, switch}
import util.DotClass
import rewrite.Rewrites.patch
@@ -1168,7 +1168,7 @@ object Parsers {
def bindingName(): TermName =
if (in.token == USCORE) {
in.nextToken()
- ctx.freshName(nme.USCORE_PARAM_PREFIX).toTermName
+ WildcardParamName.fresh()
}
else ident()
@@ -1224,7 +1224,7 @@ object Parsers {
path(thisOK = true)
case USCORE =>
val start = in.skipToken()
- val pname = ctx.freshName(nme.USCORE_PARAM_PREFIX).toTermName
+ val pname = WildcardParamName.fresh()
val param = ValDef(pname, TypeTree(), EmptyTree).withFlags(SyntheticTermParam)
.withPos(Position(start))
placeholderParams = param :: placeholderParams
@@ -1705,7 +1705,7 @@ object Parsers {
if (isConcreteOwner || in.token != USCORE) ident().toTypeName
else {
in.nextToken()
- ctx.freshName(nme.USCORE_PARAM_PREFIX).toTypeName
+ WildcardParamName.fresh().toTypeName
}
val hkparams = typeParamClauseOpt(ParamOwner.TypeParam)
val bounds =
diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala
index ff5019dc9..b0fa8d760 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala
@@ -37,7 +37,7 @@ object Scanners {
var lastOffset: Offset = 0
/** the name of an identifier */
- var name: TermName = null
+ var name: SimpleTermName = null
/** the string value of a literal */
var strVal: String = null
@@ -98,7 +98,7 @@ object Scanners {
/** Clear buffer and set name and token */
def finishNamed(idtoken: Token = IDENTIFIER, target: TokenData = this): Unit = {
- target.name = flushBuf(litBuf).toTermName
+ target.name = termName(flushBuf(litBuf))
target.token = idtoken
if (idtoken == IDENTIFIER) {
val idx = target.name.start
diff --git a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
index d2ea9240c..770b826fd 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
@@ -129,7 +129,7 @@ abstract class TokensCommon {
final val lastParen = RBRACE
def buildKeywordArray(keywords: TokenSet) = {
- def start(tok: Token) = tokenString(tok).toTermName.start
+ def start(tok: Token) = tokenString(tok).toTermName.asSimpleName.start
def sourceKeywords = keywords.toList.filter { (kw: Token) =>
val ts = tokenString(kw)
(ts != null) && !ts.contains(' ')
diff --git a/compiler/src/dotty/tools/dotc/parsing/package.scala b/compiler/src/dotty/tools/dotc/parsing/package.scala
index 8b113ed96..cdb30d0be 100644
--- a/compiler/src/dotty/tools/dotc/parsing/package.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/package.scala
@@ -10,7 +10,7 @@ package object parsing {
def precedence(operator: Name): Int =
if (operator eq nme.ERROR) -1
else {
- val firstCh = operator(0)
+ val firstCh = operator.firstPart.head
if (isScalaLetter(firstCh)) 1
else if (operator.isOpAssignmentName) 0
else firstCh match {
diff --git a/compiler/src/dotty/tools/dotc/printing/Formatting.scala b/compiler/src/dotty/tools/dotc/printing/Formatting.scala
index aa25880c2..b35a07027 100644
--- a/compiler/src/dotty/tools/dotc/printing/Formatting.scala
+++ b/compiler/src/dotty/tools/dotc/printing/Formatting.scala
@@ -139,7 +139,7 @@ object Formatting {
seen.record(super.ParamRefNameString(param), param)
override def toTextRef(tp: SingletonType): Text = tp match {
- case tp: SkolemType => seen.record(tp.repr, tp)
+ case tp: SkolemType => seen.record(tp.repr.toString, tp)
case _ => super.toTextRef(tp)
}
}
diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
index c762bbeaf..375edc3cb 100644
--- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -97,11 +97,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
|| (sym.name == nme.PACKAGE) // package
)
- def nameString(name: Name): String = name.toString + {
- if (ctx.settings.debugNames.value)
- if (name.isTypeName) "/T" else "/V"
- else ""
- }
+ def nameString(name: Name): String = name.toString
def toText(name: Name): Text = Str(nameString(name))
@@ -135,8 +131,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
toTextRHS(tp)
case tp: TermRef
if !tp.denotationIsCurrent && !homogenizedView || // always print underlying when testing picklers
- tp.symbol.is(Module) ||
- tp.symbol.name.isImportName =>
+ tp.symbol.is(Module) || tp.symbol.name == nme.IMPORT =>
toTextRef(tp) ~ ".type"
case tp: TermRef if tp.denot.isOverloaded =>
"<overloaded " ~ toTextRef(tp) ~ ">"
@@ -268,7 +263,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
if (idx >= 0) selfRecName(idx + 1)
else "{...}.this" // TODO move underlying type to an addendum, e.g. ... z3 ... where z3: ...
case tp: SkolemType =>
- if (homogenizedView) toText(tp.info) else tp.repr
+ if (homogenizedView) toText(tp.info) else toText(tp.repr)
}
}
diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 0b683d90c..c3f36cc46 100644
--- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -13,6 +13,7 @@ import Trees._
import TypeApplications._
import Decorators._
import config.Config
+import transform.SymUtils._
import scala.annotation.switch
import language.implicitConversions
@@ -58,11 +59,12 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
protected val PrintableFlags = (SourceModifierFlags | Label | Module | Local).toCommonFlags
- override def nameString(name: Name): String = name.decode.toString
+ override def nameString(name: Name): String =
+ if (ctx.settings.debugNames.value) name.debugString else name.decode.toString
override protected def simpleNameString(sym: Symbol): String = {
val name = if (ctx.property(XprintMode).isEmpty) sym.originalName else sym.name
- nameString(if (sym is ExpandedTypeParam) name.asTypeName.unexpandedName else name)
+ nameString(if (sym.is(TypeParam)) name.asTypeName.unexpandedName else name)
}
override def fullNameString(sym: Symbol): String =
@@ -130,7 +132,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
if (defn.isTupleClass(cls)) return toTextTuple(args)
return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close
case tp: TypeRef =>
- val hideType = !ctx.settings.debugAlias.value && (tp.symbol is AliasPreferred)
+ val hideType = !ctx.settings.debugAlias.value && (tp.symbol.isAliasPreferred)
if (hideType && !ctx.phase.erasedTypes && !tp.symbol.isCompleting) {
tp.info match {
case TypeAlias(alias) => return toText(alias)
@@ -154,8 +156,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
// one version of the annotation tree that has the correct positions).
withoutPos(super.toText(tp))
case tp: SelectionProto =>
- return "?{ " ~ toText(tp.name) ~ (" " provided !tp.name.decode.last.isLetterOrDigit) ~
- ": " ~ toText(tp.memberProto) ~ " }"
+ return "?{ " ~ toText(tp.name) ~
+ (" " provided !tp.name.toSimpleName.decode.last.isLetterOrDigit) ~
+ ": " ~ toText(tp.memberProto) ~ " }"
case tp: ViewProto =>
return toText(tp.argType) ~ " ?=>? " ~ toText(tp.resultType)
case tp @ FunProto(args, resultType, _) =>
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 87837fd82..20cd08426 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -237,7 +237,7 @@ object messages {
val msg = {
import core.Flags._
val maxDist = 3
- val decls = site.decls.flatMap { sym =>
+ val decls = site.decls.toList.flatMap { sym =>
if (sym.flagsUNSAFE.is(Synthetic | PrivateOrLocal) || sym.isConstructor) Nil
else List((sym.name.show, sym))
}
diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
index 8d704f9a2..5488d1979 100644
--- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
+++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
@@ -5,8 +5,10 @@ import ast.{Trees, tpd}
import core._, core.Decorators._
import Annotations._, Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._
import Names._, NameOps._, StdNames._
+import NameKinds.DefaultGetterName
import typer.Inliner
import typer.ErrorReporting.cyclicErrorMsg
+import transform.SymUtils._
import dotty.tools.io.Path
import java.io.PrintWriter
@@ -212,7 +214,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
// and can therefore be ignored.
def alwaysPresent(s: Symbol) =
s.isCompanionMethod || (csym.is(ModuleClass) && s.isConstructor)
- val decls = cinfo.decls.filterNot(alwaysPresent).toList
+ val decls = cinfo.decls.filter(!alwaysPresent(_)).toList
val apiDecls = apiDefinitions(decls)
val declSet = decls.toSet
@@ -222,7 +224,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
// We cannot filter out `LegacyApp` because it contains the main method,
// see the comment about main class discovery in `computeType`.
.filter(bc => !bc.is(Scala2x) || bc.eq(LegacyAppClass))
- .flatMap(_.classInfo.decls.filterNot(s => s.is(Private) || declSet.contains(s)))
+ .flatMap(_.classInfo.decls.filter(s => !(s.is(Private) || declSet.contains(s))))
// Inherited members need to be computed lazily because a class might contain
// itself as an inherited member, like in `class A { class B extends A }`,
// this works because of `classLikeCache`
@@ -299,7 +301,8 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
sym.owner.companionModule // default getters for class constructors are found in the companion object
else
sym.owner
- (0 until pnames.length).map(i => qual.info.member(sym.name.defaultGetterName(start + i)).exists)
+ (0 until pnames.length).map(i =>
+ qual.info.member(DefaultGetterName(sym.name, start + i)).exists)
} else
(0 until pnames.length).map(Function.const(false))
val params = (pnames, ptypes, defaults).zipped.map((pname, ptype, isDefault) =>
@@ -539,7 +542,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
val abs = sym.is(Abstract) || sym.is(Deferred) || absOver
val over = sym.is(Override) || absOver
new api.Modifiers(abs, over, sym.is(Final), sym.is(Sealed),
- sym.is(Implicit), sym.is(Lazy), sym.is(Macro), sym.is(SuperAccessor))
+ sym.is(Implicit), sym.is(Lazy), sym.is(Macro), sym.isSuperAccessor)
}
def apiAnnotations(s: Symbol): List[api.Annotation] = {
diff --git a/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala b/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
index 9c01aaa9a..f2ffaff5d 100644
--- a/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
+++ b/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
@@ -14,6 +14,7 @@ import DenotTransformers._
import Annotations._
import StdNames._
import NameOps._
+import NameKinds.{ExpandedName, TraitSetterName}
import ast.Trees._
/** This phase augments Scala2 traits with implementation classes and with additional members
@@ -66,16 +67,16 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
meth.copy(
owner = implClass,
name = mold.name.asTermName,
- flags = Method | JavaStatic | mold.flags & ExpandedName,
+ flags = Method | JavaStatic,
info = fullyParameterizedType(mold.info, mixin))
}
def traitSetter(getter: TermSymbol) =
getter.copy(
name = getter.ensureNotPrivate.name
- .expandedName(getter.owner, nme.TRAIT_SETTER_SEPARATOR)
+ .expandedName(getter.owner, TraitSetterName)
.asTermName.setterName,
- flags = Method | Accessor | ExpandedName,
+ flags = Method | Accessor,
info = MethodType(getter.info.resultType :: Nil, defn.UnitType))
for (sym <- mixin.info.decls) {
@@ -89,9 +90,9 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
else if (!sym.is(Deferred) && !sym.setter.exists &&
!sym.info.resultType.isInstanceOf[ConstantType])
traitSetter(sym.asTerm).enteredAfter(thisTransform)
- if ((sym.is(PrivateAccessor, butNot = ExpandedName) &&
+ if ((sym.is(PrivateAccessor) && !sym.name.is(ExpandedName) &&
(sym.isGetter || sym.isSetter)) // strangely, Scala 2 fields are also methods that have Accessor set.
- || sym.is(SuperAccessor)) // scala2 superaccessors are pickled as private, but are compiled as public expanded
+ || sym.isSuperAccessor) // scala2 superaccessors are pickled as private, but are compiled as public expanded
sym.ensureNotPrivate.installAfter(thisTransform)
}
ctx.log(i"Scala2x trait decls of $mixin = ${mixin.info.decls.toList.map(_.showDcl)}%\n %")
diff --git a/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala b/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
index cd05589c3..b9a9544f5 100644
--- a/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
@@ -12,6 +12,7 @@ import core.SymDenotations._
import core.StdNames.nme
import core.Names._
import core.NameOps._
+import core.NameKinds.TempResultName
import ast.Trees._
import SymUtils._
import collection.{ mutable, immutable }
@@ -138,7 +139,7 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo
val Select(_, nme.elem) = qual
recur(qual)
case Select(_, nme.elem) if refInfo.boxedRefClasses.contains(lhs.symbol.maybeOwner) =>
- val tempDef = transformFollowing(SyntheticValDef(ctx.freshName("ev$").toTermName, tree.rhs))
+ val tempDef = transformFollowing(SyntheticValDef(TempResultName.fresh(), tree.rhs))
transformFollowing(Block(tempDef :: Nil, cpy.Assign(tree)(lhs, ref(tempDef.symbol))))
case _ =>
tree
diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
index d64120085..4cee0d0de 100644
--- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
@@ -11,6 +11,7 @@ import core.Types._
import core.Names._
import core.StdNames._
import core.NameOps._
+import core.NameKinds.ShadowedName
import core.Decorators._
import core.Constants._
import core.Definitions._
@@ -363,7 +364,7 @@ object Erasure extends TypeTestsCasts{
def select(qual: Tree, sym: Symbol): Tree = {
val name = tree.typeOpt match {
- case tp: NamedType if tp.name.isShadowedName => sym.name.shadowedName
+ case tp: NamedType if tp.name.is(ShadowedName) => sym.name.derived(ShadowedName)
case _ => sym.name
}
untpd.cpy.Select(tree)(qual, sym.name)
diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala
index 7b15b7e54..f63cba3f1 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala
@@ -38,7 +38,7 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
case tpe @ SAMType(_) if isPlatformSam(tpe.classSymbol.asClass) =>
tree
case tpe =>
- val Seq(samDenot) = tpe.abstractTermMembers.filter(!_.symbol.is(SuperAccessor))
+ val Seq(samDenot) = tpe.abstractTermMembers.filter(!_.symbol.isSuperAccessor)
cpy.Block(tree)(stats,
AnonClass(tpe :: Nil, fn.symbol.asTerm :: Nil, samDenot.symbol.asTerm.name :: Nil))
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index a6e643992..7ad7fb348 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -11,6 +11,7 @@ import core.Decorators._
import core.StdNames.nme
import core.Names._
import core.NameOps._
+import core.NameKinds.OuterSelectName
import ast.Trees._
import SymUtils._
import dotty.tools.dotc.ast.tpd
@@ -61,10 +62,11 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
/** Convert a selection of the form `qual.C_<OUTER>` to an outer path from `qual` to `C` */
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
- if (tree.name.isOuterSelect)
- outer.path(start = tree.qualifier, count = tree.name.outerSelectHops)
- .ensureConforms(tree.tpe)
- else tree
+ tree.name match {
+ case OuterSelectName(_, nhops) =>
+ outer.path(start = tree.qualifier, count = nhops).ensureConforms(tree.tpe)
+ case _ => tree
+ }
/** First, add outer accessors if a class does not have them yet and it references an outer this.
* If the class has outer accessors, implement them.
@@ -215,7 +217,7 @@ object ExplicitOuter {
def outerAccessor(cls: ClassSymbol)(implicit ctx: Context): Symbol =
if (cls.isStatic) NoSymbol // fast return to avoid scanning package decls
else cls.info.member(outerAccName(cls)).suchThat(_ is OuterAccessor).symbol orElse
- cls.info.decls.find(_ is OuterAccessor).getOrElse(NoSymbol)
+ cls.info.decls.find(_ is OuterAccessor)
/** Class has an outer accessor. Can be called only after phase ExplicitOuter. */
private def hasOuter(cls: ClassSymbol)(implicit ctx: Context): Boolean =
diff --git a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
index 64474cecd..61f32edae 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
@@ -16,6 +16,7 @@ import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTrans
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
import TypeErasure.{ valueErasure, ErasedValueType }
import TypeUtils._
+import NameKinds.{ExtMethName, UniqueExtMethName}
import util.Positions._
import Decorators._
import SymUtils._
@@ -206,11 +207,11 @@ object ExtensionMethods {
val alts = decl.alternatives
val index = alts indexOf imeth.denot
assert(index >= 0, alts + " does not contain " + imeth)
- def altName(index: Int) = (imeth.name + "$extension" + index).toTermName
+ def altName(index: Int) = UniqueExtMethName(imeth.name.asTermName, index)
altName(index) #:: ((0 until alts.length).toStream filter (index != _) map altName)
case decl =>
assert(decl.exists, imeth.name + " not found in " + imeth.owner + "'s decls: " + imeth.owner.info.decls)
- Stream((imeth.name + "$extension").toTermName)
+ Stream(ExtMethName(imeth.name.asTermName))
}
}
diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
index 8328e43de..a3cf71ef2 100644
--- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
@@ -19,8 +19,8 @@ import dotty.tools.dotc.core.Denotations.SingleDenotation
import scala.collection.mutable
import DenotTransformers._
import typer.Checking
-import Names.Name
import NameOps._
+import NameKinds.{AvoidClashName, OuterSelectName}
import StdNames._
@@ -77,7 +77,7 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = {
tree match {
- case Select(qual, name) if !name.isOuterSelect && tree.symbol.exists =>
+ case Select(qual, name) if !name.is(OuterSelectName) && tree.symbol.exists =>
assert(qual.tpe derivesFrom tree.symbol.owner, i"non member selection of ${tree.symbol.showLocated} from ${qual.tpe} in $tree")
case _: TypeTree =>
case _: Import | _: NamedArg | _: TypTree =>
@@ -129,7 +129,7 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota
case _ =>
false
}
- val uniqueName = if (nameClash) objName.avoidClashName else objName
+ val uniqueName = if (nameClash) AvoidClashName(objName) else objName
Thicket(stat :: ModuleDef(registerCompanion(uniqueName, stat.symbol), Nil).trees)
case stat => stat
}
diff --git a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
index 2035fb04b..f64006d73 100644
--- a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
@@ -10,6 +10,7 @@ import Contexts._
import Symbols._
import Decorators._
import NameOps._
+import NameKinds._
import StdNames.nme
import rewrite.Rewrites.patch
import util.Positions.Position
@@ -106,7 +107,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
*/
def transformSyntheticModule(tree: ValOrDefDef)(implicit ctx: Context) = {
val sym = tree.symbol
- val holderSymbol = ctx.newSymbol(sym.owner, sym.asTerm.name.lazyLocalName,
+ val holderSymbol = ctx.newSymbol(sym.owner, LazyLocalName.fresh(sym.asTerm.name),
Flags.Synthetic, sym.info.widen.resultType).enteredAfter(this)
val field = ValDef(holderSymbol, tree.rhs.changeOwnerAfter(sym, holderSymbol, this))
val getter = DefDef(sym.asTerm, ref(holderSymbol))
@@ -119,8 +120,9 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
*/
def transformLocalDef(x: ValOrDefDef)(implicit ctx: Context) = {
val valueInitter = x.rhs
- val holderName = ctx.freshName(x.name.asTermName.lazyLocalName).toTermName
- val initName = ctx.freshName(x.name ++ StdNames.nme.LAZY_LOCAL_INIT).toTermName
+ val xname = x.name.asTermName
+ val holderName = LazyLocalName.fresh(xname)
+ val initName = LazyLocalInitName.fresh(xname)
val tpe = x.tpe.widen.resultType.widen
val holderType =
@@ -211,7 +213,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
val claz = x.symbol.owner.asClass
val tpe = x.tpe.widen.resultType.widen
assert(!(x.symbol is Flags.Mutable))
- val containerName = ctx.freshName(x.name.asTermName.lazyLocalName).toTermName
+ val containerName = LazyLocalName.fresh(x.name.asTermName)
val containerSymbol = ctx.newSymbol(claz, containerName,
x.symbol.flags &~ containerFlagsMask | containerFlags | Flags.Private,
tpe, coord = x.symbol.coord
@@ -223,7 +225,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
Thicket(containerTree, slowPath)
}
else {
- val flagName = ctx.freshName(x.name ++ StdNames.nme.BITMAP_PREFIX).toTermName
+ val flagName = LazyBitMapName.fresh(x.name.asTermName)
val flagSymbol = ctx.newSymbol(x.symbol.owner, flagName, containerFlags | Flags.Private, defn.BooleanType).enteredAfter(this)
val flag = ValDef(flagSymbol, Literal(Constants.Constant(false)))
val slowPath = DefDef(x.symbol.asTerm, mkNonThreadSafeDef(ref(containerSymbol), ref(flagSymbol), x.rhs))
@@ -376,7 +378,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
appendOffsetDefs += (claz -> new OffsetInfo(List(offsetTree), ord))
}
- val containerName = ctx.freshName(x.name.asTermName.lazyLocalName).toTermName
+ val containerName = LazyLocalName.fresh(x.name.asTermName)
val containerSymbol = ctx.newSymbol(claz, containerName, x.symbol.flags &~ containerFlagsMask | containerFlags, tpe, coord = x.symbol.coord).enteredAfter(this)
val containerTree = ValDef(containerSymbol, defaultValue(tpe))
diff --git a/compiler/src/dotty/tools/dotc/transform/LiftTry.scala b/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
index d01195614..278868131 100644
--- a/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
@@ -8,6 +8,7 @@ import core.Contexts._
import core.Types._
import core.Flags._
import core.Decorators._
+import core.NameKinds.LiftedTreeName
import NonLocalReturns._
/** Lifts try's that might be executed on non-empty expression stacks
@@ -56,7 +57,7 @@ class LiftTry extends MiniPhase with IdentityDenotTransformer { thisTransform =>
if (needLift) {
ctx.debuglog(i"lifting tree at ${tree.pos}, current owner = ${ctx.owner}")
val fn = ctx.newSymbol(
- ctx.owner, ctx.freshName("liftedTree").toTermName, Synthetic | Method,
+ ctx.owner, LiftedTreeName.fresh(), Synthetic | Method,
MethodType(Nil, tree.tpe.widenIfUnstable), coord = tree.pos)
tree.changeOwnerAfter(ctx.owner, fn, thisTransform)
Block(DefDef(fn, tree) :: Nil, ref(fn).appliedToNone)
diff --git a/compiler/src/dotty/tools/dotc/transform/Mixin.scala b/compiler/src/dotty/tools/dotc/transform/Mixin.scala
index fd4370d3e..546077d27 100644
--- a/compiler/src/dotty/tools/dotc/transform/Mixin.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Mixin.scala
@@ -13,6 +13,7 @@ import Decorators._
import DenotTransformers._
import StdNames._
import NameOps._
+import NameKinds._
import Phases._
import ast.untpd
import ast.Trees._
@@ -219,7 +220,7 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
ref(mixin.implClass).select(implClassGetter).appliedTo(This(cls))
}
- if (isCurrent(getter) || getter.is(ExpandedName)) {
+ if (isCurrent(getter) || getter.name.is(ExpandedName)) {
val rhs =
if (was(getter, ParamAccessor)) nextArgument()
else if (isScala2x)
diff --git a/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala b/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
index b0ee0930d..652320639 100644
--- a/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
+++ b/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
@@ -55,6 +55,7 @@ class MoveStatics extends MiniPhaseTransform with SymTransformer { thisTransform
}
def move(module: TypeDef, companion: TypeDef): List[Tree] = {
+ assert(companion ne module)
if (!module.symbol.is(Flags.Module)) move(companion, module)
else {
val allMembers =
diff --git a/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala b/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
index 7680e283e..fdee076b4 100644
--- a/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
+++ b/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
@@ -5,6 +5,7 @@ import core._
import Contexts._, Symbols._, Types._, Flags._, Decorators._, StdNames._, Constants._, Phases._
import TreeTransforms._
import ast.Trees._
+import NameKinds.NonLocalReturnKeyName
import collection.mutable
object NonLocalReturns {
@@ -38,7 +39,7 @@ class NonLocalReturns extends MiniPhaseTransform { thisTransformer =>
private def nonLocalReturnKey(meth: Symbol)(implicit ctx: Context) =
nonLocalReturnKeys.getOrElseUpdate(meth,
ctx.newSymbol(
- meth, ctx.freshName("nonLocalReturnKey").toTermName, Synthetic, defn.ObjectType, coord = meth.pos))
+ meth, NonLocalReturnKeyName.fresh(), Synthetic, defn.ObjectType, coord = meth.pos))
/** Generate a non-local return throw with given return expression from given method.
* I.e. for the method's non-local return key, generate:
diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
index dbc7666f7..d87412d93 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -11,6 +11,7 @@ import core.Symbols._
import core.Types._
import core.Constants._
import core.StdNames._
+import core.NameKinds._
import dotty.tools.dotc.ast.{untpd, TreeTypeMap, tpd}
import dotty.tools.dotc.core
import dotty.tools.dotc.core.DenotTransformers.DenotTransformer
@@ -70,16 +71,14 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
class OptimizingMatchTranslator extends MatchOptimizer/*(val typer: analyzer.Typer)*/ with MatchTranslator
trait CodegenCore {
- private var ctr = 0 // left for debugging
// assert(owner ne null); assert(owner ne NoSymbol)
- def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x", owner: Symbol = ctx.owner) = {
- ctr += 1
- ctx.newSymbol(owner, ctx.freshName(prefix + ctr).toTermName, Flags.Synthetic | Flags.Case, tp, coord = pos)
+ def freshSym(pos: Position, tp: Type = NoType, unique: UniqueNameKind = PatMatStdBinderName, owner: Symbol = ctx.owner) = {
+ ctx.newSymbol(owner, unique.fresh(), Flags.Synthetic | Flags.Case, tp, coord = pos)
}
- def newSynthCaseLabel(name: String, tpe: Type, owner: Symbol = ctx.owner) =
- ctx.newSymbol(owner, ctx.freshName(name).toTermName, Flags.Label | Flags.Synthetic | Flags.Method, tpe).asTerm
+ def newSynthCaseLabel(unique: UniqueNameKind, tpe: Type, owner: Symbol = ctx.owner) =
+ ctx.newSymbol(owner, unique.fresh(), Flags.Label | Flags.Synthetic | Flags.Method, tpe).asTerm
//NoSymbol.newLabel(freshName(name), NoPosition) setFlag treeInfo.SYNTH_CASE_FLAGS
// codegen relevant to the structure of the translation (how extractors are combined)
@@ -189,7 +188,8 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
//NoSymbol.newValueParameter(newTermName("x"), NoPosition, newFlags = SYNTHETIC) setInfo restpe.withoutAnnotations
- val caseSyms: List[TermSymbol] = cases.scanLeft(ctx.owner.asTerm)((curOwner, nextTree) => newSynthCaseLabel(ctx.freshName("case"), MethodType(Nil, restpe), curOwner)).tail
+ val caseSyms: List[TermSymbol] = cases.scanLeft(ctx.owner.asTerm)((curOwner, nextTree) =>
+ newSynthCaseLabel(PatMatCaseName, MethodType(Nil, restpe), curOwner)).tail
// must compute catchAll after caseLabels (side-effects nextCase)
// catchAll.isEmpty iff no synthetic default case needed (the (last) user-defined case is a default)
@@ -197,7 +197,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
val catchAllDef = matchFailGen.map { _(scrutSym) }
.getOrElse(Throw(New(defn.MatchErrorType, List(ref(scrutSym)))))
- val matchFail = newSynthCaseLabel(ctx.freshName("matchFail"), MethodType(Nil, restpe))
+ val matchFail = newSynthCaseLabel(PatMatMatchFailName, MethodType(Nil, restpe))
val catchAllDefBody = DefDef(matchFail, catchAllDef)
val nextCases = (caseSyms.tail ::: List(matchFail)).map(ref(_).ensureApplied)
@@ -249,7 +249,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
val isEmptyDenot = extractorMember(prev.tpe, nme.isEmpty)
assert(getDenot.exists && isEmptyDenot.exists, i"${prev.tpe}")
- val tmpSym = freshSym(prev.pos, prev.tpe, "o")
+ val tmpSym = freshSym(prev.pos, prev.tpe, PatMatOName)
val prevValue = ref(tmpSym).select(getDenot.symbol).ensureApplied
Block(
@@ -1056,9 +1056,9 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
}
def newBoundTree(tree: Tree, pt: Type): BoundTree = tree match {
- case SymbolBound(sym, Typed(subpat, tpe)) => BoundTree(freshSym(tree.pos, pt, prefix = "pi"), tree)
+ case SymbolBound(sym, Typed(subpat, tpe)) => BoundTree(freshSym(tree.pos, pt, PatMatPiName), tree)
case SymbolBound(sym, expr) => BoundTree(sym, expr)
- case _ => BoundTree(freshSym(tree.pos, pt, prefix = "p"), tree)
+ case _ => BoundTree(freshSym(tree.pos, pt, PatMatPName), tree)
}
final case class BoundTree(binder: Symbol, tree: Tree) {
@@ -1204,7 +1204,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
val selectorTp = sel.tpe.widen.deAnonymize/*withoutAnnotations*/
- val selectorSym = freshSym(sel.pos, selectorTp, "selector")
+ val selectorSym = freshSym(sel.pos, selectorTp, PatMatSelectorName)
val (nonSyntheticCases, defaultOverride) = cases match {
case init :+ last if isSyntheticDefaultCase(last) => (init, Some(((scrut: Symbol) => last.body)))
diff --git a/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala b/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
index d752ce8e7..7c51ba593 100644
--- a/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
@@ -43,7 +43,7 @@ class PrimitiveForwarders extends MiniPhaseTransform with IdentityDenotTransform
import ops._
def methodPrimitiveForwarders: List[Tree] =
- for (meth <- mixins.flatMap(_.info.decls.flatMap(needsPrimitiveForwarderTo)).distinct)
+ for (meth <- mixins.flatMap(_.info.decls.toList.flatMap(needsPrimitiveForwarderTo)).distinct)
yield polyDefDef(implementation(meth.asTerm), forwarder(meth))
cpy.Template(impl)(body = methodPrimitiveForwarders ::: impl.body)
diff --git a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
index 3a301167d..e7936e8d9 100644
--- a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
@@ -13,11 +13,13 @@ import Decorators._
import DenotTransformers._
import StdNames._
import NameOps._
+import NameKinds._
import ast.Trees._
import util.Positions._
import Names._
import collection.mutable
import ResolveSuper._
+import config.Config
/** This phase adds super accessors and method overrides where
* linearization differs from Java's rule for default methods in interfaces.
@@ -58,7 +60,7 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
import ops._
def superAccessors(mixin: ClassSymbol): List[Tree] =
- for (superAcc <- mixin.info.decls.filter(_ is SuperAccessor).toList)
+ for (superAcc <- mixin.info.decls.filter(_.isSuperAccessor).toList)
yield polyDefDef(implementation(superAcc.asTerm), forwarder(rebindSuper(cls, superAcc)))
def methodOverrides(mixin: ClassSymbol): List[Tree] =
@@ -72,7 +74,7 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
val meth = ddef.symbol.asTerm
- if (meth.is(SuperAccessor, butNot = Deferred)) {
+ if (meth.isSuperAccessor && !meth.is(Deferred)) {
assert(ddef.rhs.isEmpty)
val cls = meth.owner.asClass
val ops = new MixinOps(cls, thisTransform)
@@ -94,13 +96,7 @@ object ResolveSuper {
def rebindSuper(base: Symbol, acc: Symbol)(implicit ctx: Context): Symbol = {
var bcs = base.info.baseClasses.dropWhile(acc.owner != _).tail
var sym: Symbol = NoSymbol
- val unexpandedAccName =
- if (acc.is(ExpandedName)) // Cannot use unexpandedName because of #765. t2183.scala would fail if we did.
- acc.name
- .drop(acc.name.indexOfSlice(nme.EXPAND_SEPARATOR ++ nme.SUPER_PREFIX))
- .drop(nme.EXPAND_SEPARATOR.length)
- else acc.name
- val SuperAccessorName(memberName) = unexpandedAccName: Name // dotty deviation: ": Name" needed otherwise pattern type is neither a subtype nor a supertype of selector type
+ val SuperAccessorName(memberName) = acc.name.unexpandedName // dotty deviation: ": Name" needed otherwise pattern type is neither a subtype nor a supertype of selector type
ctx.debuglog(i"starting rebindsuper from $base of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName")
while (bcs.nonEmpty && sym == NoSymbol) {
val other = bcs.head.info.nonPrivateDecl(memberName)
diff --git a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
index 1a530b95c..2fea19847 100644
--- a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
@@ -11,6 +11,7 @@ import core.Decorators._
import core.StdNames.nme
import core.Names._
import core.NameOps._
+import core.NameKinds.DirectName
import ast.Trees._
import ast.tpd
import collection.mutable
@@ -91,7 +92,7 @@ class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisTr
/** A new `m$direct` method to accompany the given method `m` */
private def newDirectMethod(sym: Symbol)(implicit ctx: Context): Symbol = {
val direct = sym.copy(
- name = sym.name.directName,
+ name = DirectName(sym.name.asTermName).asInstanceOf[sym.ThisName],
flags = sym.flags | Synthetic,
info = directInfo(sym.info))
if (direct.allOverriddenSymbols.isEmpty) direct.resetFlag(Override)
@@ -103,7 +104,7 @@ class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisTr
*/
private def directMethod(sym: Symbol)(implicit ctx: Context): Symbol =
if (sym.owner.isClass) {
- val direct = sym.owner.info.member(sym.name.directName)
+ val direct = sym.owner.info.member(DirectName(sym.name.asTermName))
.suchThat(_.info matches directInfo(sym.info)).symbol
if (direct.maybeOwner == sym.owner) direct
else newDirectMethod(sym).enteredAfter(thisTransform)
@@ -121,7 +122,7 @@ class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisTr
case TypeApply(fn, args) => cpy.TypeApply(tree)(directQual(fn), args)
case Block(stats, expr) => cpy.Block(tree)(stats, directQual(expr))
case tree: RefTree =>
- cpy.Ref(tree)(tree.name.directName)
+ cpy.Ref(tree)(DirectName(tree.name.asTermName))
.withType(directMethod(tree.symbol).termRef)
}
directQual(tree.qualifier)
diff --git a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
index 728c1696b..84a32f93b 100644
--- a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -11,6 +11,7 @@ import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTrans
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
import util.Positions._
import Decorators._
+import NameKinds.{ProtectedAccessorName, ProtectedSetterName, OuterSelectName, SuperAccessorName}
import Symbols._, TypeUtils._
/** This class performs the following functions:
@@ -71,7 +72,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
val Select(qual, name) = sel
val sym = sel.symbol
val clazz = qual.symbol.asClass
- var superName = name.superName
+ var superName = SuperAccessorName(name.asTermName)
if (clazz is Trait) superName = superName.expandedName(clazz)
val superInfo = sel.tpe.widenSingleton.ensureMethodic
@@ -79,9 +80,9 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
.suchThat(_.signature == superInfo.signature).symbol
.orElse {
ctx.debuglog(s"add super acc ${sym.showLocated} to $clazz")
- val deferredOrPrivate = if (clazz is Trait) Deferred | ExpandedName else Private
+ val deferredOrPrivate = if (clazz is Trait) Deferred else Private
val acc = ctx.newSymbol(
- clazz, superName, SuperAccessor | Artifact | Method | deferredOrPrivate,
+ clazz, superName, Artifact | Method | deferredOrPrivate,
superInfo, coord = sym.coord).enteredAfter(thisTransformer)
// Diagnostic for SI-7091
if (!accDefs.contains(clazz))
@@ -151,7 +152,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
*/
private def ensureProtectedAccessOK(sel: Select, targs: List[Tree])(implicit ctx: Context) = {
val sym = sel.symbol
- if (sym.isTerm && !sel.name.isOuterSelect && needsProtectedAccessor(sym, sel.pos)) {
+ if (sym.isTerm && !sel.name.is(OuterSelectName) && needsProtectedAccessor(sym, sel.pos)) {
ctx.debuglog("Adding protected accessor for " + sel)
protectedAccessorCall(sel, targs)
} else sel
@@ -168,7 +169,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
assert(clazz.exists, sym)
ctx.debuglog("Decided for host class: " + clazz)
- val accName = sym.name.protectedAccessorName
+ val accName = ProtectedAccessorName(sym.name)
// if the result type depends on the this type of an enclosing class, the accessor
// has to take an object of exactly this type, otherwise it's more general
@@ -206,7 +207,8 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
}
def isProtectedAccessor(tree: Tree)(implicit ctx: Context): Boolean = tree match {
- case Apply(TypeApply(Select(_, name), _), qual :: Nil) => name.isProtectedAccessorName
+ case Apply(TypeApply(Select(_, name), _), qual :: Nil) =>
+ name.is(ProtectedAccessorName) || name.is(ProtectedSetterName)
case _ => false
}
@@ -221,7 +223,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
assert(clazz.exists, sym)
ctx.debuglog("Decided for host class: " + clazz)
- val accName = sym.name.protectedAccessorName
+ val accName = ProtectedAccessorName(sym.name)
// if the result type depends on the this type of an enclosing class, the accessor
// has to take an object of exactly this type, otherwise it's more general
@@ -265,7 +267,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
assert(clazz.exists, field)
ctx.debuglog("Decided for host class: " + clazz)
- val accName = field.name.protectedSetterName
+ val accName = ProtectedSetterName(field.name)
val accType = MethodType(clazz.classInfo.selfType :: field.info :: Nil, defn.UnitType)
val protectedAccessor = clazz.info.decl(accName).symbol orElse {
val newAcc = ctx.newSymbol(
diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala
index 105f54d3a..4c07ca4c8 100644
--- a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala
@@ -10,6 +10,7 @@ import Decorators._
import Names._
import StdNames._
import NameOps._
+import NameKinds._
import Flags._
import Annotations._
@@ -51,6 +52,11 @@ class SymUtils(val self: Symbol) extends AnyVal {
def isAnyOverride(implicit ctx: Context) = self.is(Override) || self.is(AbsOverride)
// careful: AbsOverride is a term only flag. combining with Override would catch only terms.
+ def isAliasPreferred(implicit ctx: Context) =
+ self.is(AliasPreferred) || self.name.is(ExpandedName)
+
+ def isSuperAccessor(implicit ctx: Context) = self.name.is(SuperAccessorName)
+
/** If this is a constructor, its owner: otherwise this. */
final def skipConstructor(implicit ctx: Context): Symbol =
if (self.isConstructor) self.owner else self
diff --git a/compiler/src/dotty/tools/dotc/transform/TailRec.scala b/compiler/src/dotty/tools/dotc/transform/TailRec.scala
index 8a695bf22..10c18e165 100644
--- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala
@@ -1,16 +1,17 @@
-package dotty.tools.dotc.transform
-
-import dotty.tools.dotc.ast.Trees._
-import dotty.tools.dotc.ast.{TreeTypeMap, tpd}
-import dotty.tools.dotc.core.Contexts.Context
-import dotty.tools.dotc.core.Decorators._
-import dotty.tools.dotc.core.DenotTransformers.DenotTransformer
-import dotty.tools.dotc.core.Denotations.SingleDenotation
-import dotty.tools.dotc.core.Symbols._
-import dotty.tools.dotc.core.Types._
-import dotty.tools.dotc.core._
-import dotty.tools.dotc.transform.TailRec._
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+package dotty.tools.dotc
+package transform
+
+import ast.Trees._
+import ast.{TreeTypeMap, tpd}
+import core._
+import Contexts.Context
+import Decorators._
+import DenotTransformers.DenotTransformer
+import Denotations.SingleDenotation
+import Symbols._
+import Types._
+import NameKinds.TailLabelName
+import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
/**
* A Tail Rec Transformer
@@ -62,6 +63,7 @@ import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, Transforme
* </p>
*/
class TailRec extends MiniPhaseTransform with DenotTransformer with FullParameterization { thisTransform =>
+ import TailRec._
import dotty.tools.dotc.ast.tpd._
@@ -70,7 +72,6 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
override def phaseName: String = "tailrec"
override def treeTransformPhase = thisTransform // TODO Make sure tailrec runs at next phase.
- final val labelPrefix = "tailLabel"
final val labelFlags = Flags.Synthetic | Flags.Label
/** Symbols of methods that have @tailrec annotatios inside */
@@ -87,12 +88,12 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
tree
}
- private def mkLabel(method: Symbol, abstractOverClass: Boolean)(implicit c: Context): TermSymbol = {
- val name = c.freshName(labelPrefix)
+ private def mkLabel(method: Symbol, abstractOverClass: Boolean)(implicit ctx: Context): TermSymbol = {
+ val name = TailLabelName.fresh()
if (method.owner.isClass)
- c.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass, abstractOverClass, liftThisType = false))
- else c.newSymbol(method, name.toTermName, labelFlags, method.info)
+ ctx.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass, abstractOverClass, liftThisType = false))
+ else ctx.newSymbol(method, name.toTermName, labelFlags, method.info)
}
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
index ebb5b605b..eb7773ef3 100644
--- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -13,6 +13,7 @@ import core.Flags._
import core.Constants._
import core.StdNames._
import core.NameOps._
+import core.NameKinds.OuterSelectName
import core.Decorators._
import core.TypeErasure.isErasedType
import core.Phases.Phase
@@ -50,10 +51,10 @@ class TreeChecker extends Phase with SymTransformer {
private val seenModuleVals = collection.mutable.HashMap[String, Symbol]()
def isValidJVMName(name: Name) =
- !name.exists(c => c == '.' || c == ';' || c =='[' || c == '/')
+ !name.toString.exists(c => c == '.' || c == ';' || c =='[' || c == '/')
def isValidJVMMethodName(name: Name) =
- !name.exists(c => c == '.' || c == ';' || c =='[' || c == '/' || c == '<' || c == '>')
+ !name.toString.exists(c => c == '.' || c == ';' || c =='[' || c == '/' || c == '<' || c == '>')
def printError(str: String)(implicit ctx: Context) = {
ctx.echo(Console.RED + "[error] " + Console.WHITE + str)
@@ -339,7 +340,7 @@ class TreeChecker extends Phase with SymTransformer {
val sym = tree.symbol
if (!tpe.isInstanceOf[WithFixedSym] &&
sym.exists && !sym.is(Private) &&
- !tree.name.isOuterSelect // outer selects have effectively fixed symbols
+ !tree.name.is(OuterSelectName) // outer selects have effectively fixed symbols
) {
val qualTpe = tree.qualifier.typeOpt
val member =
@@ -390,11 +391,11 @@ class TreeChecker extends Phase with SymTransformer {
!x.isCompanionMethod &&
!x.isValueClassConvertMethod
- val symbolsNotDefined = cls.classInfo.decls.toSet.filter(isNonMagicalMethod) -- impl.body.map(_.symbol) - constr.symbol
+ val symbolsNotDefined = cls.classInfo.decls.toList.toSet.filter(isNonMagicalMethod) -- impl.body.map(_.symbol) - constr.symbol
assert(symbolsNotDefined.isEmpty,
i" $cls tree does not define methods: ${symbolsNotDefined.toList}%, %\n" +
- i"expected: ${cls.classInfo.decls.toSet.filter(isNonMagicalMethod).toList}%, %\n" +
+ i"expected: ${cls.classInfo.decls.toList.toSet.filter(isNonMagicalMethod)}%, %\n" +
i"defined: ${impl.body.map(_.symbol)}%, %")
super.typedClassDef(cdef, cls)
@@ -403,7 +404,8 @@ class TreeChecker extends Phase with SymTransformer {
override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) =
withDefinedSyms(ddef.tparams) {
withDefinedSymss(ddef.vparamss) {
- if (!sym.isClassConstructor && !(sym.name eq Names.STATIC_CONSTRUCTOR)) assert(isValidJVMMethodName(sym.name), s"${sym.fullName} name is invalid on jvm")
+ if (!sym.isClassConstructor && !(sym.name eq Names.STATIC_CONSTRUCTOR))
+ assert(isValidJVMMethodName(sym.name), s"${sym.name.debugString} name is invalid on jvm")
ddef.vparamss.foreach(_.foreach { vparam =>
assert(vparam.symbol.is(Param),
diff --git a/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala b/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
index 9a6ecef51..44d26e7dd 100644
--- a/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
@@ -5,6 +5,7 @@ import core.Symbols._
import core.StdNames._
import ast.Trees._
import core.Types._
+import core.NameKinds.ExceptionBinderName
import dotty.tools.dotc.core.Decorators._
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Contexts.Context
@@ -83,7 +84,7 @@ class TryCatchPatterns extends MiniPhaseTransform {
implicit ctx: Context, info: TransformerInfo): Option[CaseDef] = {
if (patternMatchCases.isEmpty) None
else {
- val exName = ctx.freshName("ex").toTermName
+ val exName = ExceptionBinderName.fresh()
val fallbackSelector =
ctx.newSymbol(ctx.owner, exName, Flags.Synthetic | Flags.Case, defn.ThrowableType, coord = pos)
val sel = Ident(fallbackSelector.termRef).withPos(pos)
diff --git a/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala b/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala
index b16d05644..00d491486 100644
--- a/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala
@@ -8,6 +8,7 @@ import SymDenotations._
import Contexts._
import Flags._
import StdNames._
+import SymUtils._
/** Methods that apply to user-defined value classes */
object ValueClasses {
@@ -24,16 +25,13 @@ object ValueClasses {
d.isRealMethod &&
isDerivedValueClass(d.owner) &&
!d.isConstructor &&
- !d.is(SuperAccessor) &&
+ !d.isSuperAccessor &&
!d.is(Macro)
- /** The member that of a derived value class that unboxes it. */
+ /** The member of a derived value class that unboxes it. */
def valueClassUnbox(d: ClassDenotation)(implicit ctx: Context): Symbol =
// (info.decl(nme.unbox)).orElse(...) uncomment once we accept unbox methods
- d.classInfo.decls
- .find(d => d.isTerm && d.symbol.is(ParamAccessor))
- .map(_.symbol)
- .getOrElse(NoSymbol)
+ d.classInfo.decls.find(_.is(TermParamAccessor))
/** For a value class `d`, this returns the synthetic cast from the underlying type to
* ErasedValueType defined in the companion module. This method is added to the module
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 1fcebf4f0..2f2af9868 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -20,6 +20,7 @@ import Trees._
import config.Config
import Names._
import StdNames._
+import NameKinds.DefaultGetterName
import ProtoTypes._
import EtaExpansion._
import Inferencing._
@@ -345,7 +346,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
}
val getterPrefix =
if ((meth is Synthetic) && meth.name == nme.apply) nme.CONSTRUCTOR else meth.name
- def getterName = getterPrefix.defaultGetterName(n)
+ def getterName = DefaultGetterName(getterPrefix, n)
if (!meth.hasDefaultParams)
EmptyTree
else if (receiver.isEmpty) {
@@ -402,7 +403,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
def missingArg(n: Int): Unit = {
val pname = methodType.paramNames(n)
fail(
- if (pname contains '$') s"not enough arguments for $methString"
+ if (pname.firstPart contains '$') s"not enough arguments for $methString"
else s"missing argument for parameter $pname of $methString")
}
@@ -718,7 +719,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val lhs1 = typedExpr(lhs)
val liftedDefs = new mutable.ListBuffer[Tree]
val lhs2 = untpd.TypedSplice(liftAssigned(liftedDefs, lhs1))
- val assign = untpd.Assign(lhs2, untpd.Apply(untpd.Select(lhs2, name.init), rhss))
+ val assign = untpd.Assign(lhs2,
+ untpd.Apply(untpd.Select(lhs2, name.asSimpleName.dropRight(1)), rhss))
wrapDefs(liftedDefs, typed(assign))
}
diff --git a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
index 5aee0fd54..e5480c98d 100644
--- a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -12,6 +12,7 @@ import Symbols._
import Decorators._
import Names._
import StdNames._
+import NameKinds.UniqueName
import Trees._
import Inferencing._
import util.Positions._
@@ -21,10 +22,10 @@ object EtaExpansion {
import tpd._
- private def lift(defs: mutable.ListBuffer[Tree], expr: Tree, prefix: String = "")(implicit ctx: Context): Tree =
+ private def lift(defs: mutable.ListBuffer[Tree], expr: Tree, prefix: TermName = EmptyTermName)(implicit ctx: Context): Tree =
if (isPureExpr(expr)) expr
else {
- val name = ctx.freshName(prefix).toTermName
+ val name = UniqueName.fresh(prefix)
val liftedType = fullyDefinedType(expr.tpe.widen, "lifted expression", expr.pos)
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, liftedType, coord = positionCoord(expr.pos))
defs += ValDef(sym, expr)
@@ -48,7 +49,7 @@ object EtaExpansion {
}
/** Lift a function argument, stripping any NamedArg wrapper */
- def liftArg(defs: mutable.ListBuffer[Tree], arg: Tree, prefix: String = "")(implicit ctx: Context): Tree =
+ def liftArg(defs: mutable.ListBuffer[Tree], arg: Tree, prefix: TermName = EmptyTermName)(implicit ctx: Context): Tree =
arg match {
case arg @ NamedArg(name, arg1) => cpy.NamedArg(arg)(name, lift(defs, arg1, prefix))
case arg => lift(defs, arg, prefix)
@@ -62,7 +63,7 @@ object EtaExpansion {
case mt: MethodType =>
(args, mt.paramNames, mt.paramInfos).zipped map { (arg, name, tp) =>
if (tp.isInstanceOf[ExprType]) arg
- else liftArg(defs, arg, if (name contains '$') "" else name.toString + "$")
+ else liftArg(defs, arg, if (name.firstPart contains '$') EmptyTermName else name)
}
case _ =>
args map (liftArg(defs, _))
diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
index f6d65fbb9..38a139be1 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
@@ -13,8 +13,9 @@ import Decorators._
import Constants._
import StdNames.nme
import Contexts.Context
-import Names.{Name, TermName}
+import Names.{Name, TermName, EmptyTermName}
import NameOps._
+import NameKinds.{InlineAccessorName, OuterSelectName}
import SymDenotations.SymDenotation
import Annotations._
import transform.ExplicitOuter
@@ -49,8 +50,7 @@ object Inliner {
sym.is(AccessFlags) || sym.privateWithin.exists
/** The name of the next accessor to be generated */
- def accessorName(implicit ctx: Context) =
- ctx.freshNames.newName(inlineMethod.name.asTermName.inlineAccessorName.toString)
+ def accessorName(implicit ctx: Context) = InlineAccessorName.fresh(inlineMethod.name.asTermName)
/** A fresh accessor symbol.
*
@@ -399,9 +399,6 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
// The class that the this-proxy `selfSym` represents
def classOf(selfSym: Symbol) = selfSym.info.widen.classSymbol
- // The name of the outer selector that computes the rhs of `selfSym`
- def outerSelector(n: Int): TermName = n.toString.toTermName ++ nme.OUTER_SELECT
-
// The total nesting depth of the class represented by `selfSym`.
def outerLevel(selfSym: Symbol): Int = classOf(selfSym).ownersIterator.length
@@ -419,7 +416,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
if (!lastSelf.exists)
prefix
else
- untpd.Select(ref(lastSelf), outerSelector(lastLevel - level)).withType(selfSym.info)
+ untpd.Select(ref(lastSelf), OuterSelectName(EmptyTermName, lastLevel - level)).withType(selfSym.info)
bindingsBuf += ValDef(selfSym.asTerm, rhs)
lastSelf = selfSym
lastLevel = level
diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala
index b436b36b0..19b6dfa71 100644
--- a/compiler/src/dotty/tools/dotc/typer/Namer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala
@@ -6,6 +6,7 @@ import core._
import ast._
import Trees._, Constants._, StdNames._, Scopes._, Denotations._, Comments._
import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Flags._, Decorators._
+import NameKinds.DefaultGetterName
import ast.desugar, ast.desugar._
import ProtoTypes._
import util.Positions._
@@ -281,7 +282,7 @@ class Namer { typer: Typer =>
tree match {
case tree: TypeDef if tree.isClassDef =>
- val name = checkNoConflict(tree.name.encode).asTypeName
+ val name = checkNoConflict(tree.name.encode).toTypeName
val flags = checkFlags(tree.mods.flags &~ Implicit)
val cls = recordSym(ctx.newClassSymbol(
ctx.owner, name, flags | inSuperCall,
@@ -1012,12 +1013,8 @@ class Namer { typer: Typer =>
* the corresponding parameter where bound parameters are replaced by
* Wildcards.
*/
- def rhsProto = {
- val name = sym.asTerm.name
- val idx = name.defaultGetterIndex
- if (idx < 0) WildcardType
- else {
- val original = name.defaultGetterToMethod
+ def rhsProto = sym.asTerm.name collect {
+ case DefaultGetterName(original, idx) =>
val meth: Denotation =
if (original.isConstructorName && (sym.owner is ModuleClass))
sym.owner.companionClass.info.decl(nme.CONSTRUCTOR)
@@ -1035,8 +1032,7 @@ class Namer { typer: Typer =>
paramProto(defaultAlts.head.info.widen.paramInfoss, idx)
else
WildcardType
- }
- }
+ } getOrElse WildcardType
// println(s"final inherited for $sym: ${inherited.toString}") !!!
// println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
index ab342dc17..398a7a17e 100644
--- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -5,6 +5,7 @@ package typer
import core._
import ast._
import Contexts._, Types._, Flags._, Denotations._, Names._, StdNames._, NameOps._, Symbols._
+import NameKinds.DepParamName
import Trees._
import Constants._
import Scopes._
@@ -401,7 +402,7 @@ object ProtoTypes {
/** Create a new TypeParamRef that represents a dependent method parameter singleton */
def newDepTypeParamRef(tp: Type)(implicit ctx: Context): TypeParamRef = {
- val poly = PolyType(ctx.freshName(nme.DEP_PARAM_PREFIX).toTypeName :: Nil)(
+ val poly = PolyType(DepParamName.fresh().toTypeName :: Nil)(
pt => TypeBounds.upper(AndType(tp, defn.SingletonType)) :: Nil,
pt => defn.AnyType)
ctx.typeComparer.addToConstraint(poly, Nil)
diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
index d61f5fa68..4715873e5 100644
--- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -6,6 +6,7 @@ import core._
import config._
import Symbols._, SymDenotations._, Types._, Contexts._, Decorators._, Flags._, Names._, NameOps._
import StdNames._, Denotations._, Scopes._, Constants.Constant, SymUtils._
+import NameKinds.DefaultGetterName
import Annotations._
import util.Positions._
import scala.collection.{ mutable, immutable }
@@ -24,12 +25,8 @@ object RefChecks {
import reporting.diagnostic.Message
import reporting.diagnostic.messages._
-
- private def isDefaultGetter(name: Name): Boolean =
- name.isTermName && name.asTermName.defaultGetterIndex >= 0
-
private val defaultMethodFilter = new NameFilter {
- def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean = isDefaultGetter(name)
+ def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean = name.is(DefaultGetterName)
}
/** Only one overloaded alternative is allowed to define default arguments */
@@ -45,7 +42,9 @@ object RefChecks {
if defaultGetterClass.isClass
) {
val defaultGetterNames = defaultGetterClass.asClass.memberNames(defaultMethodFilter)
- val defaultMethodNames = defaultGetterNames map (_.asTermName.defaultGetterToMethod)
+ val defaultMethodNames = defaultGetterNames map { _ rewrite {
+ case DefaultGetterName(methName, _) => methName
+ }}
for (name <- defaultMethodNames) {
val methods = clazz.info.member(name).alternatives.map(_.symbol)
@@ -238,7 +237,7 @@ object RefChecks {
}
}
else
- isDefaultGetter(member.name) || // default getters are not checked for compatibility
+ member.name.is(DefaultGetterName) || // default getters are not checked for compatibility
memberTp.overrides(otherTp)
//Console.println(infoString(member) + " overrides " + infoString(other) + " in " + clazz);//DEBUG
@@ -298,7 +297,7 @@ object RefChecks {
} else if (other.isEffectivelyFinal) { // (1.2)
overrideError(i"cannot override final member ${other.showLocated}")
} else if (!other.is(Deferred) &&
- !isDefaultGetter(other.name) &&
+ !other.name.is(DefaultGetterName) &&
!member.isAnyOverride) {
// (*) Exclusion for default getters, fixes SI-5178. We cannot assign the Override flag to
// the default getter: one default getter might sometimes override, sometimes not. Example in comment on ticket.
@@ -405,7 +404,7 @@ object RefChecks {
def ignoreDeferred(member: SingleDenotation) =
member.isType ||
- member.symbol.is(SuperAccessor) || // not yet synthesized
+ member.symbol.isSuperAccessor || // not yet synthesized
member.symbol.is(JavaDefined) && hasJavaErasedOverriding(member.symbol)
// 2. Check that only abstract classes have deferred members
diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
index ead4ad5cb..ec6fb1770 100644
--- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -91,8 +91,8 @@ trait TypeAssigner {
else
parent
}
- val refinableDecls = info.decls.filterNot(
- sym => sym.is(TypeParamAccessor | Private) || sym.isConstructor)
+ val refinableDecls = info.decls.filter(
+ sym => !(sym.is(TypeParamAccessor | Private) || sym.isConstructor))
val fullType = (parentType /: refinableDecls)(addRefinement)
mapOver(fullType)
case TypeBounds(lo, hi) if variance > 0 =>
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index a7b8200b5..e6236d122 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -18,6 +18,7 @@ import SymDenotations._
import Annotations._
import Names._
import NameOps._
+import NameKinds._
import Flags._
import Decorators._
import ErrorReporting._
@@ -572,7 +573,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def canAssign(sym: Symbol) = // allow assignments from the primary constructor to class fields
sym.is(Mutable, butNot = Accessor) ||
ctx.owner.isPrimaryConstructor && !sym.is(Method) && sym.owner == ctx.owner.owner ||
- ctx.owner.name.isTraitSetterName || ctx.owner.isStaticConstructor
+ ctx.owner.name.is(TraitSetterName) || ctx.owner.isStaticConstructor
lhsCore.tpe match {
case ref: TermRef if canAssign(ref.symbol) =>
assignType(cpy.Assign(tree)(lhs1, typed(tree.rhs, ref.info)))
diff --git a/compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala b/compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala
index 8892a570e..5dbec3e5a 100644
--- a/compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala
+++ b/compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala
@@ -3,9 +3,12 @@ package dotc
package util
import scala.collection.mutable
+import core.Names.TermName
+import core.NameKinds.UniqueNameKind
+import core.StdNames.str
-trait FreshNameCreator {
- def newName(prefix: String = ""): String
+abstract class FreshNameCreator {
+ def newName(prefix: TermName, unique: UniqueNameKind): TermName
}
object FreshNameCreator {
@@ -18,11 +21,11 @@ object FreshNameCreator {
* that the returned name has never been returned by a previous
* call to this function (provided the prefix does not end in a digit).
*/
- def newName(prefix: String): String = {
- val safePrefix = prefix.replaceAll("""[<>]""", """\$""")
- counters(safePrefix) += 1
- val counter = counters(safePrefix)
- if (prefix.isEmpty) "$" + counter + "$" else safePrefix + counter
+ def newName(prefix: TermName, unique: UniqueNameKind): TermName = {
+ val key = str.sanitize(prefix.toString + unique.separator)
+ counters(key) += 1
+ val counter = counters(key)
+ prefix.derived(unique.NumberedInfo(counter))
}
}
}
diff --git a/compiler/src/dotty/tools/dotc/util/NameTransformer.scala b/compiler/src/dotty/tools/dotc/util/NameTransformer.scala
index 330d513fe..52f8e6ec0 100644
--- a/compiler/src/dotty/tools/dotc/util/NameTransformer.scala
+++ b/compiler/src/dotty/tools/dotc/util/NameTransformer.scala
@@ -60,7 +60,7 @@ object NameTransformer {
* @param name the string to encode
* @return the string with all recognized opchars replaced with their encoding
*/
- def encode[N <: Name](name: N): N = {
+ def encode(name: SimpleTermName): SimpleTermName = {
var buf: StringBuilder = null
val len = name.length
var i = 0
@@ -87,8 +87,7 @@ object NameTransformer {
i += 1
}
if (buf eq null) name
- else if (name.isTermName) buf.toString.toTermName.asInstanceOf[N]
- else buf.toString.toTypeName.asInstanceOf[N]
+ else termName(buf.toString)
}
/** Replace `\$opname` by corresponding operator symbol.
diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala
index 1c80767ee..af2c88e1a 100644
--- a/compiler/test/dotc/tests.scala
+++ b/compiler/test/dotc/tests.scala
@@ -203,7 +203,9 @@ class tests extends CompilerTest {
private val stdlibFiles: List[String] = StdLibSources.whitelisted
- @Test def compileStdLib = compileList("compileStdLib", stdlibFiles, "-migration" :: "-Yno-inline" :: scala2mode)
+ @Test def compileStdLib =
+ if (!generatePartestFiles)
+ compileList("compileStdLib", stdlibFiles, "-migration" :: "-Yno-inline" :: scala2mode)
@Test def compileMixed = compileLine(
"""../tests/pos/B.scala
|../scala-scala/src/library/scala/collection/immutable/Seq.scala
diff --git a/compiler/test/dotty/tools/DottyTypeStealer.scala b/compiler/test/dotty/tools/DottyTypeStealer.scala
index ff6e67e41..727cd9e7d 100644
--- a/compiler/test/dotty/tools/DottyTypeStealer.scala
+++ b/compiler/test/dotty/tools/DottyTypeStealer.scala
@@ -19,7 +19,7 @@ object DottyTypeStealer extends DottyTest {
implicit val ctx = context
val findValDef: (List[ValDef], tpd.Tree) => List[ValDef] =
(acc , tree) => { tree match {
- case t: ValDef if t.name.startsWith(dummyName.toTermName) => t :: acc
+ case t: ValDef if t.name.startsWith(dummyName) => t :: acc
case _ => acc
}
}
diff --git a/compiler/test/dotty/tools/ShowClassTests.scala b/compiler/test/dotty/tools/ShowClassTests.scala
index 4aa9e8845..66ae80169 100644
--- a/compiler/test/dotty/tools/ShowClassTests.scala
+++ b/compiler/test/dotty/tools/ShowClassTests.scala
@@ -65,7 +65,7 @@ class ShowClassTests extends DottyTest {
debug_println(s"blacklisted package: $path")
else {
for (
- sym <- pkg.info.decls if sym.owner == pkg.moduleClass && !(sym.name contains '$')
+ sym <- pkg.info.decls if sym.owner == pkg.moduleClass && !(sym.name.toString contains '$')
) {
debug_println(s"showing $sym in ${pkg.fullName}")
if (sym is PackageVal) showPackage(sym.asTerm)
diff --git a/compiler/test/dotty/tools/dotc/ParallelTesting.scala b/compiler/test/dotty/tools/dotc/ParallelTesting.scala
index 45de03b48..80c56808b 100644
--- a/compiler/test/dotty/tools/dotc/ParallelTesting.scala
+++ b/compiler/test/dotty/tools/dotc/ParallelTesting.scala
@@ -423,7 +423,8 @@ trait ParallelTesting { self =>
extends Test(testSources, times, threadLimit, suppressAllOutput) {
private def runMain(dir: JFile, testSource: TestSource): Array[String] = {
def renderStackTrace(ex: Throwable): String =
- ex.getStackTrace
+ if (ex == null) ""
+ else ex.getStackTrace
.takeWhile(_.getMethodName != "invoke0")
.mkString(" ", "\n ", "")