Skip to content

Commit de7d42c

Browse files
Ichoranretronym
authored andcommitted
Added function converter capability based on initial reflection work from Jason Zaugg.
If you have something from java.util.functions, you should be able to ``` import scala.compat.java8.FunctionConverters._ ``` and then use `.asScala` to convert to the corresponding Scala function. If you have a Scala function, use `.asJava` to convert to the best-matching item from java.util.functions. If you want a function that isn't the best match, use the corresponding `asJavaInterfaceName` method, e.g. ``` asJavaUnaryOperator((i: Int) => i+1) // Best match would be IntUnaryOperator The code is created with a code generator that needs to run in Scala 2.11+, but SBT runs 2.10 by default. Thus, build.sbtt was reworked to be multi-module (the sub-module is the code generator).
1 parent 9ef565f commit de7d42c

File tree

3 files changed

+420
-84
lines changed

3 files changed

+420
-84
lines changed

build.sbt

+107-84
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,114 @@
1-
scalaModuleSettings
2-
3-
scalaVersion := "2.11.6"
4-
5-
organization := "org.scala-lang.modules"
6-
7-
name := "scala-java8-compat"
8-
9-
version := "0.6.0-SNAPSHOT"
10-
11-
// important!! must come here (why?)
12-
scalaModuleOsgiSettings
13-
14-
OsgiKeys.exportPackage := Seq(s"scala.compat.java8.*;version=${version.value}")
15-
16-
OsgiKeys.privatePackage := List("scala.concurrent.java8.*")
17-
18-
libraryDependencies += "junit" % "junit" % "4.11" % "test"
19-
20-
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.4" % "test"
21-
22-
libraryDependencies += "com.novocode" % "junit-interface" % "0.10" % "test"
23-
24-
mimaPreviousVersion := None
25-
26-
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a")
27-
28-
sourceGenerators in Compile <+= sourceManaged in Compile map { dir =>
29-
def write(name: String, content: String) = {
30-
val f = dir / "scala" / "compat" / "java8" / s"${name}.java"
31-
IO.write(f, content)
32-
f
33-
}
34-
(
35-
Seq(write("JFunction", CodeGen.factory)) ++
36-
(0 to 22).map(n => write("JFunction" + n, CodeGen.fN(n))) ++
37-
(0 to 22).map(n => write("JProcedure" + n, CodeGen.pN(n))) ++
38-
CodeGen.specializedF0.map((write _).tupled) ++
39-
CodeGen.specializedF1.map((write _).tupled) ++
40-
CodeGen.specializedF2.map((write _).tupled)
41-
)
42-
}
43-
44-
sourceGenerators in Test <+= sourceManaged in Test map { dir =>
45-
def write(name: String, content: String) = {
46-
val f = dir / "scala" / "compat" / "java8" / s"${name}.java"
47-
IO.write(f, content)
48-
f
49-
}
50-
Seq(write("TestApi", CodeGen.testApi))
51-
}
52-
53-
initialize := {
54-
// Run previously configured inialization...
55-
initialize.value
56-
// ... and then check the Java version.
57-
val specVersion = sys.props("java.specification.version")
58-
if (Set("1.5", "1.6", "1.7") contains specVersion)
59-
sys.error("Java 8 or higher is required for this project.")
60-
}
61-
621
val disableDocs = sys.props("nodocs") == "true"
632

64-
publishArtifact in packageDoc := !disableDocs
65-
663
lazy val JavaDoc = config("genjavadoc") extend Compile
674

