Skip to content

Commit a51a2cc

Browse files
committed
Bug fixes
nameddefaults.scala now compiles without crashing
1 parent 1384750 commit a51a2cc

File tree

12 files changed

+115
-65
lines changed

12 files changed

+115
-65
lines changed

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/Denotations.scala

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ 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._
99
import StdNames._
1010
import Symbols.NoSymbol
1111
import Symbols._
@@ -1191,27 +1191,40 @@ object Denotations {
11911191
* if generateStubs is set, generates stubs for missing top-level symbols
11921192
*/
11931193
def staticRef(path: Name, generateStubs: Boolean = true)(implicit ctx: Context): Denotation = {
1194-
def recur(path: Name, len: Int): Denotation = {
1195-
val point = path.lastIndexOf('.', len - 1)
1196-
val owner =
1197-
if (point > 0) recur(path.toTermName, point).disambiguate(_.info.isParameterless)
1198-
else if (path.isTermName) defn.RootClass.denot
1199-
else defn.EmptyPackageClass.denot
1194+
def select(prefix: Denotation, selector: Name): Denotation = {
1195+
val owner = prefix.disambiguate(_.info.isParameterless)
12001196
if (owner.exists) {
1201-
val name = path slice (point + 1, len)
1202-
val result = owner.info.member(name)
1203-
if (result ne NoDenotation) result
1197+
val result = owner.info.member(selector)
1198+
if (result.exists) result
12041199
else {
12051200
val alt =
1206-
if (generateStubs) missingHook(owner.symbol.moduleClass, name)
1201+
if (generateStubs) missingHook(owner.symbol.moduleClass, selector)
12071202
else NoSymbol
1208-
if (alt.exists) alt.denot
1209-
else MissingRef(owner, name)
1203+
if (alt.exists) alt.denot else MissingRef(owner, selector)
12101204
}
12111205
}
12121206
else owner
12131207
}
1214-
recur(path, path.length)
1208+
def recur(path: Name, wrap: Name => Name = identity): Denotation = path match {
1209+
case path: TypeName =>
1210+
recur(path.toTermName, n => wrap(n.toTypeName))
1211+
case DerivedTermName(prefix, NameInfo.ModuleClass) =>
1212+
recur(prefix, n => wrap(n.derived(NameInfo.ModuleClass)))
1213+
case DerivedTermName(prefix, NameInfo.Qualified(selector, ".")) =>
1214+
select(recur(prefix), wrap(selector))
1215+
case path: SimpleTermName =>
1216+
def recurSimple(len: Int, wrap: Name => Name): Denotation = {
1217+
val point = path.lastIndexOf('.', len - 1)
1218+
val selector = wrap(path.slice(point + 1, len))
1219+
val prefix =
1220+
if (point > 0) recurSimple(point, identity)
1221+
else if (selector.isTermName) defn.RootClass.denot
1222+
else defn.EmptyPackageClass.denot
1223+
select(prefix, selector)
1224+
}
1225+
recurSimple(path.length, wrap)
1226+
}
1227+
recur(path.unmangleClassName)
12151228
}
12161229

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

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ abstract class NameInfo extends util.DotClass {
1010
def kind: NameInfo.Kind
1111
def mkString(underlying: TermName): String
1212
def map(f: SimpleTermName => SimpleTermName): NameInfo = this
13-
def contains(ch: Char): Boolean = false
13+
def satisfies(p: SimpleTermName => Boolean): Boolean = false
1414
def ++(other: String): NameInfo = unsupported("++")
1515
}
1616

@@ -34,7 +34,7 @@ object NameInfo {
3434
def kind = QualifiedKind
3535
def mkString(underlying: TermName) = s"$underlying$separator$name"
3636
override def map(f: SimpleTermName => SimpleTermName): NameInfo = Qualified(f(name), separator)
37-
override def contains(ch: Char): Boolean = name.contains(ch)
37+
override def satisfies(p: SimpleTermName => Boolean): Boolean = p(name)
3838
override def ++(other: String): NameInfo = Qualified(name ++ other, separator)
3939
override def toString = s"Qualified($name, $separator)"
4040
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ object NameOps {
7070
def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
7171
def isLoopHeaderLabel = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
7272
def isProtectedAccessorName = name startsWith PROTECTED_PREFIX
73-
def isReplWrapperName = name containsSlice INTERPRETER_IMPORT_WRAPPER
74-
def isTraitSetterName = name containsSlice TRAIT_SETTER_SEPARATOR
73+
def isReplWrapperName = name.toSimpleName containsSlice INTERPRETER_IMPORT_WRAPPER
74+
def isTraitSetterName = name.toSimpleName containsSlice TRAIT_SETTER_SEPARATOR
7575
def isSetterName = name endsWith SETTER_SUFFIX
7676
def isSingletonName = name endsWith SINGLETON_SUFFIX
7777
def isModuleClassName =
@@ -80,7 +80,7 @@ object NameOps {
8080
def isAvoidClashName = name endsWith AVOID_CLASH_SUFFIX
8181
def isImportName = name startsWith IMPORT
8282
def isFieldName = name endsWith LOCAL_SUFFIX
83-
def isShadowedName = name.length > 0 && name.head == '(' && name.startsWith(nme.SHADOWED)
83+
def isShadowedName = name.startsWith(nme.SHADOWED)
8484
def isDefaultGetterName = name.isTermName && name.asTermName.defaultGetterIndex >= 0
8585
def isScala2LocalSuffix = name.endsWith(" ")
8686
def isModuleVarName(name: Name): Boolean =
@@ -162,7 +162,7 @@ object NameOps {
162162
/** The expanded name of `name` relative to `basename` with given `separator`
163163
*/
164164
def expandedName(prefix: Name, separator: Name = nme.EXPAND_SEPARATOR): N =
165-
name.fromName(prefix ++ separator ++ name).asInstanceOf[N]
165+
name.likeKinded(prefix ++ separator ++ name).asInstanceOf[N]
166166

167167
def expandedName(prefix: Name): N = expandedName(prefix, nme.EXPAND_SEPARATOR)
168168

@@ -204,7 +204,7 @@ object NameOps {
204204
else likeTyped(ctx.freshName(name ++ NameTransformer.NAME_JOIN_STRING)))
205205

206206
def unmangleClassName: N =
207-
if (Config.semanticNames)
207+
if (Config.semanticNames && name.isSimple && name.isTypeName)
208208
if (name.endsWith(MODULE_SUFFIX))
209209
likeTyped(name.dropRight(MODULE_SUFFIX.length).moduleClassName)
210210
else name
@@ -327,7 +327,7 @@ object NameOps {
327327
val methodTags: Seq[Name] = (methodTargs zip methodTarsNames).sortBy(_._2).map(x => typeToTag(x._1))
328328
val classTags: Seq[Name] = (classTargs zip classTargsNames).sortBy(_._2).map(x => typeToTag(x._1))
329329

330-
name.fromName(name ++ nme.specializedTypeNames.prefix ++
330+
name.likeKinded(name ++ nme.specializedTypeNames.prefix ++
331331
methodTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.separator ++
332332
classTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.suffix)
333333
}

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

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,13 @@ object Names {
6262
/** This name downcasted to a term name */
6363
def asTermName: TermName
6464

65-
def toSimpleName: SimpleTermName = this.asInstanceOf[SimpleTermName]
65+
def isSimple: Boolean
66+
def asSimpleName: SimpleTermName
67+
def toSimpleName: SimpleTermName
68+
def mapSimpleCore(f: SimpleTermName => Name): ThisName
6669

6770
/** A name of the same kind as this name and with same characters as given `name` */
68-
def fromName(name: Name): ThisName
71+
def likeKinded(name: Name): ThisName
6972

7073
def derived(info: NameInfo): ThisName
7174
def without(kind: NameInfo.Kind): ThisName
@@ -84,10 +87,14 @@ object Names {
8487
def ++ (other: Name): ThisName = ++ (other.toString)
8588
def ++ (other: String): ThisName
8689

87-
def replace(from: Char, to: Char): ThisName = fromName(toSimpleName.replace(from, to))
90+
def replace(from: Char, to: Char): ThisName = likeKinded(asSimpleName.replace(from, to))
8891

92+
def isEmpty: Boolean
8993
def startsWith(str: String): Boolean
9094
def startsWith(name: Name): Boolean = startsWith(name.toString)
95+
def endsWith(str: String): Boolean
96+
def endsWith(name: Name): Boolean = endsWith(name.toString)
97+
9198

9299
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
93100
}
@@ -112,7 +119,7 @@ object Names {
112119
_typeName
113120
}
114121

115-
def fromName(name: Name): TermName = name.toTermName
122+
def likeKinded(name: Name): TermName = name.toTermName
116123

117124
def info = NameInfo.TermName
118125
def underlying: TermName = unsupported("underlying")
@@ -178,6 +185,9 @@ object Names {
178185
ownKind == kind ||
179186
!NameInfo.definesNewName(ownKind) && ownKind > kind && underlying.is(kind)
180187
}
188+
189+
override def hashCode = System.identityHashCode(this)
190+
override def equals(other: Any) = this eq other.asInstanceOf[AnyRef]
181191
}
182192

183193
class SimpleTermName(val start: Int, val length: Int, @sharable private[Names] var next: SimpleTermName) extends TermName {
@@ -193,21 +203,34 @@ object Names {
193203
i < length
194204
}
195205

206+
def isEmpty = length == 0
207+
196208
def startsWith(str: String): Boolean = {
197209
var i = 0
198210
while (i < str.length && i < length && apply(i) == str(i)) i += 1
199211
i == str.length
200212
}
201213

214+
def endsWith(str: String): Boolean = {
215+
var i = 1
216+
while (i <= str.length && i <= length && apply(length - i) == str(str.length - i)) i += 1
217+
i > str.length
218+
}
219+
202220
override def replace(from: Char, to: Char): ThisName = {
203221
val cs = new Array[Char](length)
204222
Array.copy(chrs, start, cs, 0, length)
205223
for (i <- 0 until length) {
206224
if (cs(i) == from) cs(i) = to
207225
}
208-
fromName(termName(cs, 0, length))
226+
likeKinded(termName(cs, 0, length))
209227
}
210228

229+
def isSimple = true
230+
def asSimpleName = this
231+
def toSimpleName = this
232+
def mapSimpleCore(f: SimpleTermName => Name): TermName = likeKinded(f(this))
233+
211234
def encode: SimpleTermName =
212235
if (dontEncode(toTermName)) this else NameTransformer.encode(this)
213236

@@ -225,14 +248,14 @@ object Names {
225248

226249
class TypeName(val toTermName: TermName) extends Name {
227250

228-
override def toSimpleName: SimpleTermName = toTermName.toSimpleName
229-
230251
def ++ (other: String): ThisName = toTermName.++(other).toTypeName
231252

253+
def isEmpty = toTermName.isEmpty
232254
def startsWith(str: String): Boolean = toTermName.startsWith(str)
255+
def endsWith(str: String): Boolean = toTermName.endsWith(str)
233256

234-
def encode: Name = toTermName.encode
235-
def decode: Name = toTermName.decode
257+
def encode: Name = toTermName.encode.toTypeName
258+
def decode: Name = toTermName.decode.toTypeName
236259

237260
type ThisName = TypeName
238261
def isTypeName = true
@@ -241,7 +264,12 @@ object Names {
241264
def asTypeName = this
242265
def asTermName = throw new ClassCastException(this + " is not a term name")
243266

244-
def fromName(name: Name): TypeName = name.toTypeName
267+
def isSimple = toTermName.isSimple
268+
def asSimpleName = toTermName.asSimpleName
269+
def toSimpleName = toTermName.toSimpleName
270+
def mapSimpleCore(f: SimpleTermName => Name): TypeName = toTermName.mapSimpleCore(f).toTypeName
271+
272+
def likeKinded(name: Name): TypeName = name.toTypeName
245273

246274
def derived(info: NameInfo): TypeName = toTermName.derived(info).toTypeName
247275
def without(kind: NameInfo.Kind): TypeName = toTermName.without(kind).toTypeName
@@ -254,14 +282,21 @@ object Names {
254282
/** A term name that's derived from an `underlying` name and that
255283
* adds `info` to it.
256284
*/
257-
class DerivedTermName(override val underlying: TermName, override val info: NameInfo)
285+
case class DerivedTermName(override val underlying: TermName, override val info: NameInfo)
258286
extends TermName {
259287
def ++ (other: String): ThisName = derived(info ++ other)
288+
def isEmpty = false
260289
def startsWith(str: String): Boolean = underlying.startsWith(str)
290+
def endsWith(str: String): Boolean = info.satisfies(_.endsWith(str))
261291
def encode: Name = underlying.encode.derived(info.map(_.encode))
262292
def decode: Name = underlying.decode.derived(info.map(_.decode))
263293
override def toString = info.mkString(underlying)
264294
override def debugString = s"${underlying.debugString}[$info]"
295+
296+
def isSimple = false
297+
def asSimpleName = throw new UnsupportedOperationException(s"$debugString is not a simple name")
298+
def toSimpleName = termName(toString)
299+
def mapSimpleCore(f: SimpleTermName => Name) = underlying.mapSimpleCore(f).derived(info)
265300
}
266301

267302
// Nametable
@@ -413,8 +448,8 @@ object Names {
413448
StringBuilder.newBuilder.mapResult(termName(_).toTypeName)
414449

415450
implicit class nameToSeq(val name: Name) extends IndexedSeqOptimized[Char, Name] {
416-
def length = name.toSimpleName.length
417-
def apply(n: Int) = name.toSimpleName.apply(n)
451+
def length = name.asSimpleName.length
452+
def apply(n: Int) = name.asSimpleName.apply(n)
418453
override protected[this] def newBuilder: Builder[Char, Name] =
419454
if (name.isTypeName) typeNameBuilder else termNameBuilder
420455

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

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ object SymDenotations {
387387
* A separator "" means "flat name"; the real separator in this case is "$" and
388388
* enclosing packages do not form part of the name.
389389
*/
390-
def fullNameSeparated(separator: String, semantic: Boolean)(implicit ctx: Context): Name = {
390+
def fullNameSeparated(separator: String)(implicit ctx: Context): Name = {
391391
var sep = separator
392392
var stopAtPackage = false
393393
if (sep.isEmpty) {
@@ -404,13 +404,13 @@ object SymDenotations {
404404
encl = encl.owner
405405
sep += "~"
406406
}
407-
var prefix = encl.fullNameSeparated(separator, semantic)
407+
var prefix = encl.fullNameSeparated(separator)
408408
val fn =
409-
if (semantic) {
409+
if (Config.semanticNames) {
410410
if (sep == "$")
411411
// duplicate scalac's behavior: don't write a double '$$' for module class members.
412412
prefix = prefix.without(NameInfo.ModuleClassKind)
413-
prefix.derived(NameInfo.Qualified(name.toSimpleName, sep))
413+
name.mapSimpleCore(sn => prefix.derived(NameInfo.Qualified(sn, sep)))
414414
}
415415
else {
416416
if (owner.is(ModuleClass, butNot = Package) && sep == "$")
@@ -422,15 +422,6 @@ object SymDenotations {
422422
}
423423
}
424424

425-
def fullNameSeparated(separator: String)(implicit ctx: Context): Name =
426-
if (Config.semanticNames) {
427-
val fn1 = fullNameSeparated(separator, false)
428-
val fn2 = fullNameSeparated(separator, true)
429-
assert(fn1.toString == fn2.toString, s"mismatch, was: $fn1, sem: $fn2")
430-
fn2
431-
}
432-
else fullNameSeparated(separator, false)
433-
434425
/** The encoded flat name of this denotation, where joined names are separated by `separator` characters. */
435426
def flatName(implicit ctx: Context): Name = fullNameSeparated("")
436427

compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package core
44
package tasty
55

66
import collection.mutable
7-
import Names.{Name, chrs}
7+
import Names.{Name, chrs, DerivedTermName, SimpleTermName}
88
import Decorators._, NameOps._
99
import TastyBuffer._
1010
import scala.io.Codec
@@ -24,21 +24,31 @@ class NameBuffer extends TastyBuffer(10000) {
2424
nameRefs(name) = ref
2525
ref
2626
}
27-
def nameIndex(name: Name): NameRef = {
28-
val tname =
29-
if (name.isShadowedName) Shadowed(nameIndex(name.revertShadowed))
30-
else Simple(name.toTermName.toSimpleName)
27+
28+
def nameIndex(name: Name, toTasty: SimpleTermName => TastyName): NameRef = {
29+
val tname = name.toTermName match {
30+
case DerivedTermName(name1, NameInfo.ModuleClass) =>
31+
ModuleClass(nameIndex(name1, toTasty))
32+
case DerivedTermName(prefix, NameInfo.Qualified(selector, ".")) =>
33+
Qualified(nameIndex(prefix, toTasty), nameIndex(selector))
34+
case name1 =>
35+
if (name1.isShadowedName) Shadowed(nameIndex(name1.revertShadowed, toTasty))
36+
else toTasty(name1.asSimpleName)
37+
}
3138
nameIndex(tname)
3239
}
3340

41+
def nameIndex(name: Name): NameRef = nameIndex(name, Simple)
42+
3443
def nameIndex(str: String): NameRef = nameIndex(str.toTermName)
3544

3645
def fullNameIndex(name: Name): NameRef = {
37-
val pos = name.lastIndexOf('.')
38-
if (pos > 0)
39-
nameIndex(Qualified(fullNameIndex(name.take(pos)), nameIndex(name.drop(pos + 1))))
40-
else
41-
nameIndex(name)
46+
def split(name: SimpleTermName): TastyName = {
47+
val pos = name.lastIndexOf('.')
48+
if (pos <= 0) Simple(name)
49+
else Qualified(fullNameIndex(name.take(pos)), nameIndex(name.drop(pos + 1)))
50+
}
51+
nameIndex(name, split)
4252
}
4353

4454
private def withLength(op: => Unit, lengthWidth: Int = 1): Unit = {

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ class TreePickler(pickler: TastyPickler) {
576576
}
577577

578578
def qualifiedName(sym: Symbol)(implicit ctx: Context): TastyName =
579-
if (sym.isRoot || sym.owner.isRoot) TastyName.Simple(sym.name.toTermName.toSimpleName)
579+
if (sym.isRoot || sym.owner.isRoot) TastyName.Simple(sym.name.toTermName.asSimpleName)
580580
else TastyName.Qualified(nameIndex(qualifiedName(sym.owner)), nameIndex(sym.name))
581581

582582
def pickleModifiers(sym: Symbol)(implicit ctx: Context): Unit = {

0 commit comments

Comments
 (0)