aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2015-06-25 09:39:15 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-07-13 15:31:15 +0200
commitd8985603b5d670414ea7844a628168f92a09c402 (patch)
treed024e3b6ceea68c62764faaead372a6b2af36c4a
parentc76d63da11e8456422c0bd0fd3e38cfdad049e50 (diff)
downloaddotty-d8985603b5d670414ea7844a628168f92a09c402.tar.gz
dotty-d8985603b5d670414ea7844a628168f92a09c402.tar.bz2
dotty-d8985603b5d670414ea7844a628168f92a09c402.zip
SpecializeNames: Duplicate scalac behaviour, sort tparams
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala9
-rw-r--r--src/dotty/tools/dotc/core/Names.scala23
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala3
-rw-r--r--src/dotty/tools/dotc/transform/FunctionalInterfaces.scala7
4 files changed, 37 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index 4d6cca61d..74555961e 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -236,7 +236,7 @@ object NameOps {
case nme.clone_ => nme.clone_
}
- def specializedFor(returnType: Types.Type, args: List[Types.Type])(implicit ctx: Context): name.ThisName = {
+ def specializedFor(classTargs: List[Types.Type], classTargsNames: List[Name], methodTargs: List[Types.Type], methodTarsNames: List[Name])(implicit ctx: Context): name.ThisName = {
def typeToTag(tp: Types.Type): Name = {
tp.classSymbol match {
@@ -253,9 +253,12 @@ 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 ++
- args.map(typeToTag).foldRight(typeToTag(returnType))(_ ++ _) ++
- nme.specializedTypeNames.suffix)
+ 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 */
diff --git a/src/dotty/tools/dotc/core/Names.scala b/src/dotty/tools/dotc/core/Names.scala
index 1ee56fe1c..a09487280 100644
--- a/src/dotty/tools/dotc/core/Names.scala
+++ b/src/dotty/tools/dotc/core/Names.scala
@@ -347,4 +347,27 @@ object Names {
StringBuilder.newBuilder.mapResult(s => from.fromChars(s.toCharArray, 0, s.length))
def apply(): Builder[Char, Name] = termNameBuilder
}
+
+ implicit val NameOrdering: Ordering[Name] = new Ordering[Name] {
+ def compare(x: Name, y: Name): Int = {
+ if (x.isTermName && y.isTypeName) 1
+ else if (x.isTypeName && y.isTermName) -1
+ else if (x.start == y.start && x.length == y.length) 0
+ else {
+ val until = Math.min(x.length, 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 {
+ if (x.length < y.length) 1
+ else if (x.length > y.length) -1
+ else 0 // shouldn't happen, but still
+ }
+ }
+ }
+ }
}
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index eb1a73625..577e1ebf3 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -559,7 +559,8 @@ object StdNames {
final val Void: N = "V"
final val Object: N = "L"
- final val prefix: N = "$mc"
+ final val prefix: N = "$m"
+ final val separator: N = "c"
final val suffix: N = "$sp"
}
diff --git a/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala b/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
index 03b2910ae..fe5acf3f0 100644
--- a/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
+++ b/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
@@ -63,7 +63,12 @@ class FunctionalInterfaces extends MiniPhaseTransform {
val m = tree.meth.tpe.widen.asInstanceOf[MethodType]
if (shouldSpecialize(m)) {
- val interfaceName = (functionName ++ m.paramTypes.length.toString).specializedFor(m.resultType, m.paramTypes)
+ val functionSymbol = tree.tpe.widenDealias.classSymbol
+ val names = ctx.atPhase(ctx.erasurePhase.prev) {
+ implicit ctx => functionSymbol.typeParams.map(_.name)
+ }
+ val interfaceName = (functionName ++ m.paramTypes.length.toString).specializedFor(m.paramTypes ::: m.resultType :: Nil, names, Nil, Nil)
+
// symbols loaded from classpath aren't defined in periods earlier than when they where loaded
val interface = ctx.withPhase(ctx.typerPhase).getClassIfDefined(functionPackage ++ interfaceName)
if (interface.exists) {