diff options
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/NameOps.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Names.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/StdNames.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/FunctionalInterfaces.scala | 7 |
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) { |