From 27039e2b3c87a1398e9e312ec8fd9506c19b1c15 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 23 Jan 2016 19:35:26 -0500 Subject: [PATCH 1/4] Reproduce #2411 --- .../source-dependencies/nested-case-class/A.scala | 11 +++++++++++ .../source-dependencies/nested-case-class/test | 1 + 2 files changed, 12 insertions(+) create mode 100644 sbt/src/sbt-test/source-dependencies/nested-case-class/A.scala create mode 100644 sbt/src/sbt-test/source-dependencies/nested-case-class/test diff --git a/sbt/src/sbt-test/source-dependencies/nested-case-class/A.scala b/sbt/src/sbt-test/source-dependencies/nested-case-class/A.scala new file mode 100644 index 000000000..cc6a53b6a --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/nested-case-class/A.scala @@ -0,0 +1,11 @@ +package example + +class A { + case class B(x: Int) + def c = B +} +object A { + def main(args: Array[String]): Unit = { + (new A).c + } +} diff --git a/sbt/src/sbt-test/source-dependencies/nested-case-class/test b/sbt/src/sbt-test/source-dependencies/nested-case-class/test new file mode 100644 index 000000000..62ea636c1 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/nested-case-class/test @@ -0,0 +1 @@ +> run From 49431eb6f8a990e85f24a779d552249e6194e181 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Sun, 24 Jan 2016 09:30:08 +0100 Subject: [PATCH 2/4] determine bytecode type with transformedType ... not exitingPostErasure, as this phase-travel crashes the compile (it's only really meant for going back in time, right?) --- .../interface/src/main/scala/xsbt/ExtractAPI.scala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala index 172f8f090..3810a23bd 100644 --- a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala +++ b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala @@ -225,10 +225,10 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, def build(t: Type, typeParams: Array[xsbti.api.TypeParameter], valueParameters: List[xsbti.api.ParameterList]): List[xsbti.api.Def] = { - def parameterList(syms: List[Symbol]): xsbti.api.ParameterList = + def parameterList(syms: List[Symbol], erase: Boolean = false): xsbti.api.ParameterList = { val isImplicitList = syms match { case head :: _ => isImplicit(head); case _ => false } - new xsbti.api.ParameterList(syms.map(parameterS).toArray, isImplicitList) + new xsbti.api.ParameterList(syms.map(parameterS(erase)).toArray, isImplicitList) } t match { case PolyType(typeParams0, base) => @@ -249,7 +249,7 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, build(resultType, typeParams, parameterList(params) :: valueParameters) val afterErasure = if (inspectPostErasure) - build(resultType, typeParams, global exitingPostErasure (parameterList(mType.params) :: valueParameters)) + build(resultType, typeParams, parameterList(mType.params, erase = true) :: valueParameters) else Nil @@ -277,7 +277,7 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, val beforeErasure = makeDef(processType(in, dropConst(returnType))) val afterErasure = if (inspectPostErasure) { - val erasedReturn = dropConst(global exitingPostErasure viewer(in).memberInfo(s)) map { + val erasedReturn = dropConst(transformedType(viewer(in).memberInfo(s))) map { case MethodType(_, r) => r case other => other } @@ -287,8 +287,10 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, beforeErasure :: afterErasure } } - def parameterS(s: Symbol): xsbti.api.MethodParameter = - makeParameter(simpleName(s), s.info, s.info.typeSymbol, s) + def parameterS(erase: Boolean)(s: Symbol): xsbti.api.MethodParameter = { + val tp = if (erase) transformedType(s.info) else s.info + makeParameter(simpleName(s), tp, tp.typeSymbol, s) + } // paramSym is only for 2.8 and is to determine if the parameter has a default def makeParameter(name: String, tpe: Type, ts: Symbol, paramSym: Symbol): xsbti.api.MethodParameter = From a93f1e50c8b7d8d5013bef33495b687bb1ff12a5 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Sun, 24 Jan 2016 09:42:01 +0100 Subject: [PATCH 3/4] Add second test case for sbt/sbt#2411 Thanks @smarter, see sbt/sbt#2416 --- .../nested-case-class/{A.scala => changes/A0.scala} | 0 .../nested-case-class/changes/A1.scala | 13 +++++++++++++ .../source-dependencies/nested-case-class/test | 5 +++++ 3 files changed, 18 insertions(+) rename sbt/src/sbt-test/source-dependencies/nested-case-class/{A.scala => changes/A0.scala} (100%) create mode 100644 sbt/src/sbt-test/source-dependencies/nested-case-class/changes/A1.scala diff --git a/sbt/src/sbt-test/source-dependencies/nested-case-class/A.scala b/sbt/src/sbt-test/source-dependencies/nested-case-class/changes/A0.scala similarity index 100% rename from sbt/src/sbt-test/source-dependencies/nested-case-class/A.scala rename to sbt/src/sbt-test/source-dependencies/nested-case-class/changes/A0.scala diff --git a/sbt/src/sbt-test/source-dependencies/nested-case-class/changes/A1.scala b/sbt/src/sbt-test/source-dependencies/nested-case-class/changes/A1.scala new file mode 100644 index 000000000..e71b1ef17 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/nested-case-class/changes/A1.scala @@ -0,0 +1,13 @@ +package example + +class VC(val self: Int) extends AnyVal + +class A { + case class B(x: VC) + def c = B +} +object A { + def main(args: Array[String]): Unit = { + (new A).c + } +} \ No newline at end of file diff --git a/sbt/src/sbt-test/source-dependencies/nested-case-class/test b/sbt/src/sbt-test/source-dependencies/nested-case-class/test index 62ea636c1..28ed70321 100644 --- a/sbt/src/sbt-test/source-dependencies/nested-case-class/test +++ b/sbt/src/sbt-test/source-dependencies/nested-case-class/test @@ -1 +1,6 @@ +$ copy-file changes/A0.scala A.scala +> run + +# The same test case, but involving value classes +$ copy-file changes/A1.scala A.scala > run From 1ebe86b704f7900ef9ec2eb0fcef56d3572dd73e Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Sun, 24 Jan 2016 18:54:03 +0100 Subject: [PATCH 4/4] Restore compiler bridge source for Scala < 2.10 --- compile/interface/src/main/scala/xsbt/Compat.scala | 13 ++++--------- .../interface/src/main/scala/xsbt/ExtractAPI.scala | 4 ++-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/compile/interface/src/main/scala/xsbt/Compat.scala b/compile/interface/src/main/scala/xsbt/Compat.scala index 5b8c3983b..9f9fb247c 100644 --- a/compile/interface/src/main/scala/xsbt/Compat.scala +++ b/compile/interface/src/main/scala/xsbt/Compat.scala @@ -45,15 +45,10 @@ abstract class Compat { val Nullary = global.NullaryMethodType val ScalaObjectClass = definitions.ScalaObjectClass - // `afterPostErasure` doesn't exist in Scala < 2.10 - implicit def withAfterPostErasure(global: Global): WithAfterPostErasure = new WithAfterPostErasure(global) - class WithAfterPostErasure(global: Global) { - def afterPostErasure[T](op: => T): T = op - } - // `exitingPostErasure` was called `afterPostErasure` in 2.10 - implicit def withExitingPostErasure(global: Global): WithExitingPostErasure = new WithExitingPostErasure(global) - class WithExitingPostErasure(global: Global) { - def exitingPostErasure[T](op: => T): T = global afterPostErasure op + // `transformedType` doesn't exist in Scala < 2.10 + implicit def withTransformedType(global: Global): WithTransformedType = new WithTransformedType(global) + class WithTransformedType(global: Global) { + def transformedType(tpe: Type): Type = tpe } private[this] final class MiscCompat { diff --git a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala index 3810a23bd..31389218b 100644 --- a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala +++ b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala @@ -277,7 +277,7 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, val beforeErasure = makeDef(processType(in, dropConst(returnType))) val afterErasure = if (inspectPostErasure) { - val erasedReturn = dropConst(transformedType(viewer(in).memberInfo(s))) map { + val erasedReturn = dropConst(global.transformedType(viewer(in).memberInfo(s))) map { case MethodType(_, r) => r case other => other } @@ -288,7 +288,7 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, } } def parameterS(erase: Boolean)(s: Symbol): xsbti.api.MethodParameter = { - val tp = if (erase) transformedType(s.info) else s.info + val tp = if (erase) global.transformedType(s.info) else s.info makeParameter(simpleName(s), tp, tp.typeSymbol, s) }