68-
sources in (Compile, doc) := {
69-
val orig = (sources in (Compile, doc)).value
70-
orig.filterNot(_.getName.endsWith(".java")) // raw types not cooked by scaladoc: https://issues.scala-lang.org/browse/SI-8449
5+
def jwrite(dir: java.io.File)(name: String, content: String) = {
6+
val f = dir / "scala" / "compat" / "java8" / s"${name}.java"
7+
IO.write(f, content)
8+
f
719
}
7210

73-
inConfig(JavaDoc)(Defaults.configSettings) ++ (if (disableDocs) Nil else Seq(
74-
packageDoc in Compile <<= packageDoc in JavaDoc,
75-
sources in JavaDoc <<= (target, compile in Compile, sources in Compile) map {(t, c, s) =>
76-
val allJavaSources = (t / "java" ** "*.java").get ++ s.filter(_.getName.endsWith(".java"))
77-
allJavaSources.filterNot(_.getName.contains("FuturesConvertersImpl.java")) // this file triggers bugs in genjavadoc
78-
},
79-
javacOptions in JavaDoc := Seq(),
80-
artifactName in packageDoc in JavaDoc := ((sv, mod, art) => "" + mod.name + "_" + sv.binary + "-" + mod.revision + "-javadoc.jar"),
81-
libraryDependencies += compilerPlugin("com.typesafe.genjavadoc" % "genjavadoc-plugin" % "0.8" cross CrossVersion.full),
82-
scalacOptions in Compile <+= target map (t => "-P:genjavadoc:out=" + (t / "java"))
83-
))
84-
85-
initialCommands :=
86-
"""|import scala.concurrent._
87-
|import ExecutionContext.Implicits.global
88-
|import java.util.concurrent.{CompletionStage,CompletableFuture}
89-
|import scala.compat.java8.FutureConverter._
90-
|""".stripMargin
11+
lazy val commonSettings = Seq(
12+
scalaVersion := "2.11.6",
13+
organization := "org.scala-lang.modules",
14+
version := "0.6.0-SNAPSHOT",
15+
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
16+
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
17+
)
18+
19+
lazy val fnGen = (project in file("fnGen")).
20+
settings(commonSettings: _*).
21+
settings(
22+
fork in run := true // Needed if you run this project directly
23+
)
9124

25+
lazy val root = (project in file(".")).
26+
dependsOn(fnGen).
27+
settings(scalaModuleSettings: _*).
28+
settings(commonSettings: _*).
29+
settings(
30+
name := "scala-java8-compat"
31+
).
32+
settings(
33+
// important!! must come here (why?)
34+
scalaModuleOsgiSettings: _*
35+
).
36+
settings(
37+
fork := true, // This must be set so that runner task is forked when it runs fnGen and the compiler gets a proper classpath
38+
39+
OsgiKeys.exportPackage := Seq(s"scala.compat.java8.*;version=${version.value}"),
40+
41+
OsgiKeys.privatePackage := List("scala.concurrent.java8.*"),
42+
43+
libraryDependencies += "junit" % "junit" % "4.11" % "test",
44+
45+
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.4" % "test",
46+
47+
libraryDependencies += "com.novocode" % "junit-interface" % "0.10" % "test",
48+
49+
mimaPreviousVersion := None,
50+
51+
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a"),
52+
53+
(sourceGenerators in Compile) += Def.task {
54+
val out = (sourceManaged in Compile).value
55+
if (!out.exists) IO.createDirectory(out)
56+
val canon = out.getCanonicalPath
57+
val args = (new File(canon, "FunctionConverters.scala")).toString :: Nil
58+
val runTarget = (mainClass in Compile in fnGen).value getOrElse "No main class defined for function conversion generator"
59+
val classPath = (fullClasspath in Compile in fnGen).value
60+
toError(runner.value.run(runTarget, classPath.files, args, streams.value.log))
61+
(out ** "*.scala").get
62+
}.taskValue,
63+
64+
sourceGenerators in Compile <+= sourceManaged in Compile map { dir =>
65+
val write = jwrite(dir) _
66+
Seq(write("JFunction", CodeGen.factory)) ++
67+
(0 to 22).map(n => write("JFunction" + n, CodeGen.fN(n))) ++
68+
(0 to 22).map(n => write("JProcedure" + n, CodeGen.pN(n))) ++
69+
CodeGen.specializedF0.map(write.tupled) ++
70+
CodeGen.specializedF1.map(write.tupled) ++
71+
CodeGen.specializedF2.map(write.tupled)
72+
},
73+
74+
sourceGenerators in Test <+= sourceManaged in Test map { dir =>
75+
Seq(jwrite(dir)("TestApi", CodeGen.testApi))
76+
},
77+
78+
initialize := {
79+
// Run previously configured inialization...
80+
initialize.value
81+
// ... and then check the Java version.
82+
val specVersion = sys.props("java.specification.version")
83+
if (Set("1.5", "1.6", "1.7") contains specVersion)
84+
sys.error("Java 8 or higher is required for this project.")
85+
},
86+
87+
publishArtifact in packageDoc := !disableDocs,
88+
89+
sources in (Compile, doc) := {
90+
val orig = (sources in (Compile, doc)).value
91+
orig.filterNot(_.getName.endsWith(".java")) // raw types not cooked by scaladoc: https://issues.scala-lang.org/browse/SI-8449
92+
}
93+
).
94+
settings(
95+
(inConfig(JavaDoc)(Defaults.configSettings) ++ (if (disableDocs) Nil else Seq(
96+
packageDoc in Compile <<= packageDoc in JavaDoc,
97+
sources in JavaDoc <<= (target, compile in Compile, sources in Compile) map {(t, c, s) =>
98+
val allJavaSources = (t / "java" ** "*.java").get ++ s.filter(_.getName.endsWith(".java"))
99+
allJavaSources.filterNot(_.getName.contains("FuturesConvertersImpl.java")) // this file triggers bugs in genjavadoc
100+
},
101+
javacOptions in JavaDoc := Seq(),
102+
artifactName in packageDoc in JavaDoc := ((sv, mod, art) => "" + mod.name + "_" + sv.binary + "-" + mod.revision + "-javadoc.jar"),
103+
libraryDependencies += compilerPlugin("com.typesafe.genjavadoc" % "genjavadoc-plugin" % "0.8" cross CrossVersion.full),
104+
scalacOptions in Compile <+= target map (t => "-P:genjavadoc:out=" + (t / "java"))
105+
))): _*
106+
).
107+
settings(
108+
initialCommands :=
109+
"""|import scala.concurrent._
110+
|import ExecutionContext.Implicits.global
111+
|import java.util.concurrent.{CompletionStage,CompletableFuture}
112+
|import scala.compat.java8.FutureConverter._
113+
|""".stripMargin
114+
)

0 commit comments

Comments
 (0)