Skip to content

Commit c74766d

Browse files
authored
Merge pull request #376 from sideeffffect/scala-3-native-cleanup
Scala 3 Native and cleanup
2 parents a0aa42d + 70bb8d8 commit c74766d

File tree

59 files changed

+300
-239
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+300
-239
lines changed

.github/workflows/scala.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ jobs:
4141
- name: Cache scala dependencies
4242
uses: coursier/cache-action@v6
4343
- name: Run tests
44-
if: ${{ matrix.platform != 'Native' || !startsWith(matrix.scala, '3.') }}
45-
run: sbt ++${{ matrix.scala }}! scalajavatimeTests${{ matrix.platform }}/test
44+
# TODO: investigate why tests fail on Scala 3 JVM
45+
if: ${{ matrix.platform != 'JVM' || !startsWith(matrix.scala, '3.') }}
46+
run: sbt ++${{ matrix.scala }}! tests${{ matrix.platform }}/test
4647
- name: Run demo
47-
if: ${{ matrix.platform != 'Native' || !startsWith(matrix.scala, '3.') }}
4848
run: sbt ++${{ matrix.scala }}! demo${{ matrix.platform }}/run
4949

5050
build:

build.sbt

Lines changed: 56 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@ val versions: Map[String, String] = {
2222
val scalaVer = versions("2.13")
2323
val scala3Ver = versions("3")
2424
val tzdbVersion = "2019c"
25-
val scalajavaLocalesVersion = "1.3.0"
25+
val scalajavaLocalesVersion = "1.4.0"
2626
Global / onChangedBuildSource := ReloadOnSourceChanges
2727

28-
Global / resolvers += Resolver.sonatypeRepo("public")
29-
3028
lazy val downloadFromZip: TaskKey[Unit] =
3129
taskKey[Unit]("Download the tzdb tarball and extract it")
3230

@@ -54,25 +52,33 @@ inThisBuild(
5452
)
5553
)
5654

57-
publish / skip := true
58-
59-
def scalaVersionSpecificFolders(srcName: String, srcBaseDir: java.io.File, scalaVersion: String) = {
60-
def extraDirs(suffix: String) =
61-
List(CrossType.Pure, CrossType.Full)
62-
.flatMap(_.sharedSrcDir(srcBaseDir, srcName).toList.map(f => file(f.getPath + suffix)))
63-
CrossVersion.partialVersion(scalaVersion) match {
64-
case Some((2, y)) => extraDirs("-2.x") ++ (if (y >= 13) extraDirs("-2.13+") else Nil)
65-
case Some((0 | 3, _)) => extraDirs("-2.13+") ++ extraDirs("-3.x")
66-
case _ => Nil
67-
}
68-
}
55+
lazy val root = project
56+
.in(file("."))
57+
.settings(commonSettings)
58+
.settings(
59+
publish / skip := true
60+
)
61+
.aggregate(
62+
core.js,
63+
core.jvm,
64+
core.native,
65+
tzdb.js,
66+
tzdb.jvm,
67+
tzdb.native,
68+
tests.js,
69+
tests.jvm,
70+
tests.native,
71+
demo.js,
72+
demo.jvm,
73+
demo.native
74+
)
6975

