diff --git a/build.sbt b/build.sbt index f9f58c0c91..6c06c611fe 100644 --- a/build.sbt +++ b/build.sbt @@ -75,13 +75,13 @@ val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.2.0" val debox = "org.scorexfoundation" %% "debox" % "0.10.0" val spireMacros = "org.typelevel" %% "spire-macros" % "0.17.0-M1" val fastparse = "com.lihaoyi" %% "fastparse" % "2.3.3" -val guava = "com.google.guava" % "guava" % "30.1.1-jre" val scalaCompat = "org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0" val testingDependencies = Seq( - "org.scalatest" %% "scalatest" % "3.0.9" % Test, - "org.scalactic" %% "scalactic" % "3.0.9" % Test, - "org.scalacheck" %% "scalacheck" % "1.14.3" % Test, + "org.scalatest" %% "scalatest" % "3.2.14" % Test, + "org.scalactic" %% "scalactic" % "3.2.14" % Test, + "org.scalacheck" %% "scalacheck" % "1.15.2" % Test, // last supporting Scala 2.11 + "org.scalatestplus" %% "scalacheck-1-15" % "3.2.3.0" % Test, // last supporting Scala 2.11 "com.lihaoyi" %% "pprint" % "0.6.3" % Test, "com.storm-enroute" %% "scalameter" % "0.19" % Test, "junit" % "junit" % "4.12" % Test @@ -101,7 +101,11 @@ libraryDependencies ++= Seq( scorexUtil, "org.bouncycastle" % "bcprov-jdk15on" % "1.+", fastparse, debox, spireMacros, scalaCompat -) ++ testingDependencies +) ++ testingDependencies ++ + (if (scalaVersion.value == scala211) + Seq(circeCore211, circeGeneric211, circeParser211) + else + Seq(circeCore, circeGeneric, circeParser)) lazy val circeCore211 = "io.circe" %% "circe-core" % "0.10.0" lazy val circeGeneric211 = "io.circe" %% "circe-generic" % "0.10.0" @@ -111,12 +115,6 @@ lazy val circeCore = "io.circe" %% "circe-core" % "0.13.0" lazy val circeGeneric = "io.circe" %% "circe-generic" % "0.13.0" lazy val circeParser = "io.circe" %% "circe-parser" % "0.13.0" -libraryDependencies ++= Seq( - if (scalaVersion.value == scala211) circeCore211 else circeCore, - if (scalaVersion.value == scala211) circeGeneric211 else circeGeneric, - if (scalaVersion.value == scala211) circeParser211 else circeParser - ) - scalacOptions ++= Seq("-feature", "-deprecation") parallelExecution in Test := false @@ -147,10 +145,10 @@ usePgpKeyHex("C1FD62B4D44BDF702CDF2B726FF59DA944B150DD") def libraryDefSettings = commonSettings ++ testSettings lazy val common = Project("common", file("common")) - .settings(commonSettings ++ testSettings, + .settings(libraryDefSettings, libraryDependencies ++= Seq( "org.scala-lang" % "scala-reflect" % scalaVersion.value, - debox, scalaCompat, guava + debox, scalaCompat )) .settings(publish / skip := true) @@ -168,14 +166,14 @@ lazy val libraryimpl = Project("library-impl", file("library-impl")) lazy val core = Project("core", file("core")) .dependsOn(common % allConfigDependency, libraryapi % allConfigDependency) - .settings(commonSettings, + .settings(libraryDefSettings, libraryDependencies ++= Seq( debox )) .settings(publish / skip := true) lazy val library = Project("library", file("library")) .dependsOn(common % allConfigDependency, core % allConfigDependency, libraryapi, libraryimpl) - .settings(//commonSettings, - libraryDefSettings ++ testSettings, + .settings( + libraryDefSettings, libraryDependencies ++= Seq( debox )) .settings(publish / skip := true) @@ -234,94 +232,3 @@ lazy val rootSettings = Seq( mappings in (Test, packageBin) ++= (mappings in(Test, packageBin)).all(aggregateCompile).value.flatten, mappings in(Test, packageSrc) ++= (mappings in(Test, packageSrc)).all(aggregateCompile).value.flatten ) - -def runErgoTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val ergoBranch = "test-coverage" - val sbtEnvVars = Seq("BUILD_ENV" -> "test", "SIGMASTATE_VERSION" -> sigmastateVersion) - - log.info(s"Testing current build in Ergo (branch $ergoBranch):") - val cwd = new File("").absolutePath - val ergoPath = new File(cwd + "/ergo-tests/") - log.info(s"Cleaning $ergoPath") - s"rm -rf ${ergoPath.absolutePath}" ! - - log.info(s"Cloning Ergo branch $ergoBranch into ${ergoPath.absolutePath}") - s"git clone -b $ergoBranch --single-branch https://github.com/ergoplatform/ergo.git ${ergoPath.absolutePath}" ! - - - log.info(s"Updating Ergo in $ergoPath with Sigmastate version $sigmastateVersion") - Process(Seq("sbt", "unlock", "reload", "lock"), ergoPath, sbtEnvVars: _*) ! - - log.info("Updated Ergo lock.sbt:") - Process(Seq("git", "diff", "-U0", "lock.sbt"), ergoPath) ! - - log.info(s"Running Ergo tests in $ergoPath with Sigmastate version $sigmastateVersion") - val res = Process(Seq("sbt", task), ergoPath, sbtEnvVars: _*) ! - - if (res != 0) sys.error(s"Ergo $task failed!") -} - -lazy val ergoUnitTestTask = TaskKey[Unit]("ergoUnitTestTask", "run ergo unit tests with current version") -ergoUnitTestTask := { - val log = streams.value.log - val sigmastateVersion = version.value - runErgoTask("test", sigmastateVersion, log) -} - -commands += Command.command("ergoUnitTest") { state => - "clean" :: - "publishLocal" :: - "ergoUnitTestTask" :: - state -} - -lazy val ergoItTestTask = TaskKey[Unit]("ergoItTestTask", "run ergo it:test with current version") -ergoItTestTask := { - val log = streams.value.log - val sigmastateVersion = version.value - runErgoTask("it:test", sigmastateVersion, log) -} - -commands += Command.command("ergoItTest") { state => - "clean" :: - "publishLocal" :: - "ergoItTestTask" :: - state -} - -def runSpamTestTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val spamBranch = "master" - val envVars = Seq("SIGMASTATE_VERSION" -> sigmastateVersion, - // SSH_SPAM_REPO_KEY should be set (see Jenkins Credentials Binding Plugin) - "GIT_SSH_COMMAND" -> "ssh -i $SSH_SPAM_REPO_KEY") - - log.info(s"Testing current build with spam tests (branch $spamBranch):") - val cwd = new File("") - val spamPath = new File(cwd.absolutePath + "/spam-tests/") - log.info(s"Cleaning $spamPath") - s"rm -rf ${spamPath.absolutePath}" ! - - log.info(s"Cloning spam tests branch $spamBranch into ${spamPath.absolutePath}") - Process(Seq("git", "clone", "-b", spamBranch, "--single-branch", "git@github.com:greenhat/sigma-spam.git", spamPath.absolutePath), - cwd.getAbsoluteFile, - envVars: _*) ! - - log.info(s"Running spam tests in $spamPath with Sigmastate version $sigmastateVersion") - val res = Process(Seq("sbt", task), spamPath, envVars: _*) ! - - if (res != 0) sys.error(s"Spam $task failed!") -} - -lazy val spamTestTask = TaskKey[Unit]("spamTestTask", "run spam tests with current version") -spamTestTask := { - val log = streams.value.log - val sigmastateVersion = version.value - runSpamTestTask("test", sigmastateVersion, log) -} - -commands += Command.command("spamTest") { state => - "clean" :: - "publishLocal" :: - "spamTestTask" :: - state -} diff --git a/common/src/main/java/java7/compat/Math.java b/common/src/main/java/java7/compat/Math.java deleted file mode 100644 index 72ed8d5de0..0000000000 --- a/common/src/main/java/java7/compat/Math.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java7.compat; - -/** - * Contains methods introduced since Java 1.8 which are not available in Java 1.7. - * Using this methods supports compatibility with Java 1.7 in non-JVM contexts like - * RoboVM. - * The implementations are copies from JDK 1.8 sources. - *

