Skip to content

Commit 60bed21

Browse files
committed
Merge branch 'cheeseng-feature-jason-position-macro' into 3.1.x
2 parents 91400bf + a30320b commit 60bed21

File tree

9 files changed

+153
-47
lines changed

9 files changed

+153
-47
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ Before publishing any patch release, binary compatibility with previous version
145145
$ sbt ++2.10.7 scalacticJS/package scalacticJS/mimaReportBinaryIssues
146146
$ sbt ++2.10.7 scalatestJS/package scalatestJS/mimaReportBinaryIssues
147147

148-
$ sbt ++2.12.8 scalactic/package scalactic/mimaReportBinaryIssues
149-
$ sbt ++2.12.8 scalatest/package scalatest/mimaReportBinaryIssues
150-
$ sbt ++2.12.8 scalacticJS/package scalacticJS/mimaReportBinaryIssues
151-
$ sbt ++2.12.8 scalatestJS/package scalatestJS/mimaReportBinaryIssues
148+
$ sbt ++2.12.9 scalactic/package scalactic/mimaReportBinaryIssues
149+
$ sbt ++2.12.9 scalatest/package scalatest/mimaReportBinaryIssues
150+
$ sbt ++2.12.9 scalacticJS/package scalacticJS/mimaReportBinaryIssues
151+
$ sbt ++2.12.9 scalatestJS/package scalatestJS/mimaReportBinaryIssues
152152

153153
$ sbt ++2.13.0 scalactic/package scalactic/mimaReportBinaryIssues
154154
$ sbt ++2.13.0 scalatest/package scalatest/mimaReportBinaryIssues
@@ -160,7 +160,7 @@ To publish scalactic, scalatest and scalatest-app use the following command:
160160
$ export SCALAJS_VERSION=0.6.28
161161
$ sbt ++2.10.7 clean publishSigned "project scalatestAppJS" clean publishSigned
162162
$ sbt ++2.11.12 clean publishSigned "project scalatestAppJS" clean publishSigned
163-
$ sbt ++2.12.8 "project scalatestApp" clean publishSigned "project scalatestAppJS" clean publishSigned
163+
$ sbt ++2.12.9 "project scalatestApp" clean publishSigned "project scalatestAppJS" clean publishSigned
164164
$ sbt ++2.13.0 "project scalatestApp" clean publishSigned "project scalatestAppJS" clean publishSigned
165165
$ sbt ++2.11.12 "project scalatestAppNative" clean publishSigned
166166
$ export SCALAJS_VERSION=1.0.0-M3

project/BuildCommons.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import scala.io.Source
55