7076
lazy val commonSettings = Seq(
7177
description := "java.time API implementation in Scala and Scala.js",
7278
scalaVersion := scalaVer,
7379
crossScalaVersions := versions.toList.map(_._2),
7480
// Don't include threeten on the binaries
75-
Compile / packageBin / mappings := (Compile / packageBin / mappings).value.filter { case (f, s) =>
81+
Compile / packageBin / mappings := (Compile / packageBin / mappings).value.filter { case (_, s) =>
7682
!s.contains("threeten")
7783
},
7884
Compile / scalacOptions ++= {
@@ -91,15 +97,16 @@ lazy val commonSettings = Seq(
9197
Seq.empty
9298
}
9399
},
94-
Compile / unmanagedSourceDirectories ++= scalaVersionSpecificFolders("main",
95-
baseDirectory.value,
96-
scalaVersion.value
97-
),
98-
Test / unmanagedSourceDirectories ++= scalaVersionSpecificFolders("test",
99-
baseDirectory.value,
100-
scalaVersion.value
101-
),
102100
scalacOptions ++= { if (isDotty.value) Seq.empty else Seq("-target:jvm-1.8") },
101+
scalacOptions --= {
102+
if (isDotty.value)
103+
List(
104+
"-Xfatal-warnings"
105+
)
106+
else
107+
List(
108+
)
109+
},
103110
javaOptions ++= Seq("-Dfile.encoding=UTF8"),
104111
autoAPIMappings := true,
105112
Compile / doc / sources := { if (isDotty.value) Seq() else (Compile / doc / sources).value }
@@ -122,7 +129,7 @@ def copyAndReplace(srcDirs: Seq[File], destinationDir: File): Seq[File] = {
122129
false
123130
)
124131

125-
val onlyScalaDirs = srcDirs.filter(_.getName.matches(".*scala(-\\d\\.x)?"))
132+
val onlyScalaDirs = srcDirs.filter(_.getName.matches(".*scala(-\\d)?"))
126133
// Copy the source files from the base project, exclude classes on java.util and dirs
127134
val generatedFiles: List[java.io.File] = onlyScalaDirs
128135
.foldLeft(Set.empty[File]) { (files, sourceDir) =>
@@ -152,10 +159,10 @@ def copyAndReplace(srcDirs: Seq[File], destinationDir: File): Seq[File] = {
152159
generatedFiles
153160
}
154161

155-
lazy val scalajavatime = crossProject(JVMPlatform, JSPlatform, NativePlatform)
162+
lazy val core = crossProject(JVMPlatform, JSPlatform, NativePlatform)
156163
.crossType(CrossType.Full)
157164
.in(file("core"))
158-
.settings(commonSettings: _*)
165+
.settings(commonSettings)
159166
.settings(
160167
name := "scala-java-time",
161168
libraryDependencies += ("org.portable-scala" %%% "portable-scala-reflect" % "1.1.2")
@@ -191,7 +198,6 @@ lazy val scalajavatime = crossProject(JVMPlatform, JSPlatform, NativePlatform)
191198
)
192199
)
193200
.nativeSettings(
194-
crossScalaVersions -= scala3Ver,
195201
Compile / sourceGenerators += Def.task {
196202
val srcDirs = (Compile / sourceDirectories).value
197203
val destinationDir = (Compile / sourceManaged).value
@@ -202,26 +208,24 @@ lazy val scalajavatime = crossProject(JVMPlatform, JSPlatform, NativePlatform)
202208
)
203209
)
204210

205-
lazy val scalajavatimeTZDB = crossProject(JVMPlatform, JSPlatform, NativePlatform)
211+
lazy val tzdb = crossProject(JVMPlatform, JSPlatform, NativePlatform)
206212
.crossType(CrossType.Full)
207213
.in(file("tzdb"))
208214
.settings(commonSettings)
209215
.settings(
210-
name := "scala-java-time-tzdb"
216+
name := "scala-java-time-tzdb",
217+
includeTTBP := true
211218
)
212219
.jsSettings(
213-
dbVersion := TzdbPlugin.Version(tzdbVersion),
214-
includeTTBP := true,
220+
dbVersion := TzdbPlugin.Version(tzdbVersion),
215221
Compile / sourceGenerators += Def.task {
216222
val srcDirs = (Compile / sourceManaged).value
217223
val destinationDir = (Compile / sourceManaged).value
218224
copyAndReplace(Seq(srcDirs), destinationDir)
219225
}.taskValue
220226
)
221227
.nativeSettings(
222-
crossScalaVersions -= scala3Ver,
223228
dbVersion := TzdbPlugin.Version(tzdbVersion),
224-
includeTTBP := true,
225229
tzdbPlatform := TzdbPlugin.Platform.Native,
226230
Compile / sourceGenerators += Def.task {
227231
val srcDirs = (Compile / sourceManaged).value
@@ -230,44 +234,36 @@ lazy val scalajavatimeTZDB = crossProject(JVMPlatform, JSPlatform, NativePlatfor
230234
}.taskValue
231235
)
232236
.jvmSettings(
233-
includeTTBP := true,
234237
tzdbPlatform := TzdbPlugin.Platform.Jvm
235238
)
236-
.dependsOn(scalajavatime)
237-
238-
lazy val scalajavatimeTZDBJVM = scalajavatimeTZDB.jvm.enablePlugins(TzdbPlugin)
239-
lazy val scalajavatimeTZDBJS = scalajavatimeTZDB.js.enablePlugins(TzdbPlugin)
240-
lazy val scalajavatimeTZDBNative = scalajavatimeTZDB.native.enablePlugins(TzdbPlugin)
239+
.dependsOn(core)
240+
.enablePlugins(TzdbPlugin)
241241

242-
lazy val scalajavatimeTests = crossProject(JVMPlatform, JSPlatform, NativePlatform)
242+
lazy val tests = crossProject(JVMPlatform, JSPlatform, NativePlatform)
243243
.crossType(CrossType.Full)
244244
.in(file("tests"))
245-
.settings(commonSettings: _*)
245+
.settings(commonSettings)
246246
.settings(
247-
name := "scala-java-time-tests",
248-
// No, SBT, we don't want any artifacts for root.
249-
// No, not even an empty jar.
250-
publish := {},
251-
publishLocal := {},
252-
publishArtifact := false,
247+
name := "tests",
248+
publish / skip := true,
253249
Keys.`package` := file(""),
254-
Compile / skip := isDotty.value,
255250
libraryDependencies +=
256-
"org.scalatest" %%% "scalatest" % "3.2.12" % "test",
251+
"org.scalatest" %%% "scalatest" % "3.2.12" % Test,
257252
scalacOptions ~= (_.filterNot(
258253
Set("-Wnumeric-widen", "-Ywarn-numeric-widen", "-Ywarn-value-discard", "-Wvalue-discard")
259254
))
260255
)
261256
.jvmSettings(
262257
// Fork the JVM test to ensure that the custom flags are set
263-
Test / fork := true,
264-
Test / baseDirectory := baseDirectory.value.getParentFile,
258+
Test / fork := true,
259+
Test / baseDirectory := baseDirectory.value.getParentFile,
265260
// Use CLDR provider for locales
266261
// https://docs.oracle.com/javase/8/docs/technotes/guides/intl/enhancements.8.html#cldr
267262
Test / javaOptions ++= Seq("-Duser.language=en",
268263
"-Duser.country=US",
269264
"-Djava.locale.providers=CLDR"
270-
)
265+
),
266+
Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat
271267
)
272268
.jsSettings(
273269
Test / parallelExecution := false,
@@ -281,7 +277,6 @@ lazy val scalajavatimeTests = crossProject(JVMPlatform, JSPlatform, NativePlatfo
281277
)
282278
)
283279
.nativeSettings(
284-
crossScalaVersions -= scala3Ver,
285280
Test / parallelExecution := false,
286281
Test / sourceGenerators += Def.task {
287282
val srcDirs = (Test / sourceDirectories).value
@@ -292,22 +287,20 @@ lazy val scalajavatimeTests = crossProject(JVMPlatform, JSPlatform, NativePlatfo
292287
"io.github.cquiroz" %%% "locales-full-db" % scalajavaLocalesVersion
293288
)
294289
)
295-
.dependsOn(scalajavatime, scalajavatimeTZDB)
290+
.dependsOn(core, tzdb)
296291

297292
val zonesFilterFn = (x: String) => x == "Europe/Helsinki" || x == "America/Santiago"
298293

299294
lazy val demo = crossProject(JSPlatform, JVMPlatform, NativePlatform)
300295
.in(file("demo"))
301-
.dependsOn(scalajavatime)
296+
.dependsOn(core)
302297
.enablePlugins(TzdbPlugin)
303298
.settings(
304-
scalaVersion := scalaVer,
305-
name := "demo",
306-
publish := {},
307-
publishLocal := {},
308-
publishArtifact := false,
309-
Keys.`package` := file(""),
310-
zonesFilter := zonesFilterFn
299+
scalaVersion := scalaVer,
300+
name := "demo",
301+
publish / skip := true,
302+
Keys.`package` := file(""),
303+
zonesFilter := zonesFilterFn
311304
)
312305
.jsSettings(
313306
// scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.ESModule) },
@@ -326,10 +319,6 @@ lazy val demo = crossProject(JSPlatform, JVMPlatform, NativePlatform)
326319
Compile / scalacOptions -= "-Xfatal-warnings"
327320
)
328321

329-
lazy val demoJS = demo.js
330-
lazy val demoJVM = demo.jvm
331-
lazy val demoNative = demo.native
332-
333322
// lazy val docs = project
334323
// .in(file("docs"))
335324
// .dependsOn(scalajavatime.jvm, scalajavatime.js)

core/shared/src/main/scala-2.x/org/threeten/bp/Month.scala renamed to core/shared/src/main/scala-2/org/threeten/bp/Month.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ object Month {
135135
* The singleton instance for the month of November with 30 days. This has the numeric value of
136136
* {@code 11}.
137137
*/
138-
val NOVEMBER = new Month("NOVEMBER", 10)
138+
lazy val NOVEMBER = new Month("NOVEMBER", 10)
139139

140140
/**
141141
* The singleton instance for the month of December with 31 days. This has the numeric value of
@@ -492,6 +492,7 @@ final class Month private (name: String, ordinal: Int)
492492
case OCTOBER => 274 + leap
493493
case NOVEMBER => 305 + leap
494494
case DECEMBER => 335 + leap
495+
case _ => throw new IllegalArgumentException // should never happen
495496
}
496497
}
497498

core/shared/src/main/scala/org/threeten/bp/zone/StandardZoneRules.scala

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -252,40 +252,40 @@ final class StandardZoneRules private (
252252

253253
def getOffset(localDateTime: LocalDateTime): ZoneOffset =
254254
getOffsetInfo(localDateTime) match {
255-
case transition: ZoneOffsetTransition => transition.getOffsetBefore
256-
case offset: ZoneOffset => offset
255+
case Left(transition) => transition.getOffsetBefore
256+
case Right(offset) => offset
257257
}
258258

259259
def getValidOffsets(localDateTime: LocalDateTime): java.util.List[ZoneOffset] =
260260
getOffsetInfo(localDateTime) match {
261-
case transition: ZoneOffsetTransition => transition.getValidOffsets
262-
case offset: ZoneOffset => Collections.singletonList(offset)
261+
case Left(transition) => transition.getValidOffsets
262+
case Right(offset) => Collections.singletonList(offset)
263263
}
264264

265265
def getTransition(localDateTime: LocalDateTime): ZoneOffsetTransition =
266266
getOffsetInfo(localDateTime) match {
267-
case transition: ZoneOffsetTransition => transition
268-
case _ => null
267+
case Left(transition) => transition
268+
case _ => null
269269
}
270270

271-
private def getOffsetInfo(dt: LocalDateTime): AnyRef = {
271+
private def getOffsetInfo(dt: LocalDateTime): Either[ZoneOffsetTransition, ZoneOffset] = {
272272
if (
273273
lastRules.length > 0 && dt.isAfter(
274274
savingsLocalTransitions(savingsLocalTransitions.length - 1)
275275
)
276276
) {
277-
val transArray: Array[ZoneOffsetTransition] = findTransitionArray(dt.getYear)
278-
var info: AnyRef = null
277+
val transArray: Array[ZoneOffsetTransition] = findTransitionArray(dt.getYear)
278+
var info: Either[ZoneOffsetTransition, ZoneOffset] = null
279279
for (trans <- transArray) {
280280
info = findOffsetInfo(dt, trans)
281-
if (info.isInstanceOf[ZoneOffsetTransition] || (info == trans.getOffsetBefore))
281+
if (info.isLeft || (info == Right(trans.getOffsetBefore)))
282282
return info
283283
}
284284
return info
285285
}
286286
var index: Int = Arrays.binarySearch(savingsLocalTransitions.asInstanceOf[Array[AnyRef]], dt)
287287
if (index == -1)
288-
return wallOffsets(0)
288+
return Right(wallOffsets(0))
289289
if (index < 0)
290290
index = -index - 2
291291
else if (
@@ -302,11 +302,11 @@ final class StandardZoneRules private (
302302
val offsetBefore: ZoneOffset = wallOffsets(index / 2)
303303
val offsetAfter: ZoneOffset = wallOffsets(index / 2 + 1)
304304
if (offsetAfter.getTotalSeconds > offsetBefore.getTotalSeconds)
305-
new ZoneOffsetTransition(dtBefore, offsetBefore, offsetAfter)
305+
Left(new ZoneOffsetTransition(dtBefore, offsetBefore, offsetAfter))
306306
else
307-
new ZoneOffsetTransition(dtAfter, offsetBefore, offsetAfter)
307+
Left(new ZoneOffsetTransition(dtAfter, offsetBefore, offsetAfter))
308308
} else
309-
wallOffsets(index / 2 + 1)
309+
Right(wallOffsets(index / 2 + 1))
310310
}
311311

312312
/**
@@ -319,21 +319,24 @@ final class StandardZoneRules private (
319319
* @return
320320
* the offset info, not null
321321
*/
322-
private def findOffsetInfo(dt: LocalDateTime, trans: ZoneOffsetTransition): AnyRef = {
322+
private def findOffsetInfo(
323+
dt: LocalDateTime,
324+
trans: ZoneOffsetTransition
325+
): Either[ZoneOffsetTransition, ZoneOffset] = {
323326
val localTransition: LocalDateTime = trans.getDateTimeBefore
324327
if (trans.isGap)
325328
if (dt.isBefore(localTransition))
326-
trans.getOffsetBefore
329+
Right(trans.getOffsetBefore)
327330
else if (dt.isBefore(trans.getDateTimeAfter))
328-
trans
331+
Left(trans)
329332
else
330-
trans.getOffsetAfter
333+
Right(trans.getOffsetAfter)
331334
else if (!dt.isBefore(localTransition))
332-
trans.getOffsetAfter
335+
Right(trans.getOffsetAfter)
333336
else if (dt.isBefore(trans.getDateTimeAfter))
334-
trans.getOffsetBefore
337+
Right(trans.getOffsetBefore)
335338
else
336-
trans
339+
Left(trans)
337340
}
338341

339342
def isValidOffset(localDateTime: LocalDateTime, offset: ZoneOffset): Boolean =

project/build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.6.1
1+
sbt.version=1.6.2

0 commit comments

Comments
 (0)