diff --git a/build.sbt b/build.sbt index bc1f659ae..647bf471d 100644 --- a/build.sbt +++ b/build.sbt @@ -94,6 +94,9 @@ ThisBuild / scalaOrganization := "org.scala-lang" ThisBuild / evictionErrorLevel := Level.Warn ThisBuild / semanticdbEnabled := true +val assertionsEnabled = settingKey[Boolean]("Whether to compile `_assert` calls") +ThisBuild / assertionsEnabled := !java.lang.Boolean.getBoolean("dev.tauri.choam.build.disableAssertions") + ThisBuild / tlBaseVersion := "0.4" ThisBuild / tlUntaggedAreSnapshots := false // => we get versions like 0.4-39d987a ThisBuild / tlJdkRelease := Some(11) @@ -339,13 +342,17 @@ lazy val skiplist = crossProject(JVMPlatform, JSPlatform) .in(file("skiplist")) .settings(name := "choam-skiplist") .disablePlugins(disabledPlugins: _*) + .enablePlugins(BuildInfoPlugin) .settings(commonSettings) .jvmSettings(commonSettingsJvm) .jsSettings(commonSettingsJs) - .settings(libraryDependencies ++= Seq( - dependencies.catsKernel.value, - dependencies.catsScalacheck.value % TestInternal, - )) + .settings(buildInfoSettings(pkg = "dev.tauri.choam.internal")) + .settings( + libraryDependencies ++= Seq( + dependencies.catsKernel.value, + dependencies.catsScalacheck.value % TestInternal, + ), + ) lazy val data = crossProject(JVMPlatform, JSPlatform) .crossType(CrossType.Full) @@ -445,11 +452,15 @@ lazy val ce = crossProject(JVMPlatform, JSPlatform) /** Internal use only; no published project may depend on this */ lazy val internalHelpers = project.in(file("internal-helpers")) .settings(name := "choam-internal-helpers") - .enablePlugins(NoPublishPlugin) + .enablePlugins(NoPublishPlugin, BuildInfoPlugin) .disablePlugins(disabledPlugins: _*) .settings(commonSettings) .settings(commonSettingsJvm) + .settings(buildInfoSettings(pkg = "dev.tauri.choam.helpers")) .dependsOn(ce.jvm % "compile->compile;test->test") + .settings( + assertionsEnabled := false, // so that we can test that they're disabled + ) lazy val laws = crossProject(JVMPlatform, JSPlatform) .crossType(CrossType.Full) @@ -703,7 +714,6 @@ lazy val commonSettingsJs = Seq[Setting[_]]( lazy val commonSettings = Seq[Setting[_]]( scalacOptions ++= Seq( "-language:higherKinds", - // TODO: "-Xelide-below", "INFO", // TODO: experiment with -Ydelambdafy:inline for performance // TODO: experiment with -Yno-predef and/or -Yno-imports ), @@ -719,7 +729,7 @@ lazy val commonSettings = Seq[Setting[_]]( "-Xsource:3-cross", "-Wnonunit-statement", "-Wvalue-discard", - ) + ) ++ (if (assertionsEnabled.value) Nil else List("-Xelide-below", "2001")) } else { // 3.x: List( @@ -787,6 +797,17 @@ lazy val commonSettings = Seq[Setting[_]]( inTask(packageDoc)(extraPackagingSettings) ) ++ publishSettings +def buildInfoSettings(pkg: String): Seq[Setting[_]] = Seq( + buildInfoPackage := pkg, + buildInfoKeys := Seq( + assertionsEnabled, + ), + buildInfoOptions ++= Seq( + BuildInfoOption.PackagePrivate, + BuildInfoOption.ConstantValue, + ), +) + lazy val publishSettings = Seq[Setting[_]]( organization := "dev.tauri", organizationHomepage := Some(url("https://tauri.dev")), diff --git a/core/shared/src/main/scala/dev/tauri/choam/package.scala b/core/shared/src/main/scala/dev/tauri/choam/package.scala index 59db19751..c70dfb8f2 100644 --- a/core/shared/src/main/scala/dev/tauri/choam/package.scala +++ b/core/shared/src/main/scala/dev/tauri/choam/package.scala @@ -17,7 +17,7 @@ package dev.tauri -package object choam { +package object choam extends internal.ChoamUtils { private[choam] type tailrec = scala.annotation.tailrec diff --git a/core/shared/src/test/scala/dev/tauri/choam/core/AssertSpec.scala b/core/shared/src/test/scala/dev/tauri/choam/core/AssertSpec.scala new file mode 100644 index 000000000..015024be9 --- /dev/null +++ b/core/shared/src/test/scala/dev/tauri/choam/core/AssertSpec.scala @@ -0,0 +1,26 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package core + +final class AssertSpec extends BaseSpec { + + test("_assert should be enabled during tests (for now)".fail) { + _assert(false) + } +} diff --git a/internal-helpers/src/test/scala-2.13/dev/tauri/choam/helpers/ChoamUtils2.scala b/internal-helpers/src/test/scala-2.13/dev/tauri/choam/helpers/ChoamUtils2.scala new file mode 100644 index 000000000..8aef2dc56 --- /dev/null +++ b/internal-helpers/src/test/scala-2.13/dev/tauri/choam/helpers/ChoamUtils2.scala @@ -0,0 +1,34 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package helpers + +import scala.annotation.{ elidable, nowarn } + +// Note: this is duplicated from `ChoamUtils`, +// so that we can test disabling `_assert`. +@nowarn("msg=elidable") +private[choam] abstract class ChoamUtils2 { + + @elidable(elidable.ASSERTION) + private[choam] final def _assert(ok: Boolean): Unit = { + if (!ok) { + throw new AssertionError + } + } +} diff --git a/internal-helpers/src/test/scala-2.13/dev/tauri/choam/helpers/DisableAssertionsSpecScala213.scala b/internal-helpers/src/test/scala-2.13/dev/tauri/choam/helpers/DisableAssertionsSpecScala213.scala new file mode 100644 index 000000000..432f613af --- /dev/null +++ b/internal-helpers/src/test/scala-2.13/dev/tauri/choam/helpers/DisableAssertionsSpecScala213.scala @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package helpers + +final class DisableAssertionsSpecScala213 extends BaseSpec { + + test("The Scala 2.13 `-Xelide-below` also affects Predef.assert") { + Predef.assert(false) + Predef.assert(false, "foo") + } +} diff --git a/internal-helpers/src/test/scala-3/dev/tauri/choam/helpers/ChoamUtils2.scala b/internal-helpers/src/test/scala-3/dev/tauri/choam/helpers/ChoamUtils2.scala new file mode 100644 index 000000000..7e9bcc6aa --- /dev/null +++ b/internal-helpers/src/test/scala-3/dev/tauri/choam/helpers/ChoamUtils2.scala @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package helpers + +// Note: this is duplicated from `ChoamUtils`, +// so that we can test disabling `_assert`. +private[choam] abstract class ChoamUtils2 { + + private[choam] inline final val assertionsEnabled = + BuildInfo.assertionsEnabled + + private[choam] inline final def _assert(inline ok: Boolean): Unit = { + inline if (assertionsEnabled) { + if (!ok) { + throw new AssertionError + } + } + } +} diff --git a/internal-helpers/src/test/scala/dev/tauri/choam/helpers/DisabledAssertionsSpec.scala b/internal-helpers/src/test/scala/dev/tauri/choam/helpers/DisabledAssertionsSpec.scala new file mode 100644 index 000000000..117247893 --- /dev/null +++ b/internal-helpers/src/test/scala/dev/tauri/choam/helpers/DisabledAssertionsSpec.scala @@ -0,0 +1,43 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package helpers + +final class DisableAssertionsSpec extends BaseSpec { + + test("_assert should have no effect") { + _assert(false) + _assert({ throw new Exception; false }) : @nowarn("cat=w-flag-dead-code") + } + + test("munit assert should still work".fail) { + this.assert(false) + } + + test("require(Boolean) should still work".fail) { + require(false) + } + + test("require(Boolean, => Any) should still work".fail) { + require(false, "foo") + } + + test("impossible should still work".fail) { + impossible("foo") + } +} diff --git a/internal-helpers/src/test/scala/dev/tauri/choam/helpers/package.scala b/internal-helpers/src/test/scala/dev/tauri/choam/helpers/package.scala new file mode 100644 index 000000000..0f0a86d8b --- /dev/null +++ b/internal-helpers/src/test/scala/dev/tauri/choam/helpers/package.scala @@ -0,0 +1,20 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam + +package object helpers extends ChoamUtils2 diff --git a/mcas/shared/src/main/scala/dev/tauri/choam/internal/mcas/package.scala b/mcas/shared/src/main/scala/dev/tauri/choam/internal/mcas/package.scala index 9e50aeeb8..6c534e1ba 100644 --- a/mcas/shared/src/main/scala/dev/tauri/choam/internal/mcas/package.scala +++ b/mcas/shared/src/main/scala/dev/tauri/choam/internal/mcas/package.scala @@ -18,7 +18,7 @@ package dev.tauri.choam package internal -package object mcas { +package object mcas extends ChoamUtils { private[mcas] type tailrec = scala.annotation.tailrec diff --git a/mcas/shared/src/test/scala/dev/tauri/choam/internal/mcas/AssertSpec.scala b/mcas/shared/src/test/scala/dev/tauri/choam/internal/mcas/AssertSpec.scala new file mode 100644 index 000000000..621e8a6e4 --- /dev/null +++ b/mcas/shared/src/test/scala/dev/tauri/choam/internal/mcas/AssertSpec.scala @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package internal +package mcas + +final class AssertSpec extends BaseSpec { + + test("_assert should be enabled during tests (for now)".fail) { + _assert(false) + } +} diff --git a/project/plugins.sbt b/project/plugins.sbt index 112eb8ef0..3e7bcbc71 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -37,5 +37,6 @@ addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2") // htt addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.17.0") // https://www.scala-js.org/ addSbtPlugin("net.bzzt" % "sbt-strict-scala-versions" % "0.0.1") // https://github.com/raboof/sbt-strict-scala-versions addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.10.4") // https://github.com/sbt/sbt-native-packager +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.13.1") // https://github.com/sbt/sbt-buildinfo ThisBuild / semanticdbEnabled := true diff --git a/skiplist/jvm/src/test/scala/dev/tauri/choam/internal/skiplist/AssertSpec.scala b/skiplist/jvm/src/test/scala/dev/tauri/choam/internal/skiplist/AssertSpec.scala new file mode 100644 index 000000000..72c76ba8a --- /dev/null +++ b/skiplist/jvm/src/test/scala/dev/tauri/choam/internal/skiplist/AssertSpec.scala @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package internal +package skiplist + +final class AssertSpec extends munit.FunSuite { + + test("_assert should be enabled during tests (for now)".fail) { + _assert(false) + } +} diff --git a/skiplist/shared/src/main/scala-2.13/dev/tauri/choam/internal/ChoamUtils.scala b/skiplist/shared/src/main/scala-2.13/dev/tauri/choam/internal/ChoamUtils.scala new file mode 100644 index 000000000..0d3467e13 --- /dev/null +++ b/skiplist/shared/src/main/scala-2.13/dev/tauri/choam/internal/ChoamUtils.scala @@ -0,0 +1,33 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package internal + +import scala.annotation.{ elidable, nowarn } + +// Note: this code is duplicated for (1) Scala 2.13/3, and (2) for tests in `helpers`. +@nowarn("msg=elidable") +private[choam] abstract class ChoamUtils { + + @elidable(elidable.ASSERTION) + private[choam] final def _assert(ok: Boolean): Unit = { + if (!ok) { + throw new AssertionError + } + } +} diff --git a/skiplist/shared/src/main/scala-3/dev/tauri/choam/internal/ChoamUtils.scala b/skiplist/shared/src/main/scala-3/dev/tauri/choam/internal/ChoamUtils.scala new file mode 100644 index 000000000..e52f83eac --- /dev/null +++ b/skiplist/shared/src/main/scala-3/dev/tauri/choam/internal/ChoamUtils.scala @@ -0,0 +1,34 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.tauri.choam +package internal + +// Note: this code is duplicated for (1) Scala 2.13/3, and (2) for tests in `helpers`. +private[choam] abstract class ChoamUtils { + + private[choam] inline final val assertionsEnabled = + BuildInfo.assertionsEnabled + + private[choam] inline final def _assert(inline ok: Boolean): Unit = { + inline if (assertionsEnabled) { + if (!ok) { + throw new AssertionError + } + } + } +} diff --git a/skiplist/shared/src/main/scala/dev/tauri/choam/internal/skiplist/package.scala b/skiplist/shared/src/main/scala/dev/tauri/choam/internal/skiplist/package.scala index 7a6eb7513..390a4b59e 100644 --- a/skiplist/shared/src/main/scala/dev/tauri/choam/internal/skiplist/package.scala +++ b/skiplist/shared/src/main/scala/dev/tauri/choam/internal/skiplist/package.scala @@ -18,7 +18,7 @@ package dev.tauri.choam package internal -package object skiplist { +package object skiplist extends ChoamUtils { private[choam] type tailrec = scala.annotation.tailrec