66
trait BuildCommons {
77

8-
lazy val supportedScalaVersions = List("2.13.0", "2.12.8", "2.11.12", "2.10.7")
8+
lazy val supportedScalaVersions = List("2.13.0", "2.12.9", "2.11.12", "2.10.7")
99

1010
val releaseVersion = "3.1.0-M1"
1111

project/GenMacroContext.scala

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import java.io.File
2+
import java.io.BufferedWriter
3+
import java.io.FileWriter
4+
import scala.io.Source
5+
6+
object GenMacroContext {
7+
8+
private def writeFile(targetFile: File, content: String): File = {
9+
targetFile.getParentFile.mkdirs()
10+
val destWriter = new BufferedWriter(new FileWriter(targetFile))
11+
try {
12+
destWriter.write(content)
13+
targetFile
14+
}
15+
finally {
16+
destWriter.flush()
17+
destWriter.close()
18+
println("Generated " + targetFile.getAbsolutePath)
19+
}
20+
}
21+
22+
def genMain(targetDir: File, version: String, scalaVersion: String): Seq[File] = {
23+
val content =
24+
if (scalaVersion.startsWith("2.13") || scalaVersion.startsWith("2.12"))
25+
"""/*
26+
| * Copyright 2001-2019 Artima, Inc.
27+
| *
28+
| * Licensed under the Apache License, Version 2.0 (the "License");
29+
| * you may not use this file except in compliance with the License.
30+
| * You may obtain a copy of the License at
31+
| *
32+
| * http://www.apache.org/licenses/LICENSE-2.0
33+
| *
34+
| * Unless required by applicable law or agreed to in writing, software
35+
| * distributed under the License is distributed on an "AS IS" BASIS,
36+
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37+
| * See the License for the specific language governing permissions and
38+
| * limitations under the License.
39+
| */
40+
|package org.scalactic
41+
|
42+
|private[scalactic] object MacroContext {
43+
|
44+
| type Context = scala.reflect.macros.blackbox.Context
45+
|
46+
|}
47+
|
48+
""".stripMargin
49+
else
50+
"""/*
51+
| * Copyright 2001-2019 Artima, Inc.
52+
| *
53+
| * Licensed under the Apache License, Version 2.0 (the "License");
54+
| * you may not use this file except in compliance with the License.
55+
| * You may obtain a copy of the License at
56+
| *
57+
| * http://www.apache.org/licenses/LICENSE-2.0
58+
| *
59+
| * Unless required by applicable law or agreed to in writing, software
60+
| * distributed under the License is distributed on an "AS IS" BASIS,
61+
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
62+
| * See the License for the specific language governing permissions and
63+
| * limitations under the License.
64+
| */
65+
|package org.scalactic
66+
|
67+
|private[scalactic] object MacroContext {
68+
|
69+
| type Context = scala.reflect.macros.Context
70+
|
71+
|}
72+
|
73+
""".stripMargin
74+
Seq(
75+
writeFile(new File(targetDir,"MacroContext.scala"), content)
76+
)
77+
}
78+
79+
80+
}

project/GenScalacticDotty.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ object GenScalacticDotty {
121121
copyDir("scalactic-macro/src/main/scala/org/scalactic/source", "org/scalactic/source", targetDir,
122122
List(
123123
"PositionMacro.scala", // Already reimplemented in Position.scala
124-
"TypeInfoMacro.scala" // Already reimplemented
124+
"TypeInfoMacro.scala", // Already reimplemented
125+
"Position.scala" // Already exists for scalactic-dotty
125126
)
126127
)
127128

project/JsBuild.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ trait JsBuild { this: BuildCommons =>
3535
ScalacticGenResourcesJSVM.genResources((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
3636
GenAnyVals.genMain((sourceManaged in Compile).value / "org" / "scalactic" / "anyvals", version.value, scalaVersion.value, false) ++
3737
GenEvery.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
38-
GenColCompatHelper.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value)
38+
GenColCompatHelper.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
39+
GenMacroContext.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value)
3940
}.taskValue
4041
},
4142
// Disable publishing macros directly, included in scalactic main jar

project/NativeBuild.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ trait NativeBuild { this: BuildCommons =>
3535
sourceGenerators in Compile += {
3636
Def.task{
3737
GenScalacticNative.genMacroScala((sourceManaged in Compile).value / "scala", version.value, scalaVersion.value) ++
38-
ScalacticGenResourcesJSVM.genResources((sourceManaged in Compile).value / "scala" / "org" / "scalactic", version.value, scalaVersion.value) ++
39-
GenAnyVals.genMain((sourceManaged in Compile).value / "scala" / "org" / "scalactic" / "anyvals", version.value, scalaVersion.value, false) ++
40-
GenEvery.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
41-
GenColCompatHelper.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value)
38+
ScalacticGenResourcesJSVM.genResources((sourceManaged in Compile).value / "scala" / "org" / "scalactic", version.value, scalaVersion.value) ++
39+
GenAnyVals.genMain((sourceManaged in Compile).value / "scala" / "org" / "scalactic" / "anyvals", version.value, scalaVersion.value, false) ++
40+
GenEvery.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
41+
GenColCompatHelper.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
42+
GenMacroContext.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value)
4243
}.taskValue
4344
},
4445
// Disable publishing macros directly, included in scalactic main jar

project/scalatest.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ object ScalatestBuild extends BuildCommons with DottyBuild with NativeBuild with
268268
ScalacticGenResourcesJVM.genResources((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
269269
GenAnyVals.genMain((sourceManaged in Compile).value / "org" / "scalactic" / "anyvals", version.value, scalaVersion.value, false) ++
270270
GenEvery.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
271-
GenColCompatHelper.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value)
271+
GenColCompatHelper.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value) ++
272+
GenMacroContext.genMain((sourceManaged in Compile).value / "org" / "scalactic", version.value, scalaVersion.value)
272273
}.taskValue
273274
},
274275
// Disable publishing macros directly, included in scalactic main jar
File renamed without changes.
Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2001-2016 Artima, Inc.
2+
* Copyright 2001-2019 Artima, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,51 +15,73 @@
1515
*/
1616
package org.scalactic.source
1717

