Skip to content

Commit 579571e

Browse files
authored
Merge pull request #2128 from dotty-staging/add-semantic-names
Delay name mangling
2 parents 4ff6561 + 87608bd commit 579571e

File tree

81 files changed

+1471
-1112
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+1471
-1112
lines changed

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ import Decorators._
3030
import tpd._
3131

3232
import scala.tools.asm
33-
import NameOps._
3433
import StdNames.nme
3534
import NameOps._
35+
import NameKinds.DefaultGetterName
3636
import dotty.tools.dotc.core
3737
import dotty.tools.dotc.core.Names.TypeName
3838

@@ -255,7 +255,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
255255
val evalue = t.symbol.name.toString // value the actual enumeration value.
256256
av.visitEnum(name, edesc, evalue)
257257
} else {
258-
assert(toDenot(t.symbol).name.toTermName.defaultGetterIndex >= 0) // this should be default getter. do not emmit.
258+
assert(toDenot(t.symbol).name.is(DefaultGetterName)) // this should be default getter. do not emmit.
259259
}
260260
case t: SeqLiteral =>
261261
val arrAnnotV: AnnotationVisitor = av.visitArray(name)
@@ -421,7 +421,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
421421
val Flag_METHOD: Flags = Flags.Method.bits
422422
val ExcludedForwarderFlags: Flags = {
423423
Flags.Specialized | Flags.Lifted | Flags.Protected | Flags.JavaStatic |
424-
Flags.ExpandedName | Flags.Bridge | Flags.VBridge | Flags.Private | Flags.Macro
424+
Flags.Bridge | Flags.VBridge | Flags.Private | Flags.Macro
425425
}.bits
426426

427427

@@ -544,8 +544,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
544544
def toTermName: Name = n.toTermName
545545
def dropModule: Name = n.stripModuleClassSuffix
546546