- * See - * this issue - */ -public final class Math { - /** - * Returns the sum of its arguments, - * throwing an exception if the result overflows an {@code int}. - * - * @param x the first value - * @param y the second value - * @return the result - * @throws ArithmeticException if the result overflows an int - * @since 1.8 - */ - public static int addExact(int x, int y) { - int r = x + y; - // HD 2-12 Overflow iff both arguments have the opposite sign of the result - if (((x ^ r) & (y ^ r)) < 0) { - throw new ArithmeticException("integer overflow"); - } - return r; - } - - /** - * Returns the sum of its arguments, - * throwing an exception if the result overflows a {@code long}. - * - * @param x the first value - * @param y the second value - * @return the result - * @throws ArithmeticException if the result overflows a long - * @since 1.8 - */ - public static long addExact(long x, long y) { - long r = x + y; - // HD 2-12 Overflow iff both arguments have the opposite sign of the result - if (((x ^ r) & (y ^ r)) < 0) { - throw new ArithmeticException("long overflow"); - } - return r; - } - - /** - * Returns the difference of the arguments, - * throwing an exception if the result overflows an {@code int}. - * - * @param x the first value - * @param y the second value to subtract from the first - * @return the result - * @throws ArithmeticException if the result overflows an int - * @since 1.8 - */ - public static int subtractExact(int x, int y) { - int r = x - y; - // HD 2-12 Overflow iff the arguments have different signs and - // the sign of the result is different than the sign of x - if (((x ^ y) & (x ^ r)) < 0) { - throw new ArithmeticException("integer overflow"); - } - return r; - } - - /** - * Returns the difference of the arguments, - * throwing an exception if the result overflows a {@code long}. - * - * @param x the first value - * @param y the second value to subtract from the first - * @return the result - * @throws ArithmeticException if the result overflows a long - * @since 1.8 - */ - public static long subtractExact(long x, long y) { - long r = x - y; - // HD 2-12 Overflow iff the arguments have different signs and - // the sign of the result is different than the sign of x - if (((x ^ y) & (x ^ r)) < 0) { - throw new ArithmeticException("long overflow"); - } - return r; - } - - /** - * Returns the product of the arguments, - * throwing an exception if the result overflows an {@code int}. - * - * @param x the first value - * @param y the second value - * @return the result - * @throws ArithmeticException if the result overflows an int - * @since 1.8 - */ - public static int multiplyExact(int x, int y) { - long r = (long)x * (long)y; - if ((int)r != r) { - throw new ArithmeticException("integer overflow"); - } - return (int)r; - } - - /** - * Returns the product of the arguments, - * throwing an exception if the result overflows a {@code long}. - * - * @param x the first value - * @param y the second value - * @return the result - * @throws ArithmeticException if the result overflows a long - * @since 1.8 - */ - public static long multiplyExact(long x, long y) { - long r = x * y; - long ax = java.lang.Math.abs(x); - long ay = java.lang.Math.abs(y); - if (((ax | ay) >>> 31 != 0)) { - // Some bits greater than 2^31 that might cause overflow - // Check the result using the divide operator - // and check for the special case of Long.MIN_VALUE * -1 - if (((y != 0) && (r / y != x)) || - (x == Long.MIN_VALUE && y == -1)) { - throw new ArithmeticException("long overflow"); - } - } - return r; - } -} diff --git a/common/src/main/java/scalan/Builtin.java b/common/src/main/java/scalan/Builtin.java deleted file mode 100644 index 83a1c37b84..0000000000 --- a/common/src/main/java/scalan/Builtin.java +++ /dev/null @@ -1,17 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** Relate annotated element with internal type or method given by `value` property. -* Applied to entities that should be replaced during virtualization by related type. -* The given related type is said to be pre-virtualized. -* The 'value' is a name of the class which can be resolved in a Scalan cake. E.g. IsoUR*/ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Builtin { - String value() default ""; // default value interpreted as "virtualized name is equal to annotated element name" -} diff --git a/common/src/main/java/scalan/Constructor.java b/common/src/main/java/scalan/Constructor.java deleted file mode 100644 index 0caecfe3d9..0000000000 --- a/common/src/main/java/scalan/Constructor.java +++ /dev/null @@ -1,14 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Used in generated wrappers. - * Annotates a wrapper method of the companion of a virtualized type wrapper, - * which (the method) corresponds to the constructor of wrapped type. */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Constructor { -} diff --git a/common/src/main/java/scalan/ContainerType.java b/common/src/main/java/scalan/ContainerType.java deleted file mode 100644 index c3768cda3c..0000000000 --- a/common/src/main/java/scalan/ContainerType.java +++ /dev/null @@ -1,14 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Annotates Special DSL types which implement the interface of containers. -* Each container is described using Cont[_] descriptors. -* Special supporting code is generated for annotated entities. */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.CLASS) -public @interface ContainerType { -} diff --git a/common/src/main/java/scalan/Convertible.java b/common/src/main/java/scalan/Convertible.java deleted file mode 100644 index 662f5f6ee3..0000000000 --- a/common/src/main/java/scalan/Convertible.java +++ /dev/null @@ -1,12 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Marks annotated type as having support for generic Converter generation. */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Convertible { -} diff --git a/common/src/main/java/scalan/External.java b/common/src/main/java/scalan/External.java deleted file mode 100644 index e8e2864c7c..0000000000 --- a/common/src/main/java/scalan/External.java +++ /dev/null @@ -1,15 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Relate annotated element with an external type or method given by `value` property. -* For example WOption related to Option is annotated as @External("Option") -* This annotation is used to separate wrapper Entity from user defined virtualized Entity. -* See WrapperEntity object. */ -@Target({ElementType.TYPE, ElementType.METHOD}) -public @interface External { - String value() default ""; // default value interpreted as "external name is equal to annotated element name" -} diff --git a/common/src/main/java/scalan/FunctorType.java b/common/src/main/java/scalan/FunctorType.java deleted file mode 100644 index 9832d78271..0000000000 --- a/common/src/main/java/scalan/FunctorType.java +++ /dev/null @@ -1,13 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Used to annotate container types (like Option, Coll), which have - * functor semantics. Special code is generated for such entities. */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.CLASS) -public @interface FunctorType { -} diff --git a/common/src/main/java/scalan/InlineAt.java b/common/src/main/java/scalan/InlineAt.java deleted file mode 100644 index 0590456be7..0000000000 --- a/common/src/main/java/scalan/InlineAt.java +++ /dev/null @@ -1,18 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Specifies the predicate when the annotated method should be inlined. -* The predicate is given by the parsable formula which can be used to -* create runtime predicate functions. -* Default empty string is interpreted as never invoke, in which case scalanizer -* don't perform virtualization of the method body and replace it with delayInvoke. */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface InlineAt { - String Never = ""; - String value() default Never; -} diff --git a/common/src/main/java/scalan/Internal.java b/common/src/main/java/scalan/Internal.java deleted file mode 100644 index 1555984ccc..0000000000 --- a/common/src/main/java/scalan/Internal.java +++ /dev/null @@ -1,14 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Used to annotate type and methods, which should not be virtualized. - * Everything marked @Internal are invisible for virtualization process. - */ -@Target({ElementType.TYPE, ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Internal { -} diff --git a/common/src/main/java/scalan/Isospec.java b/common/src/main/java/scalan/Isospec.java deleted file mode 100644 index d5c2498537..0000000000 --- a/common/src/main/java/scalan/Isospec.java +++ /dev/null @@ -1,12 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Marks annotated type as having support for isomorphic specialization. */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Isospec { -} diff --git a/common/src/main/java/scalan/Liftable.java b/common/src/main/java/scalan/Liftable.java deleted file mode 100644 index 83dc56bc17..0000000000 --- a/common/src/main/java/scalan/Liftable.java +++ /dev/null @@ -1,12 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Marks annotated type as having support for lifting values to IR nodes. */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Liftable { -} diff --git a/common/src/main/java/scalan/NeverInline.java b/common/src/main/java/scalan/NeverInline.java deleted file mode 100644 index 39b63e9a0c..0000000000 --- a/common/src/main/java/scalan/NeverInline.java +++ /dev/null @@ -1,12 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Equvalent to InlineAt(Never). */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface NeverInline { -} diff --git a/common/src/main/java/scalan/OverloadId.java b/common/src/main/java/scalan/OverloadId.java deleted file mode 100644 index c167013698..0000000000 --- a/common/src/main/java/scalan/OverloadId.java +++ /dev/null @@ -1,13 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Assigns an alternative name to the overloaded method. */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface OverloadId { - String value(); -} diff --git a/common/src/main/java/scalan/Reified.java b/common/src/main/java/scalan/Reified.java deleted file mode 100644 index 360340f678..0000000000 --- a/common/src/main/java/scalan/Reified.java +++ /dev/null @@ -1,19 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Type argument T should be reified in virtualized code type descriptor Elem[T] available -* in the scope where T is visible. This can be done either by explicitly passing additional -* parameter eT: Elem[T] or by proving that Elem[T] can be retrieved from the other arguments -* of the method or class. For example if x: Rep[T] then eT can be obtained by x.elem. -* The need for reified type arguments come from ClassTag[T], RType[T] context bounds or -* implicit parameters in the source code. -*/ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Reified { - String value() default ""; -} diff --git a/common/src/main/java/scalan/WithMethodCallRecognizers.java b/common/src/main/java/scalan/WithMethodCallRecognizers.java deleted file mode 100644 index 37e229ed01..0000000000 --- a/common/src/main/java/scalan/WithMethodCallRecognizers.java +++ /dev/null @@ -1,17 +0,0 @@ -package scalan; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Marks annotated method or trait/class as having support for pattern matching. - * Extractor methods will be generated by codegen for each method either annotated or - * belonging to the annotated type. - * Extractors can be used in rewriting rules to recognize IR nodes of MethodCall type, - * which represents the call of the annotated method. - */ -@Target({ElementType.METHOD,ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface WithMethodCallRecognizers { -} diff --git a/common/src/main/scala/java7/compat/Math.scala b/common/src/main/scala/java7/compat/Math.scala new file mode 100644 index 0000000000..a1a7ce1296 --- /dev/null +++ b/common/src/main/scala/java7/compat/Math.scala @@ -0,0 +1,126 @@ +package java7.compat + +/** + * Contains methods introduced since Java 1.8 which are not available in Java 1.7. + * Using this methods supports compatibility with Java 1.7 in non-JVM contexts like + * RoboVM. + * The implementations are copies from JDK 1.8 sources. + *

+ * See + * this issue + */ +object Math { + /** + * Returns the sum of its arguments, + * throwing an exception if the result overflows an {@code int}. + * + * @param x the first value + * @param y the second value + * @return the result + * @throws ArithmeticException if the result overflows an int + */ + def addExact(x: Int, y: Int): Int = { + val r = x + y + // HD 2-12 Overflow iff both arguments have the opposite sign of the result + if (((x ^ r) & (y ^ r)) < 0) { + throw new ArithmeticException("integer overflow") + } + r + } + + /** + * Returns the sum of its arguments, + * throwing an exception if the result overflows a {@code long}. + * + * @param x the first value + * @param y the second value + * @return the result + * @throws ArithmeticException if the result overflows a long + */ + def addExact(x: Long, y: Long): Long = { + val r = x + y + if (((x ^ r) & (y ^ r)) < 0) { + throw new ArithmeticException("long overflow") + } + r + } + + /** + * Returns the difference of the arguments, + * throwing an exception if the result overflows an {@code int}. + * + * @param x the first value + * @param y the second value to subtract from the first + * @return the result + * @throws ArithmeticException if the result overflows an int + */ + def subtractExact(x: Int, y: Int): Int = { + val r = x - y + // HD 2-12 Overflow iff the arguments have different signs and + // the sign of the result is different than the sign of x + if (((x ^ y) & (x ^ r)) < 0) { + throw new ArithmeticException("integer overflow") + } + r + } + + /** + * Returns the difference of the arguments, + * throwing an exception if the result overflows a {@code long}. + * + * @param x the first value + * @param y the second value to subtract from the first + * @return the result + * @throws ArithmeticException if the result overflows a long + */ + def subtractExact(x: Long, y: Long) = { + val r = x - y + // HD 2-12 Overflow iff the arguments have different signs and + // the sign of the result is different than the sign of x + if (((x ^ y) & (x ^ r)) < 0) { + throw new ArithmeticException("long overflow") + } + r + } + + /** + * Returns the product of the arguments, + * throwing an exception if the result overflows an {@code int}. + * + * @param x the first value + * @param y the second value + * @return the result + * @throws ArithmeticException if the result overflows an int + */ + def multiplyExact(x: Int, y: Int) = { + val r = x.toLong * y.toLong + if (r.toInt != r) { + throw new ArithmeticException("integer overflow") + } + r.toInt + } + + /** + * Returns the product of the arguments, + * throwing an exception if the result overflows a {@code long}. + * + * @param x the first value + * @param y the second value + * @return the result + * @throws ArithmeticException if the result overflows a long + */ + def multiplyExact(x: Long, y: Long) = { + val r = x * y + val ax = java.lang.Math.abs(x) + val ay = java.lang.Math.abs(y) + if ((ax | ay) >>> 31 != 0) { + // Some bits greater than 2^31 that might cause overflow + // Check the result using the divide operator + // and check for the special case of Long.MIN_VALUE * -1 + if (((y != 0) && (r / y != x)) || (x == Long.MinValue && y == -1)) { + throw new ArithmeticException("long overflow") + } + } + r + } +} diff --git a/common/src/main/scala/scalan/util/ReflectionUtil.scala b/common/src/main/scala/scalan/util/ReflectionUtil.scala index c463e8a787..15c73b0548 100644 --- a/common/src/main/scala/scalan/util/ReflectionUtil.scala +++ b/common/src/main/scala/scalan/util/ReflectionUtil.scala @@ -1,33 +1,19 @@ package scalan.util -import java.lang.reflect.{Method, AnnotatedElement} import scala.language.existentials -import scala.reflect.{classTag, ClassTag} -import scalan.OverloadId object ReflectionUtil { - def jAnnotation[A <: java.lang.annotation.Annotation : ClassTag](element: AnnotatedElement) = - Option(element.getAnnotation(classTag[A].runtimeClass.asInstanceOf[Class[A]])) - - def overloadId(method: Method) = jAnnotation[OverloadId](method).map(_.value) - - /** Returns the superclass for an anonymous class produced by mixing in traits; the argument otherwise. */ - def namedSuperclass(clazz: Class[_]) = { - if (clazz.getSimpleName.contains("$anon$")) { - val superclass = clazz.getSuperclass - if (superclass == classOf[Object]) { - // clazz is composed of traits only, return the first one - clazz.getInterfaces.head - } else - superclass - } else - clazz - } implicit class ClassOps(val cl: Class[_]) extends AnyVal { + /** Special character in the name. */ private def isSpecialChar(c: Char): Boolean = { ('0' <= c && c <= '9') || c == '$' } + + /** Safe version of `getSimpleName` that works around a bug in Scala compilers 2.11, 2.12. + * This method is only used for debugging purposes. + * @see https://github.com/scala/bug/issues/5425 + */ def safeSimpleName: String = { if (cl.getEnclosingClass == null) return cl.getSimpleName val simpleName = cl.getName.substring(cl.getEnclosingClass.getName.length) diff --git a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala index 57ce44d5b0..6a2b8635c9 100644 --- a/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala +++ b/common/src/main/scala/sigmastate/kiama/rewriting/Rewriter.scala @@ -11,6 +11,8 @@ package sigmastate.kiama package rewriting +import scala.collection.mutable + /** * Strategy-based term rewriting in the style of Stratego (http://strategoxt.org/). * The implementation here is partially based on the semantics given in "Program @@ -216,13 +218,11 @@ trait Rewriter { */ object Duplicator { - import com.google.common.base.Function - import com.google.common.cache.{CacheBuilder, CacheLoader} import java.lang.reflect.Constructor type Duper = (Any, Array[AnyRef]) => Any - object MakeDuper extends Function[Class[_], Duper] { + object MakeDuper extends (Class[_] => Duper) { def apply(clazz : Class[_]) : Duper = try { @@ -280,12 +280,25 @@ trait Rewriter { } - val cache = CacheBuilder.newBuilder.weakKeys.build( - CacheLoader.from(MakeDuper) - ) + private val cache = mutable.HashMap.empty[Class[_], Duper] + /** Obtains a duper for the given class lazily. and memoize it in the `cache` map. + * This is the simplest solution, but not the most efficient for concurrent access. + */ + def getDuper(clazz: Class[_]): Duper = synchronized { // TODO optimize: avoid global sync + val duper = cache.get(clazz) match { + case Some(d) => d + case None => + val d = MakeDuper(clazz) + cache.put(clazz, d) + d + } + duper + } + def apply[T <: Product](t : T, children : Array[AnyRef]) : T = { - val duper = cache.get(t.getClass) + val clazz = t.getClass + val duper = getDuper(clazz) duper(t, children).asInstanceOf[T] } diff --git a/common/src/test/scala/scalan/BaseTests.scala b/common/src/test/scala/scalan/BaseTests.scala index 905adda285..64a8c7f615 100644 --- a/common/src/test/scala/scalan/BaseTests.scala +++ b/common/src/test/scala/scalan/BaseTests.scala @@ -1,27 +1,30 @@ package scalan +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.funspec.AnyFunSpec + import scala.language.implicitConversions -import org.scalatest.words.ResultOfStringPassedToVerb -import org.scalatest.{FlatSpec, _} +import org.scalatest.verbs.ResultOfStringPassedToVerb +import org.scalatest.funsuite.AnyFunSuite /** * Standard base class for most test suites. See BaseNestedTests and BaseShouldTests for alternatives * * See http://doc.scalatest.org/2.2.4/#org.scalatest.FunSuite. */ -abstract class BaseTests extends FunSuite with TestUtils +abstract class BaseTests extends AnyFunSuite with TestUtils /** * Standard base class for test suites with nested tests. * * See http://doc.scalatest.org/2.2.4/#org.scalatest.FunSpec. */ -abstract class BaseNestedTests extends FunSpec with TestUtils +abstract class BaseNestedTests extends AnyFunSpec with TestUtils /** * See http://doc.scalatest.org/2.2.4/#org.scalatest.FlatSpec. */ -abstract class BaseShouldTests extends FlatSpec with TestUtils { +abstract class BaseShouldTests extends AnyFlatSpec with TestUtils { protected final class InAndIgnoreMethods2(resultOfStringPassedToVerb: ResultOfStringPassedToVerb) { import resultOfStringPassedToVerb.rest diff --git a/common/src/test/scala/scalan/TestUtils.scala b/common/src/test/scala/scalan/TestUtils.scala index 0e1645f71d..a583f590af 100644 --- a/common/src/test/scala/scalan/TestUtils.scala +++ b/common/src/test/scala/scalan/TestUtils.scala @@ -2,7 +2,8 @@ package scalan import scalan.util.FileUtil import org.scalactic.TripleEquals -import org.scalatest.{Inside, Matchers, TestSuite} +import org.scalatest.matchers.should.Matchers +import org.scalatest.{Inside, TestSuite} import scalan.util.StringUtil.StringUtilExtensions /** diff --git a/common/src/test/scala/sigmastate/VersionTestingProperty.scala b/common/src/test/scala/sigmastate/VersionTestingProperty.scala index f6d8b6c400..bfa6cace28 100644 --- a/common/src/test/scala/sigmastate/VersionTestingProperty.scala +++ b/common/src/test/scala/sigmastate/VersionTestingProperty.scala @@ -1,13 +1,14 @@ package sigmastate import org.scalactic.source.Position -import org.scalatest.{PropSpec, Tag} +import org.scalatest.propspec.AnyPropSpec +import org.scalatest.Tag /** Decorator trait which allows to redefine `property` so that it is executed repeatedly for each valid * [[VersionContext]], which is properly initialized. * Thus, the properties can be versioned using `VersionContext.current`. */ -trait VersionTestingProperty extends PropSpec with VersionTesting { +trait VersionTestingProperty extends AnyPropSpec with VersionTesting { /** Redefine `property` so that testFun is executed repeatedly for each valid * [[VersionContext]] */ diff --git a/core/src/main/scala/scalan/TypeDescs.scala b/core/src/main/scala/scalan/TypeDescs.scala index fb3c276001..97689c169d 100644 --- a/core/src/main/scala/scalan/TypeDescs.scala +++ b/core/src/main/scala/scalan/TypeDescs.scala @@ -233,15 +233,6 @@ abstract class TypeDescs extends Base { self: Scalan => final def unapply[T, E <: Elem[T]](s: Ref[T]): Nullable[E] = Nullable(s.elem.asInstanceOf[E]) - /** Get unique method name suitable to be used as HashMap key. */ - def methodKey(m: Method) = { - val ann = m.getDeclaredAnnotation(classOf[OverloadId]) - if (ann != null) - s"${m.getName}_${ann.value}" - else - m.getName - } - /** Build a mapping between methods of staged class and the corresponding methods of source class. * The methods are related using names. * The computed mapping can be used to project MethodCalls IR nodes back to the corresponding @@ -255,7 +246,7 @@ abstract class TypeDescs extends Base { self: Scalan => def declaredMethods(cls: Class[_], srcCls: Class[_], methodNames: Set[String]): Seq[(Method, MethodDesc)] = { val rmethods = cls.getDeclaredMethods.filter(m => methodNames.contains(m.getName)) val smethods = srcCls.getDeclaredMethods.filter(m => methodNames.contains(m.getName)) - val mapping = CollectionUtil.joinSeqs(rmethods, smethods)(methodKey, methodKey) + val mapping = CollectionUtil.joinSeqs(rmethods, smethods)(_.getName, _.getName) mapping.map { case (rm, sm) => (rm, RMethodDesc(sm)) }.toSeq @@ -273,7 +264,7 @@ abstract class TypeDescs extends Base { self: Scalan => val specCls = wrapSpec.getClass val wMethods = wcls.getDeclaredMethods.filter(m => methodNames.contains(m.getName)) val specMethods = specCls.getDeclaredMethods.filter(m => methodNames.contains(m.getName)) - val mapping = CollectionUtil.joinSeqs(wMethods, specMethods)(methodKey, methodKey) + val mapping = CollectionUtil.joinSeqs(wMethods, specMethods)(_.getName, _.getName) mapping.map { case (wm, sm) => (wm, WMethodDesc(wrapSpec, sm)) }.toSeq diff --git a/core/src/main/scala/scalan/primitives/Thunks.scala b/core/src/main/scala/scalan/primitives/Thunks.scala index c6d7eb63e1..6f1dc80918 100644 --- a/core/src/main/scala/scalan/primitives/Thunks.scala +++ b/core/src/main/scala/scalan/primitives/Thunks.scala @@ -2,7 +2,7 @@ package scalan.primitives import scala.language.{existentials, implicitConversions} import scalan.compilation.{GraphVizConfig, GraphVizExport} -import scalan.{Liftable => _, _} +import scalan._ import debox.{Set => DSet, Buffer => DBuffer} import debox.cfor diff --git a/library-api/src/main/scala/special/SpecialPredef.scala b/library-api/src/main/scala/special/SpecialPredef.scala index 9c0bbdca99..9152f55d09 100644 --- a/library-api/src/main/scala/special/SpecialPredef.scala +++ b/library-api/src/main/scala/special/SpecialPredef.scala @@ -1,7 +1,7 @@ package special import scala.reflect.ClassTag -import scalan.{Reified, RType} +import scalan.RType object SpecialPredef { def loopUntil[A](s1: A, isMatch: A => Boolean, step: A => A): A = { @@ -15,7 +15,7 @@ object SpecialPredef { def some[A](x: A): Option[A] = Some(x) - @Reified("A") def none[A](implicit tA: RType[A]): Option[A] = Option.empty[A] + def none[A](implicit tA: RType[A]): Option[A] = Option.empty[A] def optionGetOrElse[A](opt: Option[A], default: A): A = opt.getOrElse(default) diff --git a/library-api/src/main/scala/special/collection/Colls.scala b/library-api/src/main/scala/special/collection/Colls.scala index a2b7630e9e..555be23415 100644 --- a/library-api/src/main/scala/special/collection/Colls.scala +++ b/library-api/src/main/scala/special/collection/Colls.scala @@ -322,7 +322,7 @@ trait CollBuilder { /** Construct a new collection from the given list of arguments. * The arguments should be of the same type for which there should be * an implicit type descriptor at the call site. */ - @Reified("T") def fromItems[T](items: T*)(implicit cT: RType[T]): Coll[T] + def fromItems[T](items: T*)(implicit cT: RType[T]): Coll[T] /** Deconstruct collection of (A,B) pairs into pair of collections. * If `xs` is represented as PairColl, then this is O(1) operation (no data is touched). */ diff --git a/library-api/src/main/scala/special/wrappers/WrappersSpec.scala b/library-api/src/main/scala/special/wrappers/WrappersSpec.scala index baefa6aa3e..0765ba3358 100644 --- a/library-api/src/main/scala/special/wrappers/WrappersSpec.scala +++ b/library-api/src/main/scala/special/wrappers/WrappersSpec.scala @@ -1,8 +1,6 @@ package special.wrappers -import scala.reflect.ClassTag -import special.SpecialPredef -import scalan.{NeverInline, RType, WrapSpec} +import scalan.{RType, WrapSpec} trait WrapSpecBase extends WrapSpec { } @@ -10,14 +8,14 @@ trait WrapSpecBase extends WrapSpec { /** Wrappers spec for Option */ trait OptionWrapSpec extends WrapSpecBase { def get[A](xs: Option[A]): A = xs.get - @NeverInline // TODO codegen: convertion to Thunk is required + // TODO codegen: convertion to Thunk is required def getOrElse[A](xs: Option[A], default: => A): A = xs.getOrElse(default) def map[A,B](xs: Option[A], f: A => B): Option[B] = xs.map(f) def flatMap[A,B](xs: Option[A], f: A => Option[B]): Option[B] = xs.flatMap(f) def filter[A](xs: Option[A], f: A => Boolean): Option[A] = xs.filter(f) def isDefined[A](xs: Option[A]): Boolean = xs.isDefined def isEmpty[A](xs: Option[A]): Boolean = xs.isEmpty - @NeverInline // TODO codegen: fold should have single section, and convertion to Thunk is required + // TODO codegen: fold should have single section, and convertion to Thunk is required def fold[A,B](xs: Option[A], ifEmpty: =>B, f: A => B): B = xs.fold(ifEmpty)(f) }; diff --git a/library-impl/src/main/scala/special/collection/CollsOverArrays.scala b/library-impl/src/main/scala/special/collection/CollsOverArrays.scala index 97ef53ed17..6f7c87695d 100644 --- a/library-impl/src/main/scala/special/collection/CollsOverArrays.scala +++ b/library-impl/src/main/scala/special/collection/CollsOverArrays.scala @@ -1,13 +1,9 @@ package special.collection import java.util -import java.util.Objects -import special.SpecialPredef - -import scala.reflect.ClassTag import scalan._ import scalan.util.CollectionUtil -import scalan.{RType, Reified} +import scalan.RType import Helpers._ import debox.Buffer import scalan.RType._ @@ -187,7 +183,6 @@ class CollOverArrayBuilder extends CollBuilder { builder => pairCollFromArrays(resA, resB)(tA, tB) } - @Reified("T") override def fromItems[T](items: T*)(implicit cT: RType[T]): Coll[T] = cT match { case pt: PairType[a,b] => val tA = pt.tFst diff --git a/library/src/main/scala/special/collection/CollsUnit.scala b/library/src/main/scala/special/collection/CollsUnit.scala index 5571d4b8f6..f43e31e689 100644 --- a/library/src/main/scala/special/collection/CollsUnit.scala +++ b/library/src/main/scala/special/collection/CollsUnit.scala @@ -6,7 +6,7 @@ package special.collection { import CollBuilder._; import PairColl._; import WOption._; - @ContainerType @FunctorType @Liftable @WithMethodCallRecognizers trait Coll[A] extends Def[Coll[A]] { + trait Coll[A] extends Def[Coll[A]] { implicit def eA: Elem[A]; def builder: Ref[CollBuilder]; def length: Ref[Int]; @@ -25,22 +25,22 @@ package special.collection { def indices: Ref[Coll[Int]]; def flatMap[B](f: Ref[scala.Function1[A, Coll[B]]]): Ref[Coll[B]]; def segmentLength(p: Ref[scala.Function1[A, Boolean]], from: Ref[Int]): Ref[Int]; - @NeverInline def find(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]] = delayInvoke; + def find(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]] = delayInvoke; def indexWhere(p: Ref[scala.Function1[A, Boolean]], from: Ref[Int]): Ref[Int]; - @NeverInline def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = delayInvoke; + def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = delayInvoke; def lastIndexWhere(p: Ref[scala.Function1[A, Boolean]], end: Ref[Int]): Ref[Int]; def take(n: Ref[Int]): Ref[Coll[A]]; def patch(from: Ref[Int], patch: Ref[Coll[A]], replaced: Ref[Int]): Ref[Coll[A]]; def updated(index: Ref[Int], elem: Ref[A]): Ref[Coll[A]]; def updateMany(indexes: Ref[Coll[Int]], values: Ref[Coll[A]]): Ref[Coll[A]]; def unionSet(that: Ref[Coll[A]]): Ref[Coll[A]]; - @NeverInline def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke; - @NeverInline def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke; + def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke; + def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke; def slice(from: Ref[Int], until: Ref[Int]): Ref[Coll[A]]; def append(other: Ref[Coll[A]]): Ref[Coll[A]]; def reverse: Ref[Coll[A]] }; - @WithMethodCallRecognizers trait PairColl[L, R] extends Coll[scala.Tuple2[L, R]] { + trait PairColl[L, R] extends Coll[scala.Tuple2[L, R]] { implicit def eL: Elem[L]; implicit def eR: Elem[R]; def ls: Ref[Coll[L]]; @@ -48,9 +48,9 @@ package special.collection { def mapFirst[T1](f: Ref[scala.Function1[L, T1]]): Ref[Coll[scala.Tuple2[T1, R]]]; def mapSecond[T1](f: Ref[scala.Function1[R, T1]]): Ref[Coll[scala.Tuple2[L, T1]]] }; - @Liftable @WithMethodCallRecognizers trait CollBuilder extends Def[CollBuilder] { + trait CollBuilder extends Def[CollBuilder] { def pairColl[A, B](as: Ref[Coll[A]], bs: Ref[Coll[B]]): Ref[PairColl[A, B]]; - @Reified(value = "T") def fromItems[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]]; + def fromItems[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]]; def unzip[A, B](xs: Ref[Coll[scala.Tuple2[A, B]]]): Ref[scala.Tuple2[Coll[A], Coll[B]]]; def xor(left: Ref[Coll[Byte]], right: Ref[Coll[Byte]]): Ref[Coll[Byte]]; def replicate[T](n: Ref[Int], v: Ref[T]): Ref[Coll[T]]; diff --git a/library/src/main/scala/wrappers/scala/WOptions.scala b/library/src/main/scala/wrappers/scala/WOptions.scala index 02b9082aa0..34c7a26035 100644 --- a/library/src/main/scala/wrappers/scala/WOptions.scala +++ b/library/src/main/scala/wrappers/scala/WOptions.scala @@ -4,16 +4,16 @@ package wrappers.scala { import special.wrappers.WrappersModule trait WOptions extends Base { self: WrappersModule => - @External("Option") @ContainerType @FunctorType @Liftable @WithMethodCallRecognizers trait WOption[A] extends Def[WOption[A]] { + trait WOption[A] extends Def[WOption[A]] { implicit def eA: Elem[A]; - @External def fold[B](ifEmpty: Ref[Thunk[B]], f: Ref[scala.Function1[A, B]]): Ref[B]; - @External def isEmpty: Ref[Boolean]; - @External def isDefined: Ref[Boolean]; - @External def filter(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]]; - @External def flatMap[B](f: Ref[scala.Function1[A, WOption[B]]]): Ref[WOption[B]]; - @External def map[B](f: Ref[scala.Function1[A, B]]): Ref[WOption[B]]; - @External def getOrElse[B](default: Ref[Thunk[B]]): Ref[B]; - @External def get: Ref[A] + def fold[B](ifEmpty: Ref[Thunk[B]], f: Ref[scala.Function1[A, B]]): Ref[B]; + def isEmpty: Ref[Boolean]; + def isDefined: Ref[Boolean]; + def filter(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]]; + def flatMap[B](f: Ref[scala.Function1[A, WOption[B]]]): Ref[WOption[B]]; + def map[B](f: Ref[scala.Function1[A, B]]): Ref[WOption[B]]; + def getOrElse[B](default: Ref[Thunk[B]]): Ref[B]; + def get: Ref[A] }; trait WOptionCompanion } diff --git a/library/src/main/scala/wrappers/scalan/WRTypes.scala b/library/src/main/scala/wrappers/scalan/WRTypes.scala index 26566be4a7..07795cdada 100644 --- a/library/src/main/scala/wrappers/scalan/WRTypes.scala +++ b/library/src/main/scala/wrappers/scalan/WRTypes.scala @@ -13,9 +13,9 @@ package wrappers.scalan { trait WRTypes extends Base { self: WrappersModule => import WRType._; - @External("RType") @Liftable @WithMethodCallRecognizers trait WRType[A] extends Def[WRType[A]] { + trait WRType[A] extends Def[WRType[A]] { implicit def eA: Elem[A]; - @External def name: Ref[String] + def name: Ref[String] }; trait WRTypeCompanion } diff --git a/library/src/main/scala/wrappers/special/WSpecialPredefs.scala b/library/src/main/scala/wrappers/special/WSpecialPredefs.scala index fc7f0c7401..6a5731fa06 100644 --- a/library/src/main/scala/wrappers/special/WSpecialPredefs.scala +++ b/library/src/main/scala/wrappers/special/WSpecialPredefs.scala @@ -6,13 +6,13 @@ package wrappers.special { trait WSpecialPredefs extends Base { self: WrappersModule => import WOption._; import WSpecialPredef._; - @External("SpecialPredef") @WithMethodCallRecognizers trait WSpecialPredef extends Def[WSpecialPredef]; + trait WSpecialPredef extends Def[WSpecialPredef]; trait WSpecialPredefCompanion { - @External def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A]; - @External def none[@Reified A](implicit emA: Elem[A]): Ref[WOption[A]]; - @External def some[A](x: Ref[A]): Ref[WOption[A]]; - @External def cast[@Reified T](v: Ref[Any])(implicit emT: Elem[T]): Ref[WOption[T]]; - @External def loopUntil[A](s1: Ref[A], isMatch: Ref[scala.Function1[A, Boolean]], step: Ref[scala.Function1[A, A]]): Ref[A] + def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A]; + def none[A](implicit emA: Elem[A]): Ref[WOption[A]]; + def some[A](x: Ref[A]): Ref[WOption[A]]; + def cast[T](v: Ref[Any])(implicit emT: Elem[T]): Ref[WOption[T]]; + def loopUntil[A](s1: Ref[A], isMatch: Ref[scala.Function1[A, Boolean]], step: Ref[scala.Function1[A, A]]): Ref[A] } } } \ No newline at end of file diff --git a/library/src/test/scala/special/collections/CollsTests.scala b/library/src/test/scala/special/collections/CollsTests.scala index b22822e2aa..b8a8339276 100644 --- a/library/src/test/scala/special/collections/CollsTests.scala +++ b/library/src/test/scala/special/collections/CollsTests.scala @@ -2,7 +2,8 @@ package special.collections import org.scalacheck.Gen import org.scalatest.exceptions.TestFailedException -import org.scalatest.{Matchers, PropSpec} +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import scalan._ import sigmastate.{VersionContext, VersionTestingProperty} @@ -10,7 +11,7 @@ import special.collection.{Coll, CollOverArray, PairOfCols} import scala.language.{existentials, implicitConversions} -class CollsTests extends PropSpec with ScalaCheckPropertyChecks with Matchers with CollGens with VersionTestingProperty { testSuite => +class CollsTests extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with CollGens with VersionTestingProperty { testSuite => import Gen._ import special.collection.ExtensionMethods._ diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index 38ef31700c..a6864a3302 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -14,8 +14,6 @@ import scala.util.Try * which is used for all cryptographic operations). * So it is globally and implicitly used in all methods. * */ -@scalan.Liftable -@WithMethodCallRecognizers trait BigInt { /** Convert this BigInt value to Byte. * @throws ArithmeticException if overflow happens. @@ -98,7 +96,7 @@ trait BigInt { * @return { @code this + that} */ def add(that: BigInt): BigInt - @Internal def +(that: BigInt): BigInt = add(that) + def +(that: BigInt): BigInt = add(that) /** Returns a BigInt whose value is {@code (this - that)}. * @@ -106,7 +104,7 @@ trait BigInt { * @return { @code this - that} */ def subtract(that: BigInt): BigInt - @Internal def -(that: BigInt): BigInt = subtract(that) + def -(that: BigInt): BigInt = subtract(that) /** Returns a BigInt whose value is {@code (this * that)}. * @@ -116,7 +114,7 @@ trait BigInt { * @return { @code this * that} */ def multiply(that: BigInt): BigInt - @Internal def *(that: BigInt): BigInt = multiply(that) + def *(that: BigInt): BigInt = multiply(that) /** Returns a BigInt whose value is {@code (this / that)}. * @@ -125,7 +123,7 @@ trait BigInt { * @throws ArithmeticException if { @code that} is zero. */ def divide(that: BigInt): BigInt - @Internal def /(that: BigInt): BigInt = divide(that) + def /(that: BigInt): BigInt = divide(that) /** * Returns a BigInt whose value is {@code (this mod m}). This method @@ -138,7 +136,7 @@ trait BigInt { * @see #remainder */ def mod(m: BigInt): BigInt - @Internal def %(m: BigInt): BigInt = mod(m) + def %(m: BigInt): BigInt = mod(m) /** * Returns a BigInt whose value is {@code (this % that)}. @@ -181,7 +179,7 @@ trait BigInt { * @return `this & that` */ def and(that: BigInt): BigInt - @Internal def &(that: BigInt): BigInt = and(that) + def &(that: BigInt): BigInt = and(that) /** Returns a BigInteger whose value is `(this | that)`. (This * method returns a negative BigInteger if and only if either `this` or `that`` is @@ -191,13 +189,11 @@ trait BigInt { * @return `this | that` */ def or(that: BigInt): BigInt - @Internal def |(that: BigInt): BigInt = or(that) + def |(that: BigInt): BigInt = or(that) } /** Base class for points on elliptic curves. */ -@scalan.Liftable -@WithMethodCallRecognizers trait GroupElement { /** Checks if the provided element is an identity element. */ def isIdentity: Boolean @@ -224,8 +220,6 @@ trait GroupElement { } /** Proposition which can be proven and verified by sigma protocol. */ -@scalan.Liftable -@WithMethodCallRecognizers trait SigmaProp { def isValid: Boolean /** Serialized bytes of this sigma proposition taken as ErgoTree and then serialized. */ @@ -233,26 +227,14 @@ trait SigmaProp { /** Logical AND between this SigmaProp and other SigmaProp. * This constructs a new CAND node of sigma tree with two children. */ - @OverloadId("and_sigma") def &&(other: SigmaProp): SigmaProp - - /** Logical AND between this `SigmaProp` and `Boolean` value on the right. - * The boolean value will be wrapped into `SigmaProp` using `sigmaProp` function. - * This constructs a new CAND node of sigma tree with two children. */ - @OverloadId("and_bool") def &&(other: Boolean): SigmaProp + def &&(other: SigmaProp): SigmaProp /** Logical OR between this SigmaProp and other SigmaProp. * This constructs a new COR node of sigma tree with two children. */ - @OverloadId("or_sigma") def ||(other: SigmaProp): SigmaProp - - /** Logical OR between this `SigmaProp` and `Boolean` value on the right. - * The boolean value will be wrapped into `SigmaProp` using `sigmaProp` function. - * This constructs a new COR node of sigma tree with two children. */ - @OverloadId("or_bool") def ||(other: Boolean): SigmaProp + def ||(other: SigmaProp): SigmaProp } /** Represents any value paired with type descriptor. */ -@scalan.Liftable -@WithMethodCallRecognizers trait AnyValue { /** The data value wrapped by this instance. */ def value: Any @@ -263,8 +245,6 @@ trait AnyValue { /** Runtime representation of Ergo boxes used during execution of ErgoTree operations. * @see [[org.ergoplatform.ErgoBox]] */ -@scalan.Liftable -@WithMethodCallRecognizers trait Box { /** Blake2b256 hash of this box's content, basically equals to `blake2b256(bytes)` */ def id: Coll[Byte] @@ -341,32 +321,32 @@ trait Box { * different from cT. * @since 2.0 */ - def getReg[@Reified T](i: Int)(implicit cT: RType[T]): Option[T] + def getReg[T](i: Int)(implicit cT: RType[T]): Option[T] /** Mandatory: Monetary value, in Ergo tokens */ - def R0[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](0) + def R0[T](implicit cT:RType[T]): Option[T] = this.getReg[T](0) /** Mandatory: Guarding script */ - def R1[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](1) + def R1[T](implicit cT:RType[T]): Option[T] = this.getReg[T](1) /** Mandatory: Secondary tokens */ - def R2[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](2) + def R2[T](implicit cT:RType[T]): Option[T] = this.getReg[T](2) /** Mandatory: Reference to transaction and output id where the box was created */ - def R3[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](3) + def R3[T](implicit cT:RType[T]): Option[T] = this.getReg[T](3) /** Non-mandatory register */ - def R4[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](4) + def R4[T](implicit cT:RType[T]): Option[T] = this.getReg[T](4) /** Non-mandatory register */ - def R5[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](5) + def R5[T](implicit cT:RType[T]): Option[T] = this.getReg[T](5) /** Non-mandatory register */ - def R6[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](6) + def R6[T](implicit cT:RType[T]): Option[T] = this.getReg[T](6) /** Non-mandatory register */ - def R7[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](7) + def R7[T](implicit cT:RType[T]): Option[T] = this.getReg[T](7) /** Non-mandatory register */ - def R8[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](8) + def R8[T](implicit cT:RType[T]): Option[T] = this.getReg[T](8) /** Non-mandatory register */ - def R9[@Reified T](implicit cT:RType[T]): Option[T] = this.getReg[T](9) + def R9[T](implicit cT:RType[T]): Option[T] = this.getReg[T](9) /** Secondary tokens */ def tokens: Coll[(Coll[Byte], Long)] @@ -384,9 +364,8 @@ trait Box { * @return result of the script execution in the current context * @since Mainnet */ - def executeFromRegister[@Reified T](regId: Byte)(implicit cT:RType[T]): T + def executeFromRegister[T](regId: Byte)(implicit cT:RType[T]): T - @Internal override def toString = s"Box(id=$id; value=$value; regs=$registers)" } @@ -399,7 +378,6 @@ trait Box { * * This interface is used as runtime representation of the AvlTree type of ErgoTree. */ -@scalan.Liftable trait AvlTree { /** Returns digest of the state represented by this tree. * Authenticated tree digest = root hash bytes ++ tree height @@ -554,7 +532,6 @@ trait AvlTreeVerifier { /** Only header fields that can be predicted by a miner. * @since 2.0 */ -@scalan.Liftable trait PreHeader { // Testnet2 /** Block version, to be increased on every soft and hardfork. */ def version: Byte @@ -582,7 +559,6 @@ trait PreHeader { // Testnet2 /** Represents data of the block header available in Sigma propositions. * @since 2.0 */ -@scalan.Liftable trait Header { /** Bytes representation of ModifierId of this Header */ def id: Coll[Byte] @@ -636,8 +612,6 @@ trait Header { /** Runtime representation of Context ErgoTree type. * Represents data available in Sigma language using `CONTEXT` global variable. */ -@scalan.Liftable -@WithMethodCallRecognizers trait Context { def builder: SigmaDslBuilder @@ -742,12 +716,9 @@ trait Context { def currentErgoTreeVersion: Byte } -@scalan.Liftable trait SigmaContract { def builder: SigmaDslBuilder - @NeverInline - @Reified("T") def Collection[T](items: T*)(implicit cT: RType[T]): Coll[T] = this.builder.Colls.fromItems[T](items:_*) /** !!! all methods should delegate to builder */ @@ -778,7 +749,6 @@ trait SigmaContract { def decodePoint(encoded: Coll[Byte]): GroupElement = this.builder.decodePoint(encoded) - @Reified("T") def substConstants[T](scriptBytes: Coll[Byte], positions: Coll[Int], newValues: Coll[T]): Coll[Byte] = this.builder.substConstants(scriptBytes, positions, newValues) @@ -794,8 +764,6 @@ trait SigmaContract { * * @see SGlobal.WrappedType, CostingSigmaDslBuilder */ -@scalan.Liftable -@WithMethodCallRecognizers trait SigmaDslBuilder { /** Access to collection operations. */ @@ -886,7 +854,6 @@ trait SigmaDslBuilder { * @param newValues new values to be injected into the corresponding positions in ErgoTree.constants array * @return original scriptBytes array where only specified constants are replaced and all other bytes remain exactly the same */ - @Reified("T") def substConstants[T](scriptBytes: Coll[Byte], positions: Coll[Int], newValues: Coll[T]): Coll[Byte] /** Decodes the given bytes to the corresponding GroupElement using default serialization. @@ -896,10 +863,10 @@ trait SigmaDslBuilder { def decodePoint(encoded: Coll[Byte]): GroupElement /** Create DSL big integer from existing `java.math.BigInteger`*/ - @Internal def BigInt(n: BigInteger): BigInt + def BigInt(n: BigInteger): BigInt /** Extract `java.math.BigInteger` from DSL's `BigInt` type*/ - @Internal def toBigInteger(n: BigInt): BigInteger + def toBigInteger(n: BigInt): BigInteger /** Construct a new authenticated dictionary with given parameters and tree root digest. */ def avlTree(operationFlags: Byte, digest: Coll[Byte], keyLength: Int, valueLengthOpt: Option[Int]): AvlTree diff --git a/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala index 5634a05d6d..5bd2ad784b 100644 --- a/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala +++ b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala @@ -3,7 +3,7 @@ package special.sigma { import scalan._ trait SigmaDsl extends Base { self: SigmaLibrary => - @Liftable @WithMethodCallRecognizers trait BigInt extends Def[BigInt] { + trait BigInt extends Def[BigInt] { def toByte: Ref[Byte]; def toShort: Ref[Short]; def toInt: Ref[Int]; @@ -28,28 +28,24 @@ package special.sigma { def max(that: Ref[BigInt]): Ref[BigInt]; def negate: Ref[BigInt] }; - @Liftable @WithMethodCallRecognizers trait GroupElement extends Def[GroupElement] { + trait GroupElement extends Def[GroupElement] { def isInfinity: Ref[Boolean]; def exp(k: Ref[BigInt]): Ref[GroupElement]; def multiply(that: Ref[GroupElement]): Ref[GroupElement]; def negate: Ref[GroupElement]; def getEncoded: Ref[Coll[Byte]] }; - @Liftable @WithMethodCallRecognizers trait SigmaProp extends Def[SigmaProp] { + trait SigmaProp extends Def[SigmaProp] { def isValid: Ref[Boolean]; def propBytes: Ref[Coll[Byte]]; - @OverloadId(value = "and_sigma") def &&(other: Ref[SigmaProp]): Ref[SigmaProp]; - // manual fix - @OverloadId(value = "and_bool") def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp]; - @OverloadId(value = "or_sigma") def ||(other: Ref[SigmaProp]): Ref[SigmaProp]; - // manual fix - @OverloadId(value = "or_bool") def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp]; + def &&(other: Ref[SigmaProp]): Ref[SigmaProp]; + def ||(other: Ref[SigmaProp]): Ref[SigmaProp]; }; - @Liftable @WithMethodCallRecognizers trait AnyValue extends Def[AnyValue] { + trait AnyValue extends Def[AnyValue] { def value: Ref[Any]; def tVal: Ref[WRType[Any]] }; - @Liftable @WithMethodCallRecognizers trait Box extends Def[Box] { + trait Box extends Def[Box] { def id: Ref[Coll[Byte]]; def value: Ref[Long]; def propositionBytes: Ref[Coll[Byte]]; @@ -71,7 +67,7 @@ package special.sigma { def creationInfo: Ref[scala.Tuple2[Int, Coll[Byte]]]; def executeFromRegister[T](regId: Ref[Byte])(implicit cT: Elem[T]): Ref[T] }; - @Liftable trait AvlTree extends Def[AvlTree] { + trait AvlTree extends Def[AvlTree] { def digest: Ref[Coll[Byte]]; def enabledOperations: Ref[Byte]; def keyLength: Ref[Int]; @@ -88,7 +84,7 @@ package special.sigma { def update(operations: Ref[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]]; def remove(operations: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] }; - @Liftable trait PreHeader extends Def[PreHeader] { + trait PreHeader extends Def[PreHeader] { def version: Ref[Byte]; def parentId: Ref[Coll[Byte]]; def timestamp: Ref[Long]; @@ -97,7 +93,7 @@ package special.sigma { def minerPk: Ref[GroupElement]; def votes: Ref[Coll[Byte]] }; - @Liftable trait Header extends Def[Header] { + trait Header extends Def[Header] { def id: Ref[Coll[Byte]]; def version: Ref[Byte]; def parentId: Ref[Coll[Byte]]; @@ -114,7 +110,7 @@ package special.sigma { def powDistance: Ref[BigInt]; def votes: Ref[Coll[Byte]] }; - @Liftable @WithMethodCallRecognizers trait Context extends Def[Context] { + trait Context extends Def[Context] { def builder: Ref[SigmaDslBuilder]; def OUTPUTS: Ref[Coll[Box]]; def INPUTS: Ref[Coll[Box]]; @@ -129,7 +125,7 @@ package special.sigma { def getVar[T](id: Ref[Byte])(implicit cT: Elem[T]): Ref[WOption[T]]; def vars: Ref[Coll[AnyValue]] }; - @Liftable @WithMethodCallRecognizers trait SigmaDslBuilder extends Def[SigmaDslBuilder] { + trait SigmaDslBuilder extends Def[SigmaDslBuilder] { def Colls: Ref[CollBuilder]; def verifyZK(cond: Ref[Thunk[SigmaProp]]): Ref[Boolean]; def atLeast(bound: Ref[Int], props: Ref[Coll[SigmaProp]]): Ref[SigmaProp]; @@ -147,7 +143,7 @@ package special.sigma { def proveDlog(g: Ref[GroupElement]): Ref[SigmaProp]; def proveDHTuple(g: Ref[GroupElement], h: Ref[GroupElement], u: Ref[GroupElement], v: Ref[GroupElement]): Ref[SigmaProp]; def groupGenerator: Ref[GroupElement]; - @Reified(value = "T") def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]]): Ref[Coll[Byte]]; + def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]]): Ref[Coll[Byte]]; def decodePoint(encoded: Ref[Coll[Byte]]): Ref[GroupElement]; def avlTree(operationFlags: Ref[Byte], digest: Ref[Coll[Byte]], keyLength: Ref[Int], valueLengthOpt: Ref[WOption[Int]]): Ref[AvlTree]; def xor(l: Ref[Coll[Byte]], r: Ref[Coll[Byte]]): Ref[Coll[Byte]] diff --git a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala index efdbd3fc23..8195aed696 100644 --- a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -908,14 +908,6 @@ object SigmaProp extends EntityObject("SigmaProp") { true, false, element[SigmaProp])) } - // manual fix && - override def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - SigmaPropClass.getMethod("$amp$amp", classOf[Sym], classOf[Overloaded1]), - Array[AnyRef](other, o), - true, false, element[SigmaProp])) - } - // manual fix || override def ||(other: Ref[SigmaProp]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, @@ -923,14 +915,6 @@ object SigmaProp extends EntityObject("SigmaProp") { Array[AnyRef](other), true, false, element[SigmaProp])) } - - // manual fix || - override def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - SigmaPropClass.getMethod("$bar$bar", classOf[Sym], classOf[Overloaded1]), - Array[AnyRef](other, o), - true, false, element[SigmaProp])) - } } implicit object LiftableSigmaProp @@ -978,14 +962,6 @@ object SigmaProp extends EntityObject("SigmaProp") { true, true, element[SigmaProp])) } - // manual fix && - def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(source, - SigmaPropClass.getMethod("$amp$amp", classOf[Sym], classOf[Overloaded1]), - Array[AnyRef](other, o), - true, true, element[SigmaProp])) - } - // manual fix || def ||(other: Ref[SigmaProp]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, @@ -994,28 +970,6 @@ object SigmaProp extends EntityObject("SigmaProp") { true, true, element[SigmaProp])) } - // manual fix || - def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(source, - SigmaPropClass.getMethod("$bar$bar", classOf[Sym], classOf[Overloaded1]), - Array[AnyRef](other, o), - true, true, element[SigmaProp])) - } - - def lazyAnd(other: Ref[Thunk[SigmaProp]]): Ref[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(source, - SigmaPropClass.getMethod("lazyAnd", classOf[Sym]), - Array[AnyRef](other), - true, true, element[SigmaProp])) - } - - def lazyOr(other: Ref[Thunk[SigmaProp]]): Ref[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(source, - SigmaPropClass.getMethod("lazyOr", classOf[Sym]), - Array[AnyRef](other), - true, true, element[SigmaProp])) - } - // manual fix def builder: Ref[SigmaDslBuilder] = { asRep[SigmaDslBuilder](mkMethodCall(source, @@ -1040,7 +994,7 @@ object SigmaProp extends EntityObject("SigmaProp") { override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ Elem.declaredMethods(classOf[SigmaProp], classOf[SSigmaProp], Set( - "isValid", "propBytes", "$amp$amp", "$amp$amp", "$bar$bar", "$bar$bar" + "isValid", "propBytes", "$amp$amp", "$bar$bar" )) } } @@ -1084,7 +1038,7 @@ object SigmaProp extends EntityObject("SigmaProp") { object and_sigma_&& { def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = d match { - case MethodCall(receiver, method, args, _) if method.getName == "$amp$amp" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "and_sigma" } => + case MethodCall(receiver, method, args, _) if method.getName == "$amp$amp" && receiver.elem.isInstanceOf[SigmaPropElem[_]] => val res = (receiver, args(0)) Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[SigmaProp])]] case _ => Nullable.None @@ -1092,35 +1046,15 @@ object SigmaProp extends EntityObject("SigmaProp") { def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = unapply(exp.node) } - object and_bool_&& { - def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[Boolean])] = d match { - case MethodCall(receiver, method, args, _) if method.getName == "$amp$amp" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "and_bool" } => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[Boolean])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[Boolean])] = unapply(exp.node) - } - object or_sigma_|| { def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = d match { - case MethodCall(receiver, method, args, _) if method.getName == "$bar$bar" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "or_sigma" } => + case MethodCall(receiver, method, args, _) if method.getName == "$bar$bar" && receiver.elem.isInstanceOf[SigmaPropElem[_]] => val res = (receiver, args(0)) Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[SigmaProp])]] case _ => Nullable.None } def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = unapply(exp.node) } - - object or_bool_|| { - def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[Boolean])] = d match { - case MethodCall(receiver, method, args, _) if method.getName == "$bar$bar" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "or_bool" } => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[Boolean])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[Boolean])] = unapply(exp.node) - } } object SigmaPropCompanionMethods { diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala index 1a2b5b2878..251df04e1f 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala @@ -1,6 +1,8 @@ package org.ergoplatform -import com.google.common.primitives.Ints +import java.util + +import scorex.utils.Ints import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix import scorex.crypto.hash.{Digest32, Blake2b256} import scorex.util.encode.Base58 diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala index f1c883ab60..256f643d93 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -1,6 +1,6 @@ package org.ergoplatform -import com.google.common.primitives.{Ints, Shorts} +import scorex.utils.{Ints, Shorts} import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADKey diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index 09912c7588..76bafd2fa2 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -1,6 +1,6 @@ package sigmastate.eval -import com.google.common.primitives.{Ints, Longs} +import scorex.utils.{Ints, Longs} import java.math.BigInteger import java.util.Arrays @@ -143,19 +143,11 @@ case class CSigmaProp(sigmaTree: SigmaBoolean) extends SigmaProp with WrapperOf[ CSigmaProp(CAND.normalized(Array(sigmaTree, other.sigmaTree))) } - // TODO refactor: remove this (it shouldn't be used in interpreter) - override def &&(other: Boolean): SigmaProp = - CSigmaProp(CAND.normalized(Array(sigmaTree, TrivialProp(other)))) - override def ||(other: SigmaProp): SigmaProp = other match { case other: CSigmaProp => CSigmaProp(COR.normalized(Array(sigmaTree, other.sigmaTree))) } - // TODO refactor: remove this (it shouldn't be used in interpreter) - override def ||(other: Boolean): SigmaProp = - CSigmaProp(COR.normalized(Array(sigmaTree, TrivialProp(other)))) - override def toString: String = s"SigmaProp(${wrappedValue.showToString})" } diff --git a/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala index 4f8501606f..25f909e8bc 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -319,10 +319,6 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => case OM.isDefined(In(optionSym)) => mkOptionIsDefined(optionSym.asValue[SOption[SType]]) - case SigmaM.and_bool_&&(In(prop), In(cond)) => // TODO refactor: remove or cover by tests: it is never executed - SigmaAnd(Seq(prop.asSigmaProp, mkBoolToSigmaProp(cond.asBoolValue))) - case SigmaM.or_bool_||(In(prop), In(cond)) => // TODO refactor: remove or cover by tests: it is never executed - SigmaOr(Seq(prop.asSigmaProp, mkBoolToSigmaProp(cond.asBoolValue))) case SigmaM.and_sigma_&&(In(p1), In(p2)) => SigmaAnd(Seq(p1.asSigmaProp, p2.asSigmaProp)) case SigmaM.or_sigma_||(In(p1), In(p2)) => diff --git a/sigmastate/src/main/scala/sigmastate/utils/Extensions.scala b/sigmastate/src/main/scala/sigmastate/utils/Extensions.scala index 8d8d8d9927..24ee381108 100644 --- a/sigmastate/src/main/scala/sigmastate/utils/Extensions.scala +++ b/sigmastate/src/main/scala/sigmastate/utils/Extensions.scala @@ -1,6 +1,6 @@ package sigmastate.utils -import com.google.common.primitives.{Ints, Longs, Shorts} +import scorex.utils.{Ints, Longs, Shorts} import sigmastate.eval.SigmaDsl import special.collection.Coll diff --git a/sigmastate/src/test/java/gf2t/GF2_192Test.java b/sigmastate/src/test/java/gf2t/GF2_192Test.java deleted file mode 100644 index f438907efe..0000000000 --- a/sigmastate/src/test/java/gf2t/GF2_192Test.java +++ /dev/null @@ -1,713 +0,0 @@ -/* - By Leonid Reyzin - - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to - */ -package gf2t; - -import org.junit.Test; -import org.junit.runner.RunWith; -import sigmastate.crypto.GF2_192; -import sigmastate.crypto.GF2_192_Poly; - -import java.util.Random; -import java.util.Arrays; - -import static org.junit.Assert.assertFalse; - -@RunWith(ReadableTest.class) -public class GF2_192Test { - - private static class GF2t_slow { - - private long[] x; - - public boolean isOne() { - if (x[0] != 1l) return false; - for (int i = 1; i < x.length; i++) { - if (x[i] != 0l) return false; - } - return true; - } - - public boolean equals(long[] that) { - int i; - for (i = 0; i < Math.min(x.length, that.length); i++) { - if (x[i] != that[i]) - return false; - } - for (; i < x.length; i++) { - if (x[i] != 0) { - return false; - } - } - for (; i < that.length; i++) { - if (that[i] != 0) { - return false; - } - } - return true; - } - - - public static void mulBits(GF2t_slow ret, long[] a, long[] b) { - long[] c = new long[a.length + b.length]; - - - for (int i = 0; i < a.length; i++) { - for (int i1 = 0; i1 < 64; i1++) { - for (int j = 0; j < b.length; j++) { - for (int j1 = 0; j1 < 64; j1++) { - if ((a[i] & (1l << i1)) != 0 && (b[j] & (1l << j1)) != 0) { - int cPosition = i * 64 + i1 + j * 64 + j1; - c[cPosition / 64] ^= 1l << (cPosition % 64); - } - } - } - } - } - ret.x = c; - } - - private static void modReduce(GF2t_slow poly, Modulus mod) { - for (int i = poly.x.length * 64 - 1; i >= mod.degree; i--) { - if ((poly.x[i >> 6] & (1l << (i & 63))) != 0) { - for (int j = 0; j < mod.offset.length; j++) { - int k = i - mod.offset[j]; - poly.x[k >> 6] ^= (1l << (k & 63)); - } - } - } - } - - public String toString() { - String ret = ""; - for (int i = x.length - 1; i >= 0; i--) { - ret += x[i]; - } - return ret; - } - - public static class Modulus { - // represented as an array of bit positions - // where coefficient = 1, counting from degree down - private final int[] offset; - private final int degree; - - Modulus(int[] sparseModulus) { - degree = sparseModulus[0]; - offset = new int[sparseModulus.length]; - offset[0] = 0; - for (int i = 1; i < sparseModulus.length; i++) { - offset[i] = degree - sparseModulus[i]; - } - } - } - } - - private static long[][] testValues = null; - private static GF2_192 zero = new GF2_192(0); - private static GF2_192 one = new GF2_192(1); - private static int[] pentanomial = {192, 7, 2, 1, 0}; - private static GF2t_slow.Modulus m = new GF2t_slow.Modulus(pentanomial); - static {genTestValues();} - private static void genTestValues() { - if (testValues == null) { - testValues = new long[250][]; - - for (int i = 0; i < testValues.length; i++) { - testValues[i] = new long[3]; - } - - - // Test single 1s in every bit position but last - // (1s in last bit position -- i.e., just the value of 1 -- will be tested separately) - int j = 0; - for (int i = 1; i < 64; i++, j++) { - testValues[j][0] = 1L << i; - testValues[j][1] = 0; - testValues[j][2] = 0; - } - for (int i = 0; i < 64; i++, j++) { - testValues[j][0] = 0; - testValues[j][1] = 1L << i; - testValues[j][2] = 0; - } - for (int i = 0; i < 64; i++, j++) { - testValues[j][0] = 0; - testValues[j][1] = 0; - testValues[j][2] = 1L << i; - } - - // Test first word zero, last two words random, - // and first word random, last two words 0 - // and first word random, second word 1, last word 0 - // and last word random, first two words 0 - - Random rand = new Random(); - - for (int i = 0; i < 5; i++, j++) { - testValues[j][0] = 0; - testValues[j][1] = rand.nextLong(); - testValues[j][2] = rand.nextLong(); - } - - for (int i = 0; i < 5; i++, j++) { - testValues[j][0] = rand.nextLong(); - testValues[j][1] = 0; - testValues[j][2] = 0; - } - - - for (int i = 0; i < 5; i++, j++) { - testValues[j][0] = rand.nextLong(); - testValues[j][1] = 1; - testValues[j][2] = 0; - } - - for (int i = 0; i < 5; i++, j++) { - testValues[j][0] = 0; - testValues[j][1] = 1; - testValues[j][2] = rand.nextLong(); - } - - // Test all three words random - while (j < testValues.length) { - testValues[j][0] = rand.nextLong(); - testValues[j][1] = rand.nextLong(); - testValues[j++][2] = rand.nextLong(); - } - } - } - - @Test - public void constructorAndEqualityTest() { - GF2_192 t = new GF2_192(); - long[] r = t.toLongArray(); - assertFalse("Fail: empty constructor.", !t.isZero() || r.length != 3 || r[0] != 0L || r[1] != 0L || r[2] != 0L); - - t = new GF2_192(0); - r = t.toLongArray(); - assertFalse("Fail: constructor on 0 int",!t.isZero() || r.length != 3 || r[0] != 0L || r[1] != 0L || r[2] != 0L); - - t = new GF2_192(1); - r = t.toLongArray(); - assertFalse("Fail: constructor on 1 int", !t.isOne() || r.length != 3 || r[0] != 1L || r[1] != 0L || r[2] != 0L); - - t = new GF2_192(-1); - r = t.toLongArray(); - assertFalse("Fail: constructor on 0xFFFFFFFF int " + t, r[0] != 0xFFFFFFFFL || r[1] != 0L || r[2]!=0L); - - long[] s = new long[3]; - - s[0] = 123345L; - s[1] = 123567891234567L; - s[2] = 487237823242367L; - - t = new GF2_192(s); - - GF2_192 t1 = new GF2_192(t); - - r = t.toLongArray(); - assertFalse("Fail: constructor on long array", r[0] != s[0] || r[1] != s[1] || r[2] != s[2]); - - - r = t1.toLongArray(); - assertFalse ("Fail: copy constructor",r[0] != s[0] || r[1] != s[1] || r[2] != s[2]) ; - - byte[] b = new byte[24]; - for (int i = 0; i < 8; i++) { - b[i] = (byte) (r[0] >>> (i * 8)); - } - - for (int i = 0; i < 8; i++) { - b[i + 8] = (byte) (r[1] >>> (i * 8)); - } - - for (int i = 0; i < 8; i++) { - b[i + 16] = (byte) (r[2] >>> (i * 8)); - } - t = new GF2_192(b); - s = t.toLongArray(); - - assertFalse("Fail: constructor on byte array",r[0] != s[0] || r[1] != s[1] || r[2] != s[2]); - byte [] c = t.toByteArray(); - assertFalse("Fail: toByteArray", !Arrays.equals(b, c)); - - byte [] b2 = new byte[30]; - for (int i=0; i<24; i++) { - b2[i+6]=b[i]; - } - t = new GF2_192(b2, 6); - s = t.toLongArray(); - assertFalse("Fail: constructor on byte array with offset", r[0] != s[0] || r[1] != s[1] || r[2]!=s[2]); - - byte [] b1 = t.toByteArray(); - assertFalse("Fail: toByteArray", !Arrays.equals(b, b1)); - - - byte [] b3 = new byte [40]; - t.toByteArray(b3, 10); - for (int i = 0; i>> (i * 8)); - } - - for (int i = 0; i < 8; i++) { - b[i + 8] = (byte) (r[1] >>> (i * 8)); - } - for (int i = 0; i < 8; i++) { - b[i + 16] = (byte) (r[2] >>> (i * 8)); - } - - - t = new GF2_192(b); - s = t.toLongArray(); - assertFalse("Fail: constructor on byte array of all 1s", r[0] != s[0] || r[1] != s[1] || r[2]!=s[2]); - - b1 = t.toByteArray(); - assertFalse("Fail: toByteArray all 1s", !Arrays.equals(b, b1)); - - b2 = new byte[30]; - for (int i=0; i<24; i++) { - b2[i+6]=b[i]; - } - t = new GF2_192(b2, 6); - s = t.toLongArray(); - assertFalse("Fail: constructor on byte array with offset of all 1s", r[0] != s[0] || r[1] != s[1] || r[2]!=s[2]); - - b1 = t.toByteArray(); - assertFalse("Fail: toByteArray all 1s", !Arrays.equals(b, b1)); - - b3 = new byte [40]; - t.toByteArray(b3, 10); - for (int i = 0; i klass) throws InitializationError { - super(klass); - } - - public static LinkedList splitCamelCaseString(String s) { - LinkedList result = new LinkedList(); - for (String w : s.split("(?> 6) & (1l << (i & 63))) != 0) { + for ( j <- 0 until mod.offset.length ) { + val k = i - mod.offset(j) + poly.x(k >> 6) ^= (1l << (k & 63)) + } + } + } + } + + class Modulus private[crypto](val sparseModulus: Array[Int]) { + // represented as an array of bit positions + // where coefficient = 1, counting from degree down + final private[crypto] var offset: Array[Int] = new Array[Int](sparseModulus.length) + final private[crypto] var degree: Int = sparseModulus(0) + + offset(0) = 0 + for ( i <- 1 until sparseModulus.length ) { + offset(i) = degree - sparseModulus(i) + } + } + } + + private class GF2t_slow { + var x: Array[Long] = null + + def isOne: Boolean = { + if (x(0) != 1l) return false + for ( i <- 1 until x.length ) { + if (x(i) != 0l) return false + } + true + } + + def equals(that: Array[Long]): Boolean = { + var i = 0 + while ( i < Math.min(x.length, that.length) ) { + if (x(i) != that(i)) return false + i += 1 + } + while ( i < x.length ) { + if (x(i) != 0) return false + i += 1 + } + while ( i < that.length ) { + if (that(i) != 0) return false + i += 1 + } + true + } + + override def toString: String = { + var ret = "" + for ( i <- x.length - 1 to 0 by -1 ) { + ret += x(i) + } + ret + } + } + + private var testValues: Array[Array[Long]] = null + private val zero = new GF2_192(0) + private val one = new GF2_192(1) + private val pentanomial = Array(192, 7, 2, 1, 0) + private val m = new GF2t_slow.Modulus(pentanomial) + genTestValues() + + private def genTestValues(): Unit = { + if (testValues == null) { + testValues = new Array[Array[Long]](250) + for ( i <- 0 until testValues.length ) { + testValues(i) = new Array[Long](3) + } + + // Test single 1s in every bit position but last + // (1s in last bit position -- i.e., just the value of 1 -- will be tested separately) + + var j = 0 + var i = 1 + while ( i < 64 ) { + testValues(j)(0) = 1L << i + testValues(j)(1) = 0 + testValues(j)(2) = 0 + i += 1 + j += 1 + } + i = 0 + while ( i < 64 ) { + testValues(j)(0) = 0 + testValues(j)(1) = 1L << i + testValues(j)(2) = 0 + i += 1 + j += 1 + } + i = 0 + while ( i < 64 ) { + testValues(j)(0) = 0 + testValues(j)(1) = 0 + testValues(j)(2) = 1L << i + i += 1 + j += 1 + } + + // Test first word zero, last two words random, + // and first word random, last two words 0 + // and first word random, second word 1, last word 0 + // and last word random, first two words 0 + val rand = new Random + + i = 0 + while ( i < 5 ) { + testValues(j)(0) = 0 + testValues(j)(1) = rand.nextLong + testValues(j)(2) = rand.nextLong + i += 1 + j += 1 + } + i = 0 + while ( i < 5 ) { + testValues(j)(0) = rand.nextLong + testValues(j)(1) = 0 + testValues(j)(2) = 0 + i += 1 + j += 1 + } + i = 0 + while ( i < 5 ) { + testValues(j)(0) = rand.nextLong + testValues(j)(1) = 1 + testValues(j)(2) = 0 + i += 1 + j += 1 + } + + i = 0 + while ( i < 5 ) { + testValues(j)(0) = 0 + testValues(j)(1) = 1 + testValues(j)(2) = rand.nextLong + i += 1 + j += 1 + } + // Test all three words random + while ( j < testValues.length ) { + testValues(j)(0) = rand.nextLong + testValues(j)(1) = rand.nextLong + testValues(j)(2) = rand.nextLong + j += 1 + } + } + } + + property("constructorAndEqualityTest") { + var t = new GF2_192 + var r = t.toLongArray + assertFalse("Fail: empty constructor.", !t.isZero || r.length != 3 || r(0) != 0L || r(1) != 0L || r(2) != 0L) + + t = new GF2_192(0) + r = t.toLongArray + assertFalse("Fail: constructor on 0 int", !t.isZero || r.length != 3 || r(0) != 0L || r(1) != 0L || r(2) != 0L) + + t = new GF2_192(1) + r = t.toLongArray + assertFalse("Fail: constructor on 1 int", !t.isOne || r.length != 3 || r(0) != 1L || r(1) != 0L || r(2) != 0L) + + t = new GF2_192(-1) + r = t.toLongArray + assertFalse("Fail: constructor on 0xFFFFFFFF int " + t, r(0) != 0xFFFFFFFFL || r(1) != 0L || r(2) != 0L) + + var s = new Array[Long](3) + + s(0) = 123345L + s(1) = 123567891234567L + s(2) = 487237823242367L + + t = new GF2_192(s) + var t1 = new GF2_192(t) + + r = t.toLongArray + assertFalse("Fail: constructor on long array", r(0) != s(0) || r(1) != s(1) || r(2) != s(2)) + + r = t1.toLongArray + assertFalse("Fail: copy constructor", r(0) != s(0) || r(1) != s(1) || r(2) != s(2)) + + val b = new Array[Byte](24) + for ( i <- 0 until 8 ) { + b(i) = (r(0) >>> (i * 8)).toByte + } + for ( i <- 0 until 8 ) { + b(i + 8) = (r(1) >>> (i * 8)).toByte + } + for ( i <- 0 until 8 ) { + b(i + 16) = (r(2) >>> (i * 8)).toByte + } + + t = new GF2_192(b) + s = t.toLongArray + assertFalse("Fail: constructor on byte array", + r(0) != s(0) || r(1) != s(1) || r(2) != s(2)) + + val c = t.toByteArray + assertFalse("Fail: toByteArray", !Arrays.equals(b, c)) + + var b2 = new Array[Byte](30) + for ( i <- 0 until 24 ) { + b2(i + 6) = b(i) + } + + t = new GF2_192(b2, 6) + s = t.toLongArray + assertFalse("Fail: constructor on byte array with offset", + r(0) != s(0) || r(1) != s(1) || r(2) != s(2)) + + var b1 = t.toByteArray + assertFalse("Fail: toByteArray", !Arrays.equals(b, b1)) + + var b3 = new Array[Byte](40) + t.toByteArray(b3, 10) + for ( i <- 0 until b.length ) { + assertFalse("Fail: toByteArray with offset", + b3(i + 10) != b(i)) + } + + s(0) = 0xFFFFFFFFFFFFFFFFL + s(1) = 0xFFFFFFFFFFFFFFFFL + s(2) = 0xFFFFFFFFFFFFFFFFL + t = new GF2_192(s) + t1 = new GF2_192(t) + + r = t.toLongArray + assertFalse("Fail: constructor on long array of all 1s", + r(0) != s(0) || r(1) != s(1) || r(2) != s(2)) + + r = t1.toLongArray + assertFalse("Fail: copy constructor", + r(0) != s(0) || r(1) != s(1) || r(2) != s(2)) + + for ( i <- 0 until 8 ) { + b(i) = (r(0) >>> (i * 8)).toByte + } + + for ( i <- 0 until 8 ) { + b(i + 8) = (r(1) >>> (i * 8)).toByte + } + + for ( i <- 0 until 8 ) { + b(i + 16) = (r(2) >>> (i * 8)).toByte + } + + t = new GF2_192(b) + s = t.toLongArray + assertFalse("Fail: constructor on byte array of all 1s", + r(0) != s(0) || r(1) != s(1) || r(2) != s(2)) + + b1 = t.toByteArray + assertFalse("Fail: toByteArray all 1s", !Arrays.equals(b, b1)) + + b2 = new Array[Byte](30) + for ( i <- 0 until 24 ) { + b2(i + 6) = b(i) + } + t = new GF2_192(b2, 6) + s = t.toLongArray + assertFalse("Fail: constructor on byte array with offset of all 1s", + r(0) != s(0) || r(1) != s(1) || r(2) != s(2)) + + b1 = t.toByteArray + assertFalse("Fail: toByteArray all 1s", !Arrays.equals(b, b1)) + + b3 = new Array[Byte](40) + t.toByteArray(b3, 10) + for ( i <- 0 until b.length ) { + assertFalse("Fail: toByteArray all 1s with offset", b3(i + 10) != b(i)) + } + } + + property("pow2To2ToKTest") { + // includes squaring test + val res = new GF2_192 + var z: GF2_192 = null + val maxK = 15 + for ( k <- 0 until maxK ) { + GF2_192.power2To2ToK(res, zero, k) + assertFalse("Fail: power2To2ToK of 0 for k=" + k, !res.isZero) + + z = new GF2_192(zero) + GF2_192.power2To2ToK(z, z, k) + assertFalse("Fail: power2To2ToK of 0 in place for k=" + k, !z.isZero) + + GF2_192.power2To2ToK(res, one, k) + assertFalse("Fail: power2To2ToK of 1 for k=" + k, !res.isOne) + + z = new GF2_192(one) + GF2_192.power2To2ToK(z, z, k) + assertFalse("Fail: power2To2ToK of 1 in place for k=" + k, !z.isOne) + } + + GF2_192.sqr(res, zero) + assertFalse("Fail: sqr of 0", !res.isZero) + + z = new GF2_192(zero) + GF2_192.sqr(z, z) + assertFalse("Fail: sqr of 0 in place", !z.isZero) + + GF2_192.sqr(res, one) + assertFalse("Fail: sqr of 1", !res.isOne) + + z = new GF2_192(one) + GF2_192.sqr(z, z) + assertFalse("Fail: sqr of 1 in place", !z.isOne) + + val res1 = new GF2_192 + val res2 = new GF2_192 + for ( p <- testValues ) { + for ( k <- 0 until maxK ) { + z = new GF2_192(p) + GF2_192.power2To2ToK(res, z, k) + if (k == 0) { + // Ground truth for squaring: self-multiply + GF2_192.mul(res1, z, z) // sqr should equal power2To2ToK with k = 0 + assertFalse("Fail: power2To2To1 " + z, !(res == res1)) + GF2_192.sqr(res2, z) // sqr should equal self-multiply with k = 0 + assertFalse("Fail: sqr for k = " + k + " value = " + z, !(res == res2)) + } + else { + // res1 is the ground truth, computed using smaller values of k than is currently being tested + GF2_192.power2To2ToK(res1, res1, k - 1) + assertFalse("Fail: power2To2ToK for k = " + k + " value = " + z, !(res == res1)) + } + + // Input location = output location tests + GF2_192.power2To2ToK(z, z, k) // power2To2ToK into same location + assertFalse("Fail: power2To2ToK in place for k = " + k + " value = " + new GF2_192(p), !(res == z)) + if (k == 0) { + z = new GF2_192(p) + GF2_192.sqr(z, z) // sqr into same location + assertFalse("Fail: sqr in place " + new GF2_192(p), !(res == z)) + } + } + } + } + + property("specialMultTest") { + val res = new GF2_192 + val res1 = new GF2t_slow + + // Run everything times 0 and 0 times everything + // and everything times 1 and 1 times everything + // where 0 and 1 are GF2_192 + + for ( p <- testValues ) { + var p1 = new GF2_192(p) + GF2_192.mul(res, p1, zero) + assertFalse("Fail: " + p1 + " * 0", !res.isZero) + GF2_192.mul(p1, p1, zero) + assertFalse("Fail: " + p1 + " * 0" + " in place ", !p1.isZero) + p1 = new GF2_192(p) + GF2_192.mul(res, zero, p1) + assertFalse("Fail: 0 * " + p1, !res.isZero) + GF2_192.mul(p1, zero, p1) + assertFalse("Fail: 0 * " + p1 + " in place ", !p1.isZero) + p1 = new GF2_192(p) + GF2_192.mul(res, p1, one) + assertFalse("Fail: " + p1 + " * 1", !(res == p1)) + GF2_192.mul(p1, p1, one) + assertFalse("Fail: " + p1 + " * 1 in place", !(res == p1)) + GF2_192.mul(res, one, p1) + assertFalse("Fail: 1 * " + p1, !(res == p1)) + GF2_192.mul(p1, one, p1) + assertFalse("Fail: 1 * " + p1 + " in place", !(res == p1)) + } + + // Run everything times 0 + // and everything times 1 + // where 0 and 1 are bytes + for ( p <- testValues ) { + val p1 = new GF2_192(p) + GF2_192.mul(res, p1, 1.toByte) + assertFalse("Fail: " + p1 + " * 1 byte ", !(res == p1)) + GF2_192.mul(p1, p1, 1.toByte) + assertFalse("Fail: " + p1 + " * 1 byte in place", !(res == p1)) + GF2_192.mul(res, p1, 0.toByte) + assertFalse("Fail: " + p1 + " * 0 byte", !res.isZero) + GF2_192.mul(p1, p1, 0.toByte) + assertFalse("Fail: " + p1 + " * 0 byte in place", !p1.isZero) + } + + // Run everything times every byte + val temp = new Array[Long](1) + for ( p <- testValues ) { + for ( i <- 2 until 256 ) { + val p1 = new GF2_192(p) + temp(0) = i + GF2_192.mul(res, p1, i.toByte) + GF2t_slow.mulBits(res1, p, temp) + GF2t_slow.modReduce(res1, m) + assertFalse("Fail: " + p1 + " * " + i + " byte", !res1.equals(res.toLongArray)) + GF2_192.mul(p1, p1, i.toByte) + assertFalse("Fail: " + p1 + " * " + i + " byte in place", !(res == p1)) + } + } + } + + property("specialAddTest") { + val res = new GF2_192 + + // Run everything plus 0 and 0 plus everything + // where 0 is GF2_192 + for ( p <- testValues ) { + val p1 = new GF2_192(p) + GF2_192.add(res, p1, zero) + assertFalse(s"Fail: $p1 + 0", !(res == p1)) + GF2_192.add(p1, p1, zero) + assertFalse(s"Fail: $p1 + 0 in place", !(res == p1)) + GF2_192.add(res, zero, p1) + assertFalse(s"Fail: 0 + $p1", !(res == p1)) + GF2_192.add(p1, zero, p1) + assertFalse(s"Fail: $p1 + 0 in place", !(res == p1)) + } + } + + property("generalAddTest") { + val res = new GF2_192 + val res1 = new GF2t_slow + res1.x = new Array[Long](3) + + // Try everything plus everything in the test array + for ( p <- testValues ) { + var p1 = new GF2_192(p) + for ( q <- testValues ) { + val q1 = new GF2_192(q) + GF2_192.add(res, p1, q1) + res1.x(0) = p(0) ^ q(0) + res1.x(1) = p(1) ^ q(1) + res1.x(2) = p(2) ^ q(2) + assertFalse(s"Fail: $p1 + $q1 = $res not $res1", + !res1.equals(res.toLongArray)) + + GF2_192.add(p1, p1, q1) + assertFalse(s"Fail: $p1 + $q1 in place 1 ", !(res == p1)) + + p1 = new GF2_192(p) + GF2_192.add(q1, p1, q1) + assertFalse(s"Fail: $p1 + $q1 in place 2 ", !(res == q1)) + } + } + + // Try everything plus self in the test array, both in place and not, and make sure you get zeros + for ( p <- testValues ) { + val p1 = new GF2_192(p) + GF2_192.add(res, p1, p1) + assertFalse(s"Fail: $p1 + self", !res.isZero) + + GF2_192.add(p1, p1, p1) + assertFalse(s"Fail: $p1 self in place", !p1.isZero) + } + } + + property("generalMultTest") { + val res = new GF2_192 + val res1 = new GF2t_slow + + // Now run everything times everything in the test array + // TODO: speed this up + for ( p <- testValues ) { + var p1 = new GF2_192(p) + for ( q <- testValues ) { + val q1 = new GF2_192(q) + GF2_192.mul(res, p1, q1) + GF2t_slow.mulBits(res1, p, q) + GF2t_slow.modReduce(res1, m) + assertFalse(s"Fail: $p1 * $q1", !res1.equals(res.toLongArray)) + + GF2_192.mul(p1, p1, q1) + assertFalse(s"Fail: $p1 * $q1 in place 1 ", !(res == p1)) + + p1 = new GF2_192(p) + GF2_192.mul(q1, p1, q1) + assertFalse(s"Fail: $p1 * $q1 in place 2 ", !(res == q1)) + } + } + + // Try everything times self in the test array, in place + for ( p <- testValues ) { + val p1 = new GF2_192(p) + GF2_192.sqr(res, p1) + GF2_192.mul(p1, p1, p1) + assertFalse(s"Fail: $p1 * self in place", !(res == p1)) + } + } + + property("inversionTest") { + val res = new GF2_192 + val res2 = new GF2_192 + val res1 = new GF2t_slow + + // Test inversion of 1 + GF2_192.invert(res, one) + assertFalse("Fail: inversion of 1", !res.isOne) + + // Test inversion of everything + for ( p <- testValues ) { + val p1 = new GF2_192(p) + if (!p1.isZero) { + GF2_192.invert(res, p1) + GF2_192.mul(res2, p1, res) + assertFalse(s"Fail: inversion of $p1 self-test ", !res2.isOne) + + GF2t_slow.mulBits(res1, res.toLongArray, p) + GF2t_slow.modReduce(res1, m) + assertFalse(s"Fail: inversion of $p1 GF2t_slow-test", !res1.isOne) + + GF2_192.invert(p1, p1) + assertFalse(s"Fail: inversion of $p1 in place ", !(p1 == res)) + } + } + } + + property("interpolateTest") { + // Test for null inputs, arrays of unequal length, etc. + val optArray: Array[GF2_192] = new Array[GF2_192](2) + optArray(0) = null + optArray(1) = new GF2_192(17) + + var res: GF2_192_Poly = null + val rand: Random = new Random + + // Try with arrays of length 0 + var p = GF2_192_Poly.interpolate( + new Array[Byte](0), new Array[GF2_192](0), new GF2_192(0)) + assertFalse("Zero polynomial should be 0 at 0", !p.evaluate(0.toByte).isZero) + assertFalse("Zero polynomial should be 0 at 5", !p.evaluate(5.toByte).isZero) + + val val17 = new GF2_192(17) + p = GF2_192_Poly.interpolate(new Array[Byte](0), new Array[GF2_192](0), val17) + assertFalse("Constant 17 polynomial should be 17 at 0", !(p.evaluate(0.toByte) == val17)) + assertFalse("Constant 17 polynomial should be 17 at 5", !(p.evaluate(5.toByte) == val17)) + + for ( len <- 1 until 100 ) { + val points = new Array[Byte](len) + val values = new Array[GF2_192](len) + val temp = new Array[Byte](24) + for ( i <- 0 until len ) { + // generate a byte that is not equal to anything in the array nor 0 + var doLoop = true + while (doLoop) { + var b: Byte = 0 + do b = rand.nextInt.toByte while ( b == 0.toByte ) + var j: Int = 0 + var doBreak = false + while (!doBreak && j < i) { + if (b == points(j)) { // detected equality with something in the array + doBreak = true + } else { + j += 1 + } + } + if (j == i) { // did not detect equality with anything in the array + points(i) = b + doLoop = false + } + } + } + for ( i <- 0 until len ) { + rand.nextBytes(temp) + values(i) = new GF2_192(temp) + } + + res = GF2_192_Poly.interpolate(points, values, null) + for ( i <- 0 until len ) { + val t = res.evaluate(points(i)) + assertFalse(s"Interpolation error on length = $len at input point number $i", !(t == values(i))) + } + rand.nextBytes(temp) + val valueAt0 = new GF2_192(temp) + res = GF2_192_Poly.interpolate(points, values, valueAt0) + for ( i <- 0 until len ) { + val t = res.evaluate(points(i)) + assertFalse(s"Interpolation error on length = $len at input point number $i(with optional 0)", !(t == values(i))) + } + val t = res.evaluate(0.toByte) + assertFalse(s"Interpolation error on length = $len at input optional 0", !(t == valueAt0)) + + val b = res.toByteArray(false) + val t1 = GF2_192_Poly.fromByteArray(valueAt0.toByteArray, b) + val b1 = t1.toByteArray(false) + assertFalse( + s"To byte array round trip error ${util.Arrays.toString(b)} ${util.Arrays.toString(b1)}", + !Arrays.equals(b, b1)) + + val b2 = t1.toByteArray(true) + assertFalse("To byte array round trip error at coeff0", + !Arrays.equals(valueAt0.toByteArray, Arrays.copyOfRange(b2, 0, 24))) + assertFalse("To byte array round trip error with coeff0 at later coeff", + !Arrays.equals(b1, Arrays.copyOfRange(b2, 24, b2.length))) + + val b3 = t1.coeff0Bytes + assertFalse("To byte array round trip error on coeff0", + !Arrays.equals(b3, valueAt0.toByteArray)) + } + + for ( len <- 1 until 100 ) { + val points = new Array[Byte](len) + val values = new Array[GF2_192](len) + val temp = new Array[Byte](24) + + for ( i <- 0 until len ) { + // generate a byte that is not equal to anything in the array (but may be 0) + var okLoop = true + while (okLoop) { + val b = rand.nextInt.toByte + var j = 0 + j = 0 + var doBreak = false + while (!doBreak && j < i) { + if (b == points(j)) { + doBreak = true + } else { + j += 1 + } + } + if (j == i) { + points(i) = b + okLoop = false + } + } + } + for ( i <- 0 until len ) { + rand.nextBytes(temp) + values(i) = new GF2_192(temp) + } + + res = GF2_192_Poly.interpolate(points, values, null) + for ( i <- 0 until len ) { + val t = res.evaluate(points(i)) + assertFalse(s"Interpolation error on length = $len $i(with 0 allowed but not additional)", !(t == values(i))) + } + + for ( opt <- optArray ) { + res = GF2_192_Poly.interpolate(null, values, opt) + assertFalse("Fail: interpolate should output null on points = null", res != null) + res = GF2_192_Poly.interpolate(points, null, opt) + assertFalse("Fail: interpolate should output null on values = null", res != null) + res = GF2_192_Poly.interpolate(points, new Array[GF2_192](0), opt) + assertFalse("Fail: interpolate should output null on values of length 0", res != null) + res = GF2_192_Poly.interpolate(new Array[Byte](0), values, opt) + assertFalse("Fail: interpolate should output null on points of length 0", res != null) + res = GF2_192_Poly.interpolate(new Array[Byte](len - 1), values, opt) + assertFalse("Fail: interpolate should output null on not enough points", res != null) + res = GF2_192_Poly.interpolate(new Array[Byte](len + 1), values, opt) + assertFalse("Fail: interpolate should output null on too many points", res != null) + } + } + for ( opt <- optArray ) { + res = GF2_192_Poly.interpolate(null, null, opt) + assertFalse("Fail: interpolate should output null on both points and values = null", res != null) + } + } +} diff --git a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala index 58da469c82..d4f05a4050 100644 --- a/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala @@ -1,14 +1,16 @@ package sigmastate.eval +import org.scalatest.funsuite.AnyFunSuite +import org.scalatest.matchers.should.Matchers + import java.math.BigInteger -import org.scalatest.{FunSuite, Matchers} import sigmastate.TrivialProp import sigmastate.basics.SecP256K1Group import special.sigma.{ContractsTestkit, SigmaDslBuilder, SigmaProp} import scala.language.implicitConversions -class BasicOpsTests extends FunSuite with ContractsTestkit with Matchers { +class BasicOpsTests extends AnyFunSuite with ContractsTestkit with Matchers { override val SigmaDsl: SigmaDslBuilder = CostingSigmaDslBuilder implicit def boolToSigma(b: Boolean): SigmaProp = TrivialProp(b) diff --git a/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala index 798def6b18..25d7a9e384 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala @@ -1,10 +1,11 @@ package sigmastate.helpers -import org.scalatest.Matchers import scala.annotation.tailrec import scala.util.{Failure, Success, Try} import debox.cfor +import org.scalatest.matchers.should.Matchers + import scala.reflect.ClassTag trait NegativeTesting extends Matchers { diff --git a/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala index b9fa6ffaba..69ed1a9c78 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala @@ -6,8 +6,10 @@ import org.ergoplatform.validation.ValidationRules.CheckSerializableTypeCode import org.ergoplatform.validation.{ValidationException, ValidationSpecification} import org.scalacheck.Arbitrary.arbByte import org.scalacheck.Gen -import org.scalatest.prop.{GeneratorDrivenPropertyChecks, PropertyChecks} -import org.scalatest.{Assertion, Matchers, PropSpec} +import org.scalatest.Assertion +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.{ScalaCheckDrivenPropertyChecks, ScalaCheckPropertyChecks} import scalan.util.BenchmarkUtil import scalan.{RType, TestContexts, TestUtils} import scorex.crypto.hash.Blake2b256 @@ -27,9 +29,9 @@ import scala.language.implicitConversions import scala.reflect.ClassTag import scala.util.DynamicVariable -trait SigmaTestingCommons extends PropSpec - with PropertyChecks - with GeneratorDrivenPropertyChecks +trait SigmaTestingCommons extends AnyPropSpec + with ScalaCheckPropertyChecks + with ScalaCheckDrivenPropertyChecks with Matchers with TestUtils with TestContexts with ValidationSpecification with NegativeTesting with TestsBase { diff --git a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala index e6889e9c32..a512b25de9 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala @@ -1,11 +1,11 @@ package sigmastate.lang -import sigmastate.lang.Terms.{MethodCallLike, Ident} -import sigmastate.Values.{LongConstant, SValue, Value, SigmaBoolean, ConcreteCollection} +import org.scalatest.matchers.should.Matchers +import sigmastate.lang.Terms.{Ident, MethodCallLike} +import sigmastate.Values.{ConcreteCollection, LongConstant, SValue, SigmaBoolean, Value} import sigmastate._ -import java.math.BigInteger -import org.scalatest.Matchers +import java.math.BigInteger import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.SCollection.SByteArray import sigmastate.basics.ProveDHTuple diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala index ad8db1ef17..a9404048ed 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala @@ -2,8 +2,9 @@ package sigmastate.lang import org.ergoplatform.{Height, Inputs, Outputs, Self} import org.ergoplatform.ErgoAddressEncoder._ -import org.scalatest.prop.PropertyChecks -import org.scalatest.{Matchers, PropSpec} +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import sigmastate.Values._ import sigmastate._ import sigmastate.interpreter.Interpreter.ScriptEnv @@ -12,7 +13,7 @@ import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.BinderException import sigmastate.eval._ -class SigmaBinderTest extends PropSpec with PropertyChecks with Matchers with LangTests { +class SigmaBinderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with LangTests { import StdSigmaBuilder._ def bind(env: ScriptEnv, x: String): SValue = { diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala index 07061743c4..3e25700816 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala @@ -1,13 +1,14 @@ package sigmastate.lang -import org.scalatest.prop.PropertyChecks -import org.scalatest.{Matchers, PropSpec} +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import sigmastate.Values._ import sigmastate._ import sigmastate.lang.exceptions.ConstraintFailed import sigmastate.serialization.OpCodes -class SigmaBuilderTest extends PropSpec with PropertyChecks with Matchers with LangTests { +class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with LangTests { property("StdSigmaBuilder construct nodes") { import StdSigmaBuilder._ diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala index 7807a546a0..4b5680af0a 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala @@ -2,8 +2,9 @@ package sigmastate.lang import fastparse.Parsed import org.ergoplatform.{ErgoAddressEncoder, ErgoBox} -import org.scalatest.prop.PropertyChecks -import org.scalatest.{PropSpec, Matchers} +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import sigmastate.SCollection._ import sigmastate.Values._ import sigmastate._ @@ -12,7 +13,7 @@ import sigmastate.lang.Terms._ import sigmastate.lang.syntax.ParserException import sigmastate.serialization.OpCodes -class SigmaParserTest extends PropSpec with PropertyChecks with Matchers with LangTests { +class SigmaParserTest extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with LangTests { import StdSigmaBuilder._ private val predefFuncRegistry = new PredefinedFuncRegistry(StdSigmaBuilder) diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala index fc680bfcf9..3153344bbe 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala @@ -2,8 +2,9 @@ package sigmastate.lang import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix import org.ergoplatform._ -import org.scalatest.prop.PropertyChecks -import org.scalatest.{Matchers, PropSpec} +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import sigmastate.SCollection._ import sigmastate.Values._ import sigmastate._ @@ -19,7 +20,8 @@ import sigmastate.serialization.ErgoTreeSerializer import sigmastate.serialization.generators.ObjectGenerators import sigmastate.utxo.{Append, ExtractCreationInfo} -class SigmaTyperTest extends PropSpec with PropertyChecks with Matchers with LangTests with ObjectGenerators { +class SigmaTyperTest extends AnyPropSpec + with ScalaCheckPropertyChecks with Matchers with LangTests with ObjectGenerators { private val predefFuncRegistry = new PredefinedFuncRegistry(StdSigmaBuilder) import predefFuncRegistry._ diff --git a/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala index 5ffc800191..03b8801459 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala @@ -2,17 +2,20 @@ package sigmastate.serialization import org.ergoplatform.validation.ValidationSpecification import org.scalacheck.Gen -import org.scalatest.prop.{PropertyChecks, TableDrivenPropertyChecks, GeneratorDrivenPropertyChecks} -import org.scalatest.{PropSpec, Assertion, Matchers} +import org.scalatest.prop.TableDrivenPropertyChecks +import org.scalatest.Assertion import org.scalacheck.Arbitrary._ +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.{ScalaCheckDrivenPropertyChecks, ScalaCheckPropertyChecks} import sigmastate.Values._ import sigmastate.SType import sigmastate.helpers.NegativeTesting import sigmastate.serialization.generators._ -trait SerializationSpecification extends PropSpec - with PropertyChecks - with GeneratorDrivenPropertyChecks +trait SerializationSpecification extends AnyPropSpec + with ScalaCheckPropertyChecks + with ScalaCheckDrivenPropertyChecks with TableDrivenPropertyChecks with Matchers with ObjectGenerators diff --git a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 1693a302e4..b776bd8682 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -202,8 +202,8 @@ trait ObjectGenerators extends TypeGenerators val unsignedShortGen: Gen[Short] = Gen.chooseNum(0, Short.MaxValue).map(_.toShort) val contextExtensionGen: Gen[ContextExtension] = for { - values <- Gen.sequence(contextExtensionValuesGen(0, 5)) - } yield ContextExtension(values.asScala.toMap) + values <- Gen.sequence(contextExtensionValuesGen(0, 5))(Buildable.buildableSeq) + } yield ContextExtension(values.toMap) val serializedProverResultGen: Gen[ProverResult] = for { length <- Gen.chooseNum(1, 100) @@ -315,14 +315,14 @@ trait ObjectGenerators extends TypeGenerators tId <- modifierIdGen boxId <- unsignedShortGen tokensCount <- Gen.chooseNum[Int](0, MaxTokens) - tokens <- Gen.sequence(additionalTokensGen(tokensCount)).map(_.asScala.map(_._1)) + tokens <- Gen.sequence(additionalTokensGen(tokensCount))(Buildable.buildableSeq).map(_.map(_._1)) candidate <- ergoBoxCandidateGen(tokens.toSeq) } yield candidate.toBox(tId, boxId) val additionalRegistersGen: Gen[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] = for { regNum <- Gen.chooseNum[Byte](0, ErgoBox.nonMandatoryRegistersCount) - regs <- Gen.sequence(additionalRegistersGen(regNum)) - } yield regs.asScala.toMap + regs <- Gen.sequence(additionalRegistersGen(regNum))(Buildable.buildableSeq) + } yield regs.toMap def arrayOfN[T](n: Int, g: Gen[T])(implicit evb: Buildable[T,Array[T]]): Gen[Array[T]] = { Gen.containerOfN[Array, T](n, g) diff --git a/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala b/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala index 3ce1f60473..2578553c9f 100644 --- a/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala +++ b/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala @@ -1,11 +1,12 @@ package sigmastate.utils -import org.scalatest.prop.PropertyChecks -import org.scalatest.{PropSpec, Matchers} import sigmastate.serialization.generators.ObjectGenerators import Helpers._ +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -class HelpersTests extends PropSpec with PropertyChecks with Matchers with ObjectGenerators { +class HelpersTests extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with ObjectGenerators { property("xorU") { forAll(arrayGen[Byte]) { arr => diff --git a/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala b/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala index b1f6a5705f..0f6b69b78f 100644 --- a/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala @@ -1,13 +1,14 @@ package sigmastate.utils import org.scalacheck.{Arbitrary, Gen} -import org.scalatest.prop.PropertyChecks -import org.scalatest.{Matchers, PropSpec} +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import sigmastate.serialization.generators.ObjectGenerators -class SparseArrayContainerSpecification extends PropSpec +class SparseArrayContainerSpecification extends AnyPropSpec with ObjectGenerators - with PropertyChecks + with ScalaCheckPropertyChecks with Matchers { private val distinctCodeValuePairsGen: Gen[Seq[(Byte, Long)]] = for { diff --git a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index a9b07f8b00..8d4ac696be 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala @@ -1,6 +1,6 @@ package sigmastate.utxo -import com.google.common.primitives.Longs +import scorex.utils.Longs import org.ergoplatform._ import org.ergoplatform.dsl.{ContractSpec, SigmaContractSyntax, TestContractSpec} import scorex.crypto.authds.avltree.batch._ diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index 11ba35d60c..d9b3453777 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -1,6 +1,6 @@ package sigmastate.utxo -import com.google.common.primitives.Bytes +import scorex.utils.Bytes import org.ergoplatform.ErgoBox.R4 import org.ergoplatform._ import org.ergoplatform.validation.ValidationException diff --git a/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala b/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala index 5165517071..3bf3f0cf08 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala @@ -1,17 +1,18 @@ package sigmastate.utxo import org.ergoplatform._ -import org.scalatest.prop.GeneratorDrivenPropertyChecks -import org.scalatest.{PropSpec, Matchers} import scalan.util.BenchmarkUtil import sigmastate.helpers.SigmaTestingCommons -import sigmastate.interpreter.{ProverResult, ContextExtension} +import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.serialization.generators.ObjectGenerators import debox.{Buffer => DBuffer} +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks import sigmastate.util.{MaxArrayLength, safeNewArray} -class SerializationRoundTripSpec extends PropSpec - with GeneratorDrivenPropertyChecks +class SerializationRoundTripSpec extends AnyPropSpec + with ScalaCheckDrivenPropertyChecks with Matchers with ObjectGenerators with SigmaTestingCommons { diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala index ecf843efe1..17de1cd96f 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala @@ -26,7 +26,7 @@ case class AssetsAtomicExchange[Spec <: ContractSpec] lazy val buyerProp = proposition("buyer", { ctx: Context => import ctx._ - (HEIGHT > deadline && pkA) || { + (HEIGHT > deadline && pkA) || sigmaProp({ val tokenData = OUTPUTS(0).R2[Coll[(Coll[Byte], Long)]].get(0) val knownId = OUTPUTS(0).R4[Coll[Byte]].get == SELF.id allOf(Coll( @@ -35,7 +35,7 @@ case class AssetsAtomicExchange[Spec <: ContractSpec] OUTPUTS(0).propositionBytes == pkA.propBytes, knownId )) - } + }) }, """{ | (HEIGHT > deadline && pkA) || { @@ -52,14 +52,14 @@ case class AssetsAtomicExchange[Spec <: ContractSpec] lazy val sellerProp = proposition("seller", {ctx: Context => import ctx._ - (HEIGHT > deadline && pkB) || { + (HEIGHT > deadline && pkB) || sigmaProp({ val knownBoxId = OUTPUTS(1).R4[Coll[Byte]].get == SELF.id allOf(Coll( OUTPUTS(1).value >= 100L, knownBoxId, OUTPUTS(1).propositionBytes == pkB.propBytes )) - } + }) }, """{ | (HEIGHT > deadline && pkB) || diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala index 5724ac2fe4..448f9e4801 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala @@ -21,7 +21,7 @@ case class AssetsPartialFilling[Spec <: ContractSpec] lazy val buyerProp = proposition("buyer", { ctx: Context => import ctx._ - (HEIGHT > deadline && pkA) || { + (HEIGHT > deadline && pkA) || sigmaProp({ val outIdx = getVar[Short](127).get val out = OUTPUTS(outIdx) @@ -38,7 +38,7 @@ case class AssetsPartialFilling[Spec <: ContractSpec] out.propositionBytes == pkA.propBytes, out.R4[Coll[Byte]].get == SELF.id )) - } + }) }, """(HEIGHT > deadline && pkA) || { | @@ -62,7 +62,7 @@ case class AssetsPartialFilling[Spec <: ContractSpec] lazy val sellerProp = proposition("seller", {ctx: Context => import ctx._ - (HEIGHT > deadline && pkB) || { + (HEIGHT > deadline && pkB) || sigmaProp({ val outIdx = getVar[Short](127).get val out = OUTPUTS(outIdx) @@ -88,7 +88,7 @@ case class AssetsPartialFilling[Spec <: ContractSpec] outR4 == SELF.id, out.propositionBytes == pkB.propBytes )) - } + }) }, """ (HEIGHT > deadline && pkB) || { | val outIdx = getVar[Short](127).get diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala index 8e3e015d7d..ebbf021fb8 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala @@ -25,7 +25,7 @@ case class CrowdFunding[Spec <: ContractSpec] } val fundraisingSuccess = HEIGHT < deadline && pkProject && - OUTPUTS.exists(enoughRaised) + sigmaProp(OUTPUTS.exists(enoughRaised)) fundraisingFailure || fundraisingSuccess }, @@ -52,9 +52,9 @@ case class CrowdFunding[Spec <: ContractSpec] val c1 = HEIGHT >= deadline && pkBacker val c2 = HEIGHT < deadline && pkProject && - OUTPUTS.exists({ (out: Box) => + sigmaProp(OUTPUTS.exists({ (out: Box) => out.value >= minToRaise && out.propositionBytes == pkProject.propBytes - }) + })) c1 || c2 }, """ diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala index 2a2f2b2f7b..8e1cf9936a 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala @@ -31,7 +31,7 @@ class DummyExamplesSpecification extends SigmaTestingCommons { suite => } def getRoot(item: Coll[Byte]):Coll[Byte] = path.foldLeft(item, xor) - pkA && getRoot(oldItem) == oldRoot && getRoot(newItem) == newRoot + pkA && sigmaProp(getRoot(oldItem) == oldRoot) && sigmaProp(getRoot(newItem) == newRoot) val dummy = Coll[Byte]() val isValid = {(b:Box) => b.propositionBytes == dummy} diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala index a52c4d2999..5b47961119 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala @@ -1,6 +1,6 @@ package sigmastate.utxo.examples -import com.google.common.primitives.Longs +import scorex.utils.Longs import org.ergoplatform.ErgoBox.{R4, R5} import org.ergoplatform._ import org.ergoplatform.dsl.TestContractSpec diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index 178d053bd2..5ec589587f 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala @@ -2,7 +2,7 @@ package sigmastate.utxo.examples import java.security.SecureRandom -import com.google.common.primitives.Longs +import scorex.utils.Longs import org.ergoplatform.ErgoBox.RegisterId import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Lookup} import scorex.crypto.authds.{ADKey, ADValue} diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala index 5b6b29b665..0e0b50dacd 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala @@ -3949,15 +3949,6 @@ class SigmaDslSpecification extends SigmaDslTesting FuncValue(Vector((1, SByteArray)), ByteArrayToLong(ValUse(1, SByteArray))))) } - // TODO soft-fork: related to https://github.com/ScorexFoundation/sigmastate-interpreter/issues/427 - // TODO costing: expression t._1(t._2) cannot be costed because t is lambda argument - // ignore("Func context variable") { - // val doApply = checkEq(func[(Int => Int, Int), Int]("{ (t: (Int => Int, Int)) => t._1(t._2) }")) { (t: (Int => Int, Int)) => t._1(t._2) } - // val code = compileWithCosting(emptyEnv, s"{ (x: Int) => x + 1 }") - // val ctx = ErgoLikeContext.dummy(fakeSelf) - // doApply((CFunc[Int, Int](ctx, code), 10)) - // } - property("Box properties equivalence") { verifyCases( { diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala index 9a25237682..1b93729e93 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala @@ -48,7 +48,8 @@ class SigmaDslStaginTests extends BaseCtxTests with ErgoScriptTestkit with BaseL cake.check(boxA1, { env: EnvRep[RBox] => for { obj <- env; arg <- lifted(1) } yield obj.getReg[Coll[Byte]](arg) }, boxA1.getReg[special.collection.Coll[Byte]](1)) cake.check(boxA1, { env: EnvRep[RBox] => for { obj <- env } yield obj.registers }, boxA1.registers) - cake.check(p1, { env: EnvRep[RSigmaProp] => for { p1 <- env; arg <- lifted(true) } yield p1 && arg }, p1 && true) - cake.check(p1, { env: EnvRep[RSigmaProp] => for { p1 <- env; arg <- lifted(p2) } yield p1 && arg }, p1 && p2) + cake.check(p1, { env: EnvRep[RSigmaProp] => + for { p1 <- env; arg <- lifted(p2) } yield p1 && arg + }, p1 && p2) } } diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala index 664f3ec64a..281355ccd2 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala @@ -9,8 +9,6 @@ import org.scalacheck.Arbitrary._ import org.scalacheck.Gen.frequency import org.scalacheck.{Arbitrary, Gen} import org.scalatest.exceptions.TestFailedException -import org.scalatest.prop.PropertyChecks -import org.scalatest.{Matchers, PropSpec} import scalan.RType import scalan.RType._ import scalan.util.BenchmarkUtil @@ -35,14 +33,17 @@ import sigmastate.utxo.{DeserializeContext, DeserializeRegister, GetVar, OptionG import sigmastate.{SOption, SSigmaProp, SType, VersionContext, eval} import special.collection.{Coll, CollType} import debox.cfor +import org.scalatest.matchers.should.Matchers +import org.scalatest.propspec.AnyPropSpec +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import java.util import scala.collection.mutable import scala.reflect.ClassTag import scala.util.{Failure, Success, Try} -class SigmaDslTesting extends PropSpec - with PropertyChecks +class SigmaDslTesting extends AnyPropSpec + with ScalaCheckPropertyChecks with Matchers with SigmaTestingData with SigmaContractSyntax with ObjectGenerators { suite =>