18+
import org.scalactic.MacroContext.Context
1819
import org.scalactic.Resources
1920

20-
import scala.reflect.macros.Context
21-
2221
/**
2322
* Helper class for Position macro. (Will be removed from the public API if possible in a subsequent 3.0.0-RCx release.)
2423
*/
25-
object PositionMacro {
24+
object PositionMacro {
25+
private object sourceCompatHack {
26+
object internal { object decorators {} }
27+
}
28+
import sourceCompatHack._
2629

2730
private[scalactic] lazy val showScalacticFillFilePathnames: Boolean = {
2831
val value = System.getenv("SCALACTIC_FILL_FILE_PATHNAMES")
2932
value != null && value == "yes"
3033
}
3134

32-
/**
33-
* Helper method for Position macro.
34-
*/
35-
def genPosition(context: Context) = {
36-
import context.universe._
35+
private class PositionMacroImpl(val universe: scala.reflect.api.Universe) {
36+
37+
private val PositionModule = universe.rootMirror.staticModule("org.scalactic.source.Position")
38+
private val PositionClass = universe.rootMirror.staticClass("org.scalactic.source.Position")
39+
private val Position_apply = PositionModule.typeSignature.declaration(universe.newTermName("apply"))
40+
41+
def apply(context: Context): context.Tree = {
42+
import context.universe._
43+
44+
// On 2.10, this imports the empty object defined above
45+
// On 2.11+, this imports `Tree.setType` extension method
46+
import internal.decorators._
3747

38-
context.Expr(
39-
Apply(
40-
Select(
41-
Select(
42-
Select(
43-
Select(
44-
Select(
45-
Ident(newTermName("_root_")),
46-
newTermName("org")
47-
),
48-
newTermName("scalactic")
49-
),
50-
newTermName("source")
51-
),
52-
newTermName("Position")
53-
),
54-
newTermName("apply")
55-
),
56-
List(
57-
Literal(Constant(context.enclosingPosition.source.file.name)),
58-
Literal(if (showScalacticFillFilePathnames) Constant(context.enclosingPosition.source.path) else Constant(Resources.pleaseDefineScalacticFillFilePathnameEnvVar)),
59-
Literal(Constant(context.enclosingPosition.line))
60-
)
48+
// Our types don't capture the fact that context.universe eq this.universe, so we have to cast.
49+
implicit def castSymbol(s: universe.Symbol): context.universe.Symbol = s.asInstanceOf[context.universe.Symbol]
50+
implicit def castType(t: universe.Type): context.universe.Type = t.asInstanceOf[context.universe.Type]
51+
52+
import treeBuild.{mkAttributedIdent, mkAttributedSelect}
53+
54+
// Because this macro is called so frequently, we assign types as we build them, rather
55+
// than returning an untyped tree and letting the typechecker fill in the types.
56+
// (`setType` and `mkAttributedXxx` assign Tree.tpe.)
57+
def strLit(s: String) = {
58+
Literal(Constant(s)).setType(definitions.StringClass.toTypeConstructor)
59+
}
60+
def intLit(i: Int) = {
61+
Literal(Constant(i)).setType(definitions.IntTpe)
62+
}
63+
val args = List(
64+
strLit(context.enclosingPosition.source.file.name),
65+
if (showScalacticFillFilePathnames) strLit(context.enclosingPosition.source.path) else strLit(Resources.pleaseDefineScalacticFillFilePathnameEnvVar),
66+
intLit(context.enclosingPosition.line)
6167
)
62-
)
68+
69+
Apply(mkAttributedSelect(mkAttributedIdent(PositionModule), Position_apply), args).setType(PositionClass.toTypeConstructor)
70+
}
6371
}
6472

65-
}
73+
// Cache to avoid needing to lookup of PositionModule/PositionClass/Position_apply each macro expansion.
74+
private var cache = new java.lang.ref.WeakReference[PositionMacroImpl](null)
75+
76+
/**
77+
* Helper method for Position macro.
78+
*/
79+
def genPosition(context: Context): context.Expr[Position] = {
80+
var impl = cache.get()
81+
if (impl == null || impl.universe != context.universe) {
82+
impl = new PositionMacroImpl(context.universe)
83+
cache = new java.lang.ref.WeakReference[PositionMacroImpl](impl)
84+
}
85+
context.Expr[Position](impl.apply(context))
86+
}
87+
}

0 commit comments

Comments
 (0)