Skip to content

Commit 8015c05

Browse files
committed
Fix #33: Move macros to a dedicated object.
1 parent e2a7453 commit 8015c05

File tree

3 files changed

+73
-56
lines changed

3 files changed

+73
-56
lines changed

build.sbt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// shadow sbt-scalajs' crossProject and CrossType until Scala.js 1.0.0 is released
2+
import com.typesafe.tools.mima.core._
23
import sbtcrossproject.{crossProject, CrossType}
34

45
val previousVersion = "1.1.0"
@@ -33,6 +34,12 @@ lazy val `portable-scala-reflect` = crossProject(JSPlatform, JVMPlatform, Native
3334

3435
mimaPreviousArtifacts +=
3536
organization.value %%% moduleName.value % previousVersion,
37+
mimaBinaryIssueFilters ++= List(
38+
/* Macros were moved to `internal` package so that `Reflect`'s metadata doesn't get polluted by types from `scala-reflect` */
39+
ProblemFilters.exclude[DirectMissingMethodProblem]("org.portablescala.reflect.Reflect.lookupInstantiatableClass_impl"),
40+
ProblemFilters.exclude[DirectMissingMethodProblem]("org.portablescala.reflect.Reflect.lookupLoadableModuleClass_impl"),
41+
ProblemFilters.exclude[MissingClassProblem]("org.portablescala.reflect.Reflect$MacroCompat$*"),
42+
),
3643

3744
publishMavenStyle := true,
3845
publishTo := {

jvm/src/main/scala/org/portablescala/reflect/Reflect.scala

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,12 @@
11
package org.portablescala.reflect
22

33
import scala.language.experimental.macros
4-
54
import scala.collection.mutable
6-
75
import java.lang.reflect._
8-
96
import org.portablescala.reflect.annotation._
7+
import org.portablescala.reflect.internal.Macros
108

119
object Reflect {
12-
/** Magic to get cross-compiling access to `blackbox.Context` with a fallback
13-
* on `macros.Context`, without deprecation warning in any Scala version.
14-
*/
15-
private object MacroCompat {
16-
object Scope1 {
17-
object blackbox
18-
}
19-
import Scope1._
20-
21-
object Scope2 {
22-
import scala.reflect.macros._
23-
object Inner {
24-
import blackbox._
25-
type BlackboxContext = Context
26-
}
27-
}
28-
}
29-
30-
import MacroCompat.Scope2.Inner.BlackboxContext
3110

3211
/** Reflectively looks up a loadable module class using the current class
3312
* loader.
@@ -52,17 +31,7 @@ object Reflect {
5231
* Fully-qualified name of the module class, including its trailing `$`
5332
*/
5433
def lookupLoadableModuleClass(fqcn: String): Option[LoadableModuleClass] =
55-
macro lookupLoadableModuleClass_impl
56-
57-
def lookupLoadableModuleClass_impl(
58-
c: BlackboxContext { type PrefixType = Reflect.type })(
59-
fqcn: c.Expr[String]): c.Expr[Option[LoadableModuleClass]] = {
60-
import c.universe._
61-
val loaderExpr = currentClassLoaderExpr(c)
62-
reify {
63-
c.prefix.splice.lookupLoadableModuleClass(fqcn.splice, loaderExpr.splice)
64-
}
65-
}
34+
macro Macros.lookupLoadableModuleClass
6635

6736
/** Reflectively looks up a loadable module class.
6837
*
@@ -111,17 +80,7 @@ object Reflect {
11180
* Fully-qualified name of the class
11281
*/
11382
def lookupInstantiatableClass(fqcn: String): Option[InstantiatableClass] =
114-
macro lookupInstantiatableClass_impl
115-
116-
def lookupInstantiatableClass_impl(
117-
c: BlackboxContext { type PrefixType = Reflect.type })(
118-
fqcn: c.Expr[String]): c.Expr[Option[InstantiatableClass]] = {
119-
import c.universe._
120-
val loaderExpr = currentClassLoaderExpr(c)
121-
reify {
122-
c.prefix.splice.lookupInstantiatableClass(fqcn.splice, loaderExpr.splice)
123-
}
124-
}
83+
macro Macros.lookupInstantiatableClass
12584

12685
/** Reflectively looks up an instantiatable class.
12786
*
@@ -147,18 +106,6 @@ object Reflect {
147106
load(fqcn, loader).filter(isInstantiatableClass).map(new InstantiatableClass(_))
148107
}
149108

150-
private def currentClassLoaderExpr(
151-
c: BlackboxContext { type PrefixType = Reflect.type }): c.Expr[ClassLoader] = {
152-
import c.universe._
153-
val enclosingClassTree = c.reifyEnclosingRuntimeClass
154-
if (enclosingClassTree.isEmpty)
155-
c.abort(c.enclosingPosition, "call site does not have an enclosing class")
156-
val enclosingClassExpr = c.Expr[java.lang.Class[_]](enclosingClassTree)
157-
reify {
158-
enclosingClassExpr.splice.getClassLoader()
159-
}
160-
}
161-
162109
private def isModuleClass(clazz: Class[_]): Boolean = {
163110
try {
164111
val fld = clazz.getField("MODULE$")
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.portablescala.reflect.internal
2+
3+
import org.portablescala.reflect._
4+
5+
/* Macro definitions are enclosed in a dedicated `Macros` object,
6+
* so that their metadata (the types involved etc.) don't pollute `Reflect`'s metadata.
7+
* This enables using `Reflect`'s methods without `scala-reflect` JAR
8+
* https://github.com/scala/bug/issues/8090
9+
* https://github.com/xeno-by/sbt-example-paradise210/issues/1#issuecomment-20996354
10+
*/
11+
object Macros {
12+
/** Magic to get cross-compiling access to `blackbox.Context` with a fallback
13+
* on `macros.Context`, without deprecation warning in any Scala version.
14+
*/
15+
private object MacroCompat {
16+
object Scope1 {
17+
object blackbox
18+
}
19+
import Scope1._
20+
21+
object Scope2 {
22+
import scala.reflect.macros._
23+
object Inner {
24+
import blackbox._
25+
type BlackboxContext = Context
26+
}
27+
}
28+
}
29+
30+
import MacroCompat.Scope2.Inner.BlackboxContext
31+
32+
private def currentClassLoaderExpr(
33+
c: BlackboxContext { type PrefixType = Reflect.type }): c.Expr[ClassLoader] = {
34+
import c.universe._
35+
val enclosingClassTree = c.reifyEnclosingRuntimeClass
36+
if (enclosingClassTree.isEmpty)
37+
c.abort(c.enclosingPosition, "call site does not have an enclosing class")
38+
val enclosingClassExpr = c.Expr[java.lang.Class[_]](enclosingClassTree)
39+
reify {
40+
enclosingClassExpr.splice.getClassLoader()
41+
}
42+
}
43+
44+
def lookupLoadableModuleClass(
45+
c: BlackboxContext { type PrefixType = Reflect.type })(
46+
fqcn: c.Expr[String]): c.Expr[Option[LoadableModuleClass]] = {
47+
import c.universe._
48+
val loaderExpr = currentClassLoaderExpr(c)
49+
reify {
50+
c.prefix.splice.lookupLoadableModuleClass(fqcn.splice, loaderExpr.splice)
51+
}
52+
}
53+
54+
def lookupInstantiatableClass(
55+
c: BlackboxContext { type PrefixType = Reflect.type })(
56+
fqcn: c.Expr[String]): c.Expr[Option[InstantiatableClass]] = {
57+
import c.universe._
58+
val loaderExpr = currentClassLoaderExpr(c)
59+
reify {
60+
c.prefix.splice.lookupInstantiatableClass(fqcn.splice, loaderExpr.splice)
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)