547-
def len: Int = n.length
548-
def offset: Int = n.start
547+
def len: Int = n.toSimpleName.length
548+
def offset: Int = n.toSimpleName.start
549549
def isTermName: Boolean = n.isTermName
550550
def startsWith(s: String): Boolean = n.startsWith(s)
551551
}
@@ -557,7 +557,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
557557
def fullName: String = sym.showFullName
558558
def simpleName: Name = sym.name
559559
def javaSimpleName: Name = toDenot(sym).name // addModuleSuffix(simpleName.dropLocal)
560-
def javaBinaryName: Name = toDenot(sym).fullNameSeparated("/") // addModuleSuffix(fullNameInternal('/'))
560+
def javaBinaryName: Name = javaClassName.replace('.', '/').toTypeName // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/'))
561561
def javaClassName: String = toDenot(sym).fullName.toString// addModuleSuffix(fullNameInternal('.')).toString
562562
def name: Name = sym.name
563563
def rawname: Name = {
@@ -794,7 +794,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
794794

795795
def memberInfo(s: Symbol): Type = tp.memberInfo(s)
796796

797-
def decls: List[Symbol] = tp.decls.map(_.symbol).toList
797+
def decls: List[Symbol] = tp.decls.toList
798798

799799
def members: List[Symbol] =
800800
tp.memberDenots(takeAllFilter, (name, buf) => buf ++= tp.member(name).alternatives).map(_.symbol).toList

compiler/src/dotty/tools/dotc/FromTasty.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Decorators._
1717
import dotty.tools.dotc.transform.Pickler
1818
import tasty.DottyUnpickler
1919
import ast.tpd._
20+
import NameKinds.QualifiedName
2021

2122
/** Compiler for TASTY files.
2223
* Usage:
@@ -74,7 +75,7 @@ object FromTasty extends Driver {
7475
case unit: TASTYCompilationUnit =>
7576
val className = unit.className.toTypeName
7677
val clsd =
77-
if (className.contains('.')) ctx.base.staticRef(className)
78+
if (className.is(QualifiedName)) ctx.base.staticRef(className)
7879
else defn.EmptyPackageClass.info.decl(className)
7980
def cannotUnpickle(reason: String) = {
8081
ctx.error(s"class $className cannot be unpickled because $reason")

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import core._
66
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
77
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
88
import Decorators._
9+
import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
910
import language.higherKinds
1011
import typer.FrontEnd
1112
import collection.mutable.ListBuffer
@@ -128,7 +129,7 @@ object desugar {
128129
def makeImplicitParameters(tpts: List[Tree], forPrimaryConstructor: Boolean)(implicit ctx: Context) =
129130
for (tpt <- tpts) yield {
130131
val paramFlags: FlagSet = if (forPrimaryConstructor) PrivateLocalParamAccessor else Param
131-
val epname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX).toTermName
132+
val epname = EvidenceParamName.fresh()
132133
ValDef(epname, tpt, EmptyTree).withFlags(paramFlags | Implicit)
133134
}
134135

@@ -186,7 +187,7 @@ object desugar {
186187
case (vparam :: vparams) :: vparamss1 =>
187188
def defaultGetter: DefDef =
188189
DefDef(
189-
name = meth.name.defaultGetterName(n),
190+
name = DefaultGetterName(meth.name, n),
190191
tparams = meth.tparams.map(tparam => dropContextBound(toDefParam(tparam))),
191192
vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam), n),
192193
tpt = TypeTree(),
@@ -230,7 +231,7 @@ object desugar {
230231
private def evidenceParams(meth: DefDef)(implicit ctx: Context): List[ValDef] =
231232
meth.vparamss.reverse match {
232233
case (vparams @ (vparam :: _)) :: _ if vparam.mods is Implicit =>
233-
vparams.dropWhile(!_.name.startsWith(nme.EVIDENCE_PARAM_PREFIX))
234+
vparams.dropWhile(!_.name.is(EvidenceParamName))
234235
case _ =>
235236
Nil
236237
}
@@ -244,7 +245,7 @@ object desugar {
244245
def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = {
245246
if (tdef.mods is PrivateLocalParam) {
246247
val tparam = cpy.TypeDef(tdef)(name = tdef.name.expandedName(ctx.owner))
247-
.withMods(tdef.mods &~ PrivateLocal | ExpandedName)
248+
.withMods(tdef.mods &~ PrivateLocal)
248249
val alias = cpy.TypeDef(tdef)(rhs = refOfDef(tparam))
249250
.withMods(tdef.mods & VarianceFlags | PrivateLocalParamAccessor | Synthetic)
250251
Thicket(tparam, alias)
@@ -402,7 +403,7 @@ object desugar {
402403

403404
def anyRef = ref(defn.AnyRefAlias.typeRef)
404405
def productConstr(n: Int) = {
405-
val tycon = scalaDot((tpnme.Product.toString + n).toTypeName)
406+
val tycon = scalaDot((str.Product + n).toTypeName)
406407
val targs = constrVparamss.head map (_.tpt)
407408
if (targs.isEmpty) tycon else AppliedTypeTree(tycon, targs)
408409
}
@@ -635,7 +636,7 @@ object desugar {
635636
case (named, tpt) :: Nil =>
636637
derivedValDef(original, named, tpt, matchExpr, mods)
637638
case _ =>
638-
val tmpName = ctx.freshName().toTermName
639+
val tmpName = UniqueName.fresh()
639640
val patMods =
640641
mods & Lazy | Synthetic | (if (ctx.owner.isClass) PrivateLocal else EmptyFlags)
641642
val firstDef =
@@ -810,7 +811,7 @@ object desugar {
810811
val selectPos = Position(left.pos.start, op.pos.end, op.pos.start)
811812
Apply(Select(left, op.name).withPos(selectPos), args)
812813
} else {
813-
val x = ctx.freshName().toTermName
814+
val x = UniqueName.fresh()
814815
val selectPos = Position(op.pos.start, right.pos.end, op.pos.start)
815816
new InfixOpBlock(
816817
ValDef(x, TypeTree(), left).withMods(synthetic),
@@ -888,7 +889,7 @@ object desugar {
888889
case id: Ident if isVarPattern(id) && id.name != nme.WILDCARD => (id, id)
889890
case Typed(id: Ident, _) if isVarPattern(id) && id.name != nme.WILDCARD => (pat, id)
890891
case _ =>
891-
val name = ctx.freshName().toTermName
892+
val name = UniqueName.fresh()
892893
(Bind(name, pat), Ident(name))
893894
}
894895

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
157157
}
158158

159159
/** Is name a left-associative operator? */
160-
def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.last != ':')
160+
def isLeftAssoc(operator: Name) = !operator.isEmpty && (operator.toSimpleName.last != ':')
161161

162162
/** can this type be a type pattern? */
163163
def mayBeTypePat(tree: untpd.Tree): Boolean = unsplice(tree) match {

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ object Trees {
316316
def namePos =
317317
if (pos.exists)
318318
if (rawMods.is(Synthetic)) Position(pos.point, pos.point)
319-
else Position(pos.point, pos.point + name.stripModuleClassSuffix.length, pos.point)
319+
else Position(pos.point, pos.point + name.stripModuleClassSuffix.lastPart.length, pos.point)
320320
else pos
321321
}
322322

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Denotations._, Decorators._, DenotTransformers._
1212
import collection.mutable
1313
import util.{Property, SourceFile, NoSource}
1414
import typer.ErrorReporting._
15+
import NameKinds.TempResultName
1516

1617
import scala.annotation.tailrec
1718
import scala.io.Codec
@@ -897,7 +898,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
897898
def evalOnce(tree: Tree)(within: Tree => Tree)(implicit ctx: Context) = {
898899
if (isIdempotentExpr(tree)) within(tree)
899900
else {
900-
val vdef = SyntheticValDef(ctx.freshName("ev$").toTermName, tree)
901+
val vdef = SyntheticValDef(TempResultName.fresh(), tree)
901902
Block(vdef :: Nil, within(Ident(vdef.namedType)))
902903
}
903904
}

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ class ScalaSettings extends Settings.SettingGroup {
6565
val YcheckMods = BooleanSetting("-Ycheck-mods", "Check that symbols and their defining trees have modifiers in sync")
6666
val debug = BooleanSetting("-Ydebug", "Increase the quantity of debugging output.")
6767
val debugAlias = BooleanSetting("-Ydebug-alias", "Never follow alias when printing types")
68-
val debugNames = BooleanSetting("-YdebugNames", "Show name-space indicators when printing names")
6968
val debugTrace = BooleanSetting("-Ydebug-trace", "Trace core operations")
7069
val debugFlags = BooleanSetting("-Ydebug-flags", "Print all flags of definitions")
70+
val debugNames = BooleanSetting("-Ydebug-names", "Show internal representation of names")
7171
val debugOwners = BooleanSetting("-Ydebug-owners", "Print all owners of definitions (requires -Yprint-syms)")
7272
val termConflict = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
7373
val log = PhasesSetting("-Ylog", "Log operations during")

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,6 @@ object Contexts {
174174
protected def freshNames_=(freshNames: FreshNameCreator) = _freshNames = freshNames
175175
def freshNames: FreshNameCreator = _freshNames
176176

177-
def freshName(prefix: String = ""): String = freshNames.newName(prefix)
178-
def freshName(prefix: Name): String = freshName(prefix.toString)
179-
180177
/** A map in which more contextual properties can be stored */
181178
private var _moreProperties: Map[Key[Any], Any] = _
182179
protected def moreProperties_=(moreProperties: Map[Key[Any], Any]) = _moreProperties = moreProperties
@@ -297,7 +294,7 @@ object Contexts {
297294

298295
/** Is this a context that introduces a non-empty scope? */
299296
def isNonEmptyScopeContext: Boolean =
300-
(this.scope ne outer.scope) && this.scope.nonEmpty
297+
(this.scope ne outer.scope) && !this.scope.isEmpty
301298

302299
/** Leave message in diagnostics buffer if it exists */
303300
def diagnose(str: => String) =

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class Definitions {
6767
enterTypeField(cls, name, flags | ClassTypeParamCreationFlags, scope)
6868

6969
private def enterSyntheticTypeParam(cls: ClassSymbol, paramFlags: FlagSet, scope: MutableScope, suffix: String = "T0") =
70-
enterTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName | paramFlags, scope)
70+
enterTypeParam(cls, suffix.toTypeName.expandedName(cls), paramFlags, scope)
7171

7272
// NOTE: Ideally we would write `parentConstrs: => Type*` but SIP-24 is only
7373
// implemented in Dotty and not in Scala 2.
@@ -108,7 +108,7 @@ class Definitions {
108108
* def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
109109
* }
110110
*/
111-
private def newFunctionNTrait(name: TypeName) = {
111+
def newFunctionNTrait(name: TypeName) = {
112112
val completer = new LazyType {
113113
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
114114
val cls = denot.asClass.classSymbol
@@ -119,7 +119,7 @@ class Definitions {
119119
enterTypeParam(cls, name ++ "$T" ++ i.toString, Contravariant, decls)
120120
val resParam = enterTypeParam(cls, name ++ "$R", Covariant, decls)
121121
val (methodType, parentTraits) =
122-
if (name.startsWith(tpnme.ImplicitFunction)) {
122+
if (name.firstPart.startsWith(str.ImplicitFunction)) {
123123
val superTrait =
124124
FunctionType(arity).appliedTo(argParams.map(_.typeRef) ::: resParam.typeRef :: Nil)
125125
(ImplicitMethodType, ctx.normalizeToClassRefs(superTrait :: Nil, cls, decls))
@@ -723,12 +723,11 @@ class Definitions {
723723
/** If type `ref` refers to a class in the scala package, its name, otherwise EmptyTypeName */
724724
def scalaClassName(ref: Type)(implicit ctx: Context): TypeName = scalaClassName(ref.classSymbol)
725725

726-
private def isVarArityClass(cls: Symbol, prefix: Name) = {
727-
val name = scalaClassName(cls)
728-
name.startsWith(prefix) &&
729-
name.length > prefix.length &&
730-
name.drop(prefix.length).forall(_.isDigit)
731-
}
726+
private def isVarArityClass(cls: Symbol, prefix: String) =
727+
scalaClassName(cls).testSimple(name =>
728+
name.startsWith(prefix) &&
729+
name.length > prefix.length &&
730+
name.drop(prefix.length).forall(_.isDigit))
732731

733732
def isBottomClass(cls: Symbol) =
734733
cls == NothingClass || cls == NullClass
@@ -758,9 +757,9 @@ class Definitions {
758757
*/
759758
def isSyntheticFunctionClass(cls: Symbol) = scalaClassName(cls).isSyntheticFunction
760759

761-
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)
762-
def isTupleClass(cls: Symbol) = isVarArityClass(cls, tpnme.Tuple)
763-
def isProductClass(cls: Symbol) = isVarArityClass(cls, tpnme.Product)
760+
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, str.AbstractFunction)
761+
def isTupleClass(cls: Symbol) = isVarArityClass(cls, str.Tuple)
762+
def isProductClass(cls: Symbol) = isVarArityClass(cls, str.Product)
764763

765764
/** Returns the erased class of the function class `cls`
766765
* - FunctionN for N > 22 becomes FunctionXXL
@@ -933,23 +932,6 @@ class Definitions {
933932

934933
// ----- Initialization ---------------------------------------------------
935934

936-
/** Give the scala package a scope where a FunctionN trait is automatically
937-
* added when someone looks for it.
938-
*/
939-
private def makeScalaSpecial()(implicit ctx: Context) = {
940-
val oldInfo = ScalaPackageClass.classInfo
941-
val oldDecls = oldInfo.decls
942-
val newDecls = new MutableScope(oldDecls) {
943-
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
944-
val res = super.lookupEntry(name)
945-
if (res == null && name.isTypeName && name.isSyntheticFunction)
946-
newScopeEntry(newFunctionNTrait(name.asTypeName))
947-
else res
948-
}
949-
}
950-
ScalaPackageClass.info = oldInfo.derivedClassInfo(decls = newDecls)
951-
}
952-
953935
/** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
954936
lazy val syntheticScalaClasses = List(
955937
AnyClass,
@@ -977,8 +959,6 @@ class Definitions {
977959
def init()(implicit ctx: Context) = {
978960
this.ctx = ctx
979961
if (!_isInitialized) {
980-
makeScalaSpecial()
981-
982962
// force initialization of every symbol that is synthesized or hijacked by the compiler
983963
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
984964

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ package core
44

55
import SymDenotations.{ SymDenotation, ClassDenotation, NoDenotation }
66
import Contexts.{Context, ContextBase}
7-
import Names.{Name, PreName}
8-
import Names.TypeName
7+
import Names._
8+
import NameOps._
9+
import NameKinds._
910
import StdNames._
1011
import Symbols.NoSymbol
1112
import Symbols._
@@ -1171,27 +1172,42 @@ object Denotations {
11711172
* if generateStubs is set, generates stubs for missing top-level symbols
11721173
*/
11731174
def staticRef(path: Name, generateStubs: Boolean = true)(implicit ctx: Context): Denotation = {
1174-
def recur(path: Name, len: Int): Denotation = {
1175-
val point = path.lastIndexOf('.', len - 1)
1176-
val owner =
1177-
if (point > 0) recur(path.toTermName, point).disambiguate(_.info.isParameterless)
1178-
else if (path.isTermName) defn.RootClass.denot
1179-
else defn.EmptyPackageClass.denot
1175+
def select(prefix: Denotation, selector: Name): Denotation = {
1176+
val owner = prefix.disambiguate(_.info.isParameterless)
11801177
if (owner.exists) {
1181-
val name = path slice (point + 1, len)
1182-
val result = owner.info.member(name)
1183-
if (result ne NoDenotation) result
1178+
val result = owner.info.member(selector)
1179+
if (result.exists) result
11841180
else {
11851181
val alt =
1186-
if (generateStubs) missingHook(owner.symbol.moduleClass, name)
1182+
if (generateStubs) missingHook(owner.symbol.moduleClass, selector)
11871183
else NoSymbol
1188-
if (alt.exists) alt.denot
1189-
else MissingRef(owner, name)
1184+
if (alt.exists) alt.denot else MissingRef(owner, selector)
11901185
}
11911186
}
11921187
else owner
11931188
}
1194-
recur(path, path.length)
1189+
def recur(path: Name, wrap: TermName => Name = identity): Denotation = path match {
1190+
case path: TypeName =>
1191+
recur(path.toTermName, n => n.toTypeName)
1192+
case ModuleClassName(underlying) =>
1193+
recur(underlying, n => wrap(ModuleClassName(n)))
1194+
case QualifiedName(prefix, selector) =>
1195+
select(recur(prefix), wrap(selector))
1196+
case qn @ AnyQualifiedName(prefix, _) =>
1197+
recur(prefix, n => wrap(qn.info.mkString(n).toTermName))
1198+
case path: SimpleTermName =>
1199+
def recurSimple(len: Int, wrap: TermName => Name): Denotation = {
1200+
val point = path.lastIndexOf('.', len - 1)
1201+
val selector = wrap(path.slice(point + 1, len).asTermName)
1202+
val prefix =
1203+
if (point > 0) recurSimple(point, identity)
1204+
else if (selector.isTermName) defn.RootClass.denot
1205+
else defn.EmptyPackageClass.denot
1206+
select(prefix, selector)
1207+
}
1208+
recurSimple(path.length, wrap)
1209+
}
1210+
recur(path)
11951211
}
11961212

11971213
/** If we are looking for a non-existing term name in a package,

0 commit comments

Comments
 (0)