From 176cf8312da9c9ca6a698af6e5a11d665c804d62 Mon Sep 17 00:00:00 2001 From: skydoves Date: Sat, 27 Nov 2021 13:54:37 +0900 Subject: [PATCH 1/3] Bump AGP and kotlin versions --- dependencies.gradle | 6 +++--- gradle/wrapper/gradle-wrapper.properties | 2 +- whatif/build.gradle | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 2e74f7a..e08a1ca 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -5,14 +5,14 @@ ext.versions = [ versionCode : 11, versionName : '1.1.0', - gradleBuildTool : '4.1.3', - spotlessGradle : '5.14.0', + gradleBuildTool : '7.0.2', + spotlessGradle : '5.15.0', ktlintGradle : '0.41.0', dokkaGradle : '1.4.30', binaryValidator : '0.7.1', mavenPublish : '0.15.1', - kotlin : '1.4.31', + kotlin : '1.5.30', androidxAppcompat: '1.3.0', // for demo diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 64e9590..6a66379 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip diff --git a/whatif/build.gradle b/whatif/build.gradle index ad35f82..5665a19 100644 --- a/whatif/build.gradle +++ b/whatif/build.gradle @@ -1,4 +1,3 @@ -apply plugin: 'java-library' apply plugin: 'kotlin' apply plugin: 'org.jetbrains.dokka' apply plugin: 'binary-compatibility-validator' @@ -21,6 +20,10 @@ task coverageReport(type: JacocoReport, dependsOn: 'test') { } } +tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { + kotlinOptions.freeCompilerArgs += ["-Xopt-in=kotlin.contracts.ExperimentalContracts"] +} + dependencies { testImplementation "junit:junit:$versions.junit" } From 79acdf039c0caf240a934944c1b81cb499a2c475 Mon Sep 17 00:00:00 2001 From: skydoves Date: Sat, 27 Nov 2021 13:55:05 +0900 Subject: [PATCH 2/3] Add contract on whatif module functions --- .../main/java/com/skydoves/whatif/WhatIf.kt | 101 ++++++++++--- .../java/com/skydoves/whatif/WhatIfArray.kt | 137 +++++++++++++----- .../com/skydoves/whatif/WhatIfCollections.kt | 122 ++++++++++++---- .../java/com/skydoves/whatif/WhatIfString.kt | 18 ++- 4 files changed, 288 insertions(+), 90 deletions(-) diff --git a/whatif/src/main/java/com/skydoves/whatif/WhatIf.kt b/whatif/src/main/java/com/skydoves/whatif/WhatIf.kt index 92a09f1..5c0faed 100644 --- a/whatif/src/main/java/com/skydoves/whatif/WhatIf.kt +++ b/whatif/src/main/java/com/skydoves/whatif/WhatIf.kt @@ -20,6 +20,9 @@ package com.skydoves.whatif +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + /** * WhatIf is kotlin extensions for expressing a single if-else statement, nullable and boolean. */ @@ -38,7 +41,9 @@ public inline fun T.whatIf( given: (T) -> Boolean?, whatIf: () -> Unit ): T { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } if (given(this) == true) { whatIf() } @@ -62,7 +67,10 @@ public inline fun T.whatIf( whatIf: () -> Unit, whatIfNot: () -> Unit ): T { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (given(this) == true) { whatIf() } else { @@ -86,7 +94,9 @@ public inline fun T.whatIf( given: Boolean?, whatIf: T.() -> Unit ): T { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } if (given == true) { this.apply { whatIf() } } @@ -111,7 +121,10 @@ public inline fun T.whatIf( whatIf: T.() -> Unit, whatIfNot: T.() -> Unit ): T { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (given == true) { this.apply { whatIf() } } else { @@ -135,7 +148,9 @@ public inline fun T.whatIf( given: () -> Boolean?, whatIfDo: T.() -> Unit ): T { - + contract { + callsInPlace(whatIfDo, InvocationKind.AT_MOST_ONCE) + } return this.whatIf( given = given, whatIfDo = whatIfDo, @@ -161,7 +176,10 @@ public inline fun T.whatIf( whatIfDo: T.() -> Unit, whatIfNot: T.() -> Unit ): T { - + contract { + callsInPlace(whatIfDo, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (given() == true) { this.whatIfDo() } else { @@ -185,7 +203,9 @@ public inline fun T.whatIfMap( default: R, whatIf: (T) -> R ): R { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } return this.whatIfMap( whatIf = whatIf, whatIfNot = { default } @@ -207,7 +227,10 @@ public inline fun T.whatIfMap( whatIf: (T) -> R, whatIfNot: (T) -> R ): R { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null) { return whatIf(this) } @@ -232,7 +255,9 @@ public inline fun T.whatIfMap( default: R, whatIf: (T) -> R ): R { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } return this.whatIfMap( given = given, whatIf = whatIf, @@ -258,7 +283,10 @@ public inline fun T.whatIfMap( whatIf: (T) -> R, whatIfNot: (T) -> R ): R { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (given == true) { return whatIf(this) } @@ -290,7 +318,9 @@ public inline fun T.whatIfLet( default: R, whatIf: (T) -> R ): R { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } if (given == true) { return whatIf(this) } @@ -322,7 +352,10 @@ public inline fun T.whatIfLet( whatIf: (T) -> R, whatIfNot: (T) -> R ): R { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (given == true) { return whatIf(this) } @@ -341,7 +374,9 @@ public inline fun T.whatIfLet( public inline fun T?.whatIfNotNull( whatIf: (T) -> Unit ): T? { - + contract { + callsInPlace(whatIf, InvocationKind.EXACTLY_ONCE) + } return this.whatIfNotNull( whatIf = whatIf, whatIfNot = { } @@ -363,7 +398,10 @@ public inline fun T?.whatIfNotNull( whatIf: (T) -> Unit, whatIfNot: () -> Unit ): T? { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null) { whatIf(this) return this @@ -393,7 +431,9 @@ public inline fun T?.whatIfNotNull( public inline fun Any?.whatIfNotNullAs( whatIf: (R) -> Unit ): Any? { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } return whatIfNotNullAs( whatIf = whatIf, whatIfNot = { } @@ -426,7 +466,10 @@ public inline fun Any?.whatIfNotNullAs( whatIf: (R) -> Unit, whatIfNot: () -> Unit ): Any? { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this is R) { whatIf(this as R) return this @@ -451,7 +494,10 @@ public inline fun T?.whatIfNotNullWith( whatIf: (T) -> R, whatIfNot: (T?) -> R ): R { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null) { return whatIf(this) } @@ -470,7 +516,9 @@ public inline fun T?.whatIfNotNullWith( public inline fun Boolean?.whatIf( whatIf: () -> Unit ): Boolean? { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } return this.whatIf( whatIf = whatIf, whatIfNot = { } @@ -492,7 +540,10 @@ public inline fun Boolean?.whatIf( whatIf: () -> Unit, whatIfNot: () -> Unit ): Boolean? { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this == true) { whatIf() } else { @@ -513,7 +564,9 @@ public inline fun Boolean?.whatIf( public inline fun Boolean?.whatIfElse( whatIf: () -> Unit ): Boolean? { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } if (this == false) { whatIf() } @@ -534,7 +587,9 @@ public inline fun Boolean?.whatIfAnd( predicate: Boolean?, whatIf: () -> Unit ): Boolean? { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } if (this == true && predicate == true) { whatIf() } @@ -555,7 +610,9 @@ public inline fun Boolean?.whatIfOr( predicate: Boolean?, whatIf: () -> Unit ): Boolean? { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } if (this == true || predicate == true) { whatIf() } diff --git a/whatif/src/main/java/com/skydoves/whatif/WhatIfArray.kt b/whatif/src/main/java/com/skydoves/whatif/WhatIfArray.kt index fd20e22..07c0181 100644 --- a/whatif/src/main/java/com/skydoves/whatif/WhatIfArray.kt +++ b/whatif/src/main/java/com/skydoves/whatif/WhatIfArray.kt @@ -19,6 +19,9 @@ package com.skydoves.whatif +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + /** * An expression for invoking [whatIf] when the [Array] is not null and not empty. * @@ -30,12 +33,15 @@ package com.skydoves.whatif @WhatIfInlineOnly public inline fun Array?.whatIfNotNullOrEmpty( whatIf: (Array) -> Unit -): Array? = apply { - +): Array? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -52,13 +58,17 @@ public inline fun Array?.whatIfNotNullOrEmpty( public inline fun Array?.whatIfNotNullOrEmpty( whatIf: (Array) -> Unit, whatIfNot: () -> Unit -): Array? = apply { - +): Array? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (!this.isNullOrEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -72,8 +82,10 @@ public inline fun Array?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun ByteArray?.whatIfNotNullOrEmpty( whatIf: (ByteArray) -> Unit -): ByteArray? = apply { - +): ByteArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } return this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } @@ -94,13 +106,17 @@ public inline fun ByteArray?.whatIfNotNullOrEmpty( public inline fun ByteArray?.whatIfNotNullOrEmpty( whatIf: (ByteArray) -> Unit, whatIfNot: () -> Unit -): ByteArray? = apply { - +): ByteArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this.isNotEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -114,12 +130,15 @@ public inline fun ByteArray?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun ShortArray?.whatIfNotNullOrEmpty( whatIf: (ShortArray) -> Unit -): ShortArray? = apply { - +): ShortArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -136,13 +155,17 @@ public inline fun ShortArray?.whatIfNotNullOrEmpty( public inline fun ShortArray?.whatIfNotNullOrEmpty( whatIf: (ShortArray) -> Unit, whatIfNot: () -> Unit -): ShortArray? = apply { - +): ShortArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this.isNotEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -156,12 +179,15 @@ public inline fun ShortArray?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun IntArray?.whatIfNotNullOrEmpty( whatIf: (IntArray) -> Unit -): IntArray? = apply { - +): IntArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -178,13 +204,17 @@ public inline fun IntArray?.whatIfNotNullOrEmpty( public inline fun IntArray?.whatIfNotNullOrEmpty( whatIf: (IntArray) -> Unit, whatIfNot: () -> Unit -): IntArray? = apply { - +): IntArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this.isNotEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -198,12 +228,15 @@ public inline fun IntArray?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun LongArray?.whatIfNotNullOrEmpty( whatIf: (LongArray) -> Unit -): LongArray? = apply { - +): LongArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -220,13 +253,17 @@ public inline fun LongArray?.whatIfNotNullOrEmpty( public inline fun LongArray?.whatIfNotNullOrEmpty( whatIf: (LongArray) -> Unit, whatIfNot: () -> Unit -): LongArray? = apply { - +): LongArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this.isNotEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -240,12 +277,15 @@ public inline fun LongArray?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun FloatArray?.whatIfNotNullOrEmpty( whatIf: (FloatArray) -> Unit -): FloatArray? = apply { - +): FloatArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -262,13 +302,17 @@ public inline fun FloatArray?.whatIfNotNullOrEmpty( public inline fun FloatArray?.whatIfNotNullOrEmpty( whatIf: (FloatArray) -> Unit, whatIfNot: () -> Unit -): FloatArray? = apply { - +): FloatArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this.isNotEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -282,12 +326,15 @@ public inline fun FloatArray?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun DoubleArray?.whatIfNotNullOrEmpty( whatIf: (DoubleArray) -> Unit -): DoubleArray? = apply { - +): DoubleArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -304,13 +351,17 @@ public inline fun DoubleArray?.whatIfNotNullOrEmpty( public inline fun DoubleArray?.whatIfNotNullOrEmpty( whatIf: (DoubleArray) -> Unit, whatIfNot: () -> Unit -): DoubleArray? = apply { - +): DoubleArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this.isNotEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -324,12 +375,15 @@ public inline fun DoubleArray?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun BooleanArray?.whatIfNotNullOrEmpty( whatIf: (BooleanArray) -> Unit -): BooleanArray? = apply { - +): BooleanArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -346,13 +400,17 @@ public inline fun BooleanArray?.whatIfNotNullOrEmpty( public inline fun BooleanArray?.whatIfNotNullOrEmpty( whatIf: (BooleanArray) -> Unit, whatIfNot: () -> Unit -): BooleanArray? = apply { - +): BooleanArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this.isNotEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -366,12 +424,15 @@ public inline fun BooleanArray?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun CharArray?.whatIfNotNullOrEmpty( whatIf: (CharArray) -> Unit -): CharArray? = apply { - +): CharArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -388,11 +449,15 @@ public inline fun CharArray?.whatIfNotNullOrEmpty( public inline fun CharArray?.whatIfNotNullOrEmpty( whatIf: (CharArray) -> Unit, whatIfNot: () -> Unit -): CharArray? = apply { - +): CharArray? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (this != null && this.isNotEmpty()) { whatIf(this) } else { whatIfNot() } + return this } diff --git a/whatif/src/main/java/com/skydoves/whatif/WhatIfCollections.kt b/whatif/src/main/java/com/skydoves/whatif/WhatIfCollections.kt index ab5039a..af4f85e 100644 --- a/whatif/src/main/java/com/skydoves/whatif/WhatIfCollections.kt +++ b/whatif/src/main/java/com/skydoves/whatif/WhatIfCollections.kt @@ -19,6 +19,9 @@ package com.skydoves.whatif +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + /** * An expression for invoking [whatIf] when the [List] is not null and not empty. * @@ -30,12 +33,15 @@ package com.skydoves.whatif @WhatIfInlineOnly public inline fun List?.whatIfNotNullOrEmpty( whatIf: (List) -> Unit -): List? = apply { - +): List? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -52,13 +58,17 @@ public inline fun List?.whatIfNotNullOrEmpty( public inline fun List?.whatIfNotNullOrEmpty( whatIf: (List) -> Unit, whatIfNot: () -> Unit -): List? = apply { - +): List? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (!this.isNullOrEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -72,12 +82,15 @@ public inline fun List?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun Set?.whatIfNotNullOrEmpty( whatIf: (Set) -> Unit -): Set? = apply { - +): Set? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -94,13 +107,17 @@ public inline fun Set?.whatIfNotNullOrEmpty( public inline fun Set?.whatIfNotNullOrEmpty( whatIf: (Set) -> Unit, whatIfNot: () -> Unit -): Set? = apply { - +): Set? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (!this.isNullOrEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -114,12 +131,15 @@ public inline fun Set?.whatIfNotNullOrEmpty( @WhatIfInlineOnly public inline fun Map?.whatIfNotNullOrEmpty( whatIf: (Map) -> Unit -): Map? = apply { - +): Map? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -136,13 +156,17 @@ public inline fun Map?.whatIfNotNullOrEmpty( public inline fun Map?.whatIfNotNullOrEmpty( whatIf: (Map) -> Unit, whatIfNot: () -> Unit -): Map? = apply { - +): Map? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (!this.isNullOrEmpty()) { whatIf(this) } else { whatIfNot() } + return this } /** @@ -158,13 +182,16 @@ public inline fun Map?.whatIfNotNullOrEmpty( public inline fun , reified E> T.addWhatIfNotNull( element: E?, whatIf: (T) -> Unit -): T = apply { - +): T { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.addWhatIfNotNull( element = element, whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -182,8 +209,11 @@ public inline fun , reified E> T.addWhatIfNotNu element: E?, whatIf: (T) -> Unit, whatIfNot: (T) -> Unit -): T = apply { - +): T { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } element?.whatIfNotNullAs( whatIf = { add(it) @@ -193,6 +223,7 @@ public inline fun , reified E> T.addWhatIfNotNu whatIfNot(this) } ) + return this } /** @@ -208,13 +239,16 @@ public inline fun , reified E> T.addWhatIfNotNu public inline fun , reified E> T.addAllWhatIfNotNull( element: Collection?, whatIf: (T) -> Unit -): T = apply { - +): T { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.addAllWhatIfNotNull( element = element, whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -232,8 +266,11 @@ public inline fun , reified E> T.addAllWhatIfNo element: Collection?, whatIf: (T) -> Unit, whatIfNot: (T) -> Unit -): T = apply { - +): T { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } element?.whatIfNotNull( whatIf = { addAll(it) @@ -243,6 +280,7 @@ public inline fun , reified E> T.addAllWhatIfNo whatIfNot(this) } ) + return this } /** @@ -258,13 +296,16 @@ public inline fun , reified E> T.addAllWhatIfNo public inline fun , reified E> T.removeWhatIfNotNull( element: E?, whatIf: (T) -> Unit -): T = apply { - +): T { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.removeWhatIfNotNull( element = element, whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -282,8 +323,11 @@ public inline fun , reified E> T.removeWhatIfNo element: E?, whatIf: (T) -> Unit, whatIfNot: (T) -> Unit -): T = apply { - +): T { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } element?.whatIfNotNullAs( whatIf = { remove(it) @@ -293,6 +337,7 @@ public inline fun , reified E> T.removeWhatIfNo whatIfNot(this) } ) + return this } /** @@ -308,13 +353,16 @@ public inline fun , reified E> T.removeWhatIfNo public inline fun , reified E> T.removeAllWhatIfNotNull( element: Collection?, whatIf: (T) -> Unit -): T = apply { - +): T { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.removeAllWhatIfNotNull( element = element, whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -332,8 +380,11 @@ public inline fun , reified E> T.removeAllWhatI element: Collection?, whatIf: (T) -> Unit, whatIfNot: (T) -> Unit -): T = apply { - +): T { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } element?.whatIfNotNull( whatIf = { removeAll(it) @@ -343,6 +394,7 @@ public inline fun , reified E> T.removeAllWhatI whatIfNot(this) } ) + return this } /** @@ -357,6 +409,9 @@ public inline fun , reified E> T.removeAllWhatI public inline fun Iterable.whatIfAnd( whatIf: () -> Unit ): Iterable { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } return this.whatIfAnd( whatIf = whatIf, whatIfNot = { } @@ -377,6 +432,10 @@ public inline fun Iterable.whatIfAnd( whatIf: () -> Unit, whatIfNot: (() -> Unit) ): Iterable { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } var predicate: Boolean? = null this.forEach { @@ -408,6 +467,9 @@ public inline fun Iterable.whatIfAnd( public inline fun Iterable.whatIfOr( whatIf: () -> Unit ): Iterable { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } return this.whatIfOr( whatIf = whatIf, whatIfNot = { } @@ -428,6 +490,10 @@ public inline fun Iterable.whatIfOr( whatIf: () -> Unit, whatIfNot: (() -> Unit) ): Iterable { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } var predicate: Boolean? = null this.forEach { diff --git a/whatif/src/main/java/com/skydoves/whatif/WhatIfString.kt b/whatif/src/main/java/com/skydoves/whatif/WhatIfString.kt index 56023d1..f10bc51 100644 --- a/whatif/src/main/java/com/skydoves/whatif/WhatIfString.kt +++ b/whatif/src/main/java/com/skydoves/whatif/WhatIfString.kt @@ -19,6 +19,9 @@ package com.skydoves.whatif +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + /** * An expression for invoking [whatIf] when the [String] is not null and not empty. * @@ -30,12 +33,15 @@ package com.skydoves.whatif @WhatIfInlineOnly public inline fun String?.whatIfNotNullOrEmpty( whatIf: (String) -> Unit -): String? = apply { - +): String? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfNotNullOrEmpty( whatIf = whatIf, whatIfNot = { } ) + return this } /** @@ -52,11 +58,15 @@ public inline fun String?.whatIfNotNullOrEmpty( public inline fun String?.whatIfNotNullOrEmpty( whatIf: (String) -> Unit, whatIfNot: () -> Unit -): String? = apply { - +): String? { + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (!this.isNullOrEmpty()) { whatIf(this) } else { whatIfNot() } + return this } From 79ce1380a7a5a28ca9c842a21b45edaba59c860b Mon Sep 17 00:00:00 2001 From: skydoves Date: Sat, 27 Nov 2021 14:01:41 +0900 Subject: [PATCH 3/3] Add contract on whatif-android module --- whatif-android/build.gradle | 5 +- .../skydoves/whatif_android/WhatIfActivity.kt | 74 +++++++++++++++---- .../skydoves/whatif_android/WhatIfFragment.kt | 33 +++++++-- .../whatif_android/WhatIfFragmentActivity.kt | 14 ++++ whatif/build.gradle | 5 +- .../main/java/com/skydoves/whatif/WhatIf.kt | 2 +- 6 files changed, 107 insertions(+), 26 deletions(-) diff --git a/whatif-android/build.gradle b/whatif-android/build.gradle index 2611b17..f84926a 100644 --- a/whatif-android/build.gradle +++ b/whatif-android/build.gradle @@ -24,7 +24,10 @@ android { } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { - kotlinOptions.freeCompilerArgs += ["-Xexplicit-api=strict"] + kotlinOptions.freeCompilerArgs += [ + "-Xexplicit-api=strict", + "-Xopt-in=kotlin.contracts.ExperimentalContracts" + ] } dependencies { diff --git a/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfActivity.kt b/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfActivity.kt index 2e2eb4b..1b55803 100644 --- a/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfActivity.kt +++ b/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfActivity.kt @@ -27,6 +27,8 @@ import android.os.Parcelable import com.skydoves.whatif.whatIfNotNull import com.skydoves.whatif.whatIfNotNullAs import java.io.Serializable +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract /** * An expression for invoking [whatIf] when the [Activity]'s intent extras is not null and not empty. @@ -38,7 +40,9 @@ import java.io.Serializable public inline fun Activity.whatIfHasExtras( whatIf: (Bundle) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfHasExtras( whatIf = whatIf, whatIfNot = { } @@ -58,7 +62,10 @@ public inline fun Activity.whatIfHasExtras( whatIf: (Bundle) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this.intent.extras.whatIfNotNull( whatIf = { if (!it.isEmpty) { @@ -81,7 +88,9 @@ public inline fun Activity.whatIfHasExtras( name: String, whatIf: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfHasExtras( name = name, whatIf = whatIf, @@ -104,7 +113,10 @@ public inline fun Activity.whatIfHasExtras( whatIf: () -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } if (intent.hasExtra(name)) { whatIf() } else { @@ -124,7 +136,9 @@ public inline fun Activity.whatIfHasStringExtra( name: String, whatIf: (String) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.intent.getStringExtra(name).whatIfNotNull( whatIf = whatIf, whatIfNot = { } @@ -146,7 +160,10 @@ public inline fun Activity.whatIfHasStringExtra( whatIf: (String) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this.intent.getStringExtra(name).whatIfNotNull( whatIf = whatIf, whatIfNot = whatIfNot @@ -165,7 +182,9 @@ public inline fun Activity.whatIfHasCharSequenceExtra( name: String, whatIf: (CharSequence) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.intent.getCharSequenceExtra(name).whatIfNotNull( whatIf = whatIf, whatIfNot = { } @@ -187,7 +206,10 @@ public inline fun Activity.whatIfHasCharSequenceExtra( whatIf: (CharSequence) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this.intent.getCharSequenceExtra(name).whatIfNotNull( whatIf = whatIf, whatIfNot = whatIfNot @@ -206,7 +228,9 @@ public inline fun Activity.whatIfHasSerializableExtra name: String, whatIf: (T) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.intent.getSerializableExtra(name).whatIfNotNullAs( whatIf = whatIf, whatIfNot = { } @@ -228,7 +252,10 @@ public inline fun Activity.whatIfHasSerializableExtra whatIf: (T) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this.intent.getSerializableExtra(name).whatIfNotNullAs( whatIf = whatIf, whatIfNot = whatIfNot @@ -247,7 +274,9 @@ public inline fun Activity.whatIfHasParcelableExtra( name: String, whatIf: (T) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.intent.getParcelableExtra(name).whatIfNotNull( whatIf = whatIf, whatIfNot = { } @@ -269,7 +298,10 @@ public inline fun Activity.whatIfHasParcelableExtra( whatIf: (T) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this.intent.getParcelableExtra(name).whatIfNotNull( whatIf = whatIf, whatIfNot = whatIfNot @@ -288,7 +320,9 @@ public inline fun Activity.whatIfHasParcelableArrayList name: String, whatIf: (ArrayList) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.intent.getParcelableArrayListExtra(name).whatIfNotNull( whatIf = whatIf, whatIfNot = { } @@ -310,7 +344,10 @@ public inline fun Activity.whatIfHasParcelableArrayList whatIf: (ArrayList) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this.intent.getParcelableArrayListExtra(name).whatIfNotNull( whatIf = whatIf, whatIfNot = whatIfNot @@ -327,7 +364,9 @@ public inline fun Activity.whatIfHasParcelableArrayList public inline fun Activity.whatIfHasDeepLinkUri( whatIf: (Uri) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this.whatIfHasDeepLinkUri(whatIf, { }) } @@ -344,6 +383,9 @@ public inline fun Activity.whatIfHasDeepLinkUri( whatIf: (Uri) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this.intent.data.whatIfNotNull(whatIf, whatIfNot) } diff --git a/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfFragment.kt b/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfFragment.kt index 13df157..11c959f 100644 --- a/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfFragment.kt +++ b/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfFragment.kt @@ -27,6 +27,8 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import com.skydoves.whatif.whatIfNotNull import com.skydoves.whatif.whatIfNotNullAs +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract /** * @author skydoves (Jaewoong Eum) @@ -40,7 +42,9 @@ import com.skydoves.whatif.whatIfNotNullAs public inline fun Fragment?.whatIfNotNullContext( whatIf: (Context) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this?.context.whatIfNotNull { whatIf(it) } @@ -80,7 +84,9 @@ public inline fun Fragment?.whatIfNotNullContext( public inline fun Fragment?.whatIfNotNullActivity( whatIf: (FragmentActivity) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } this?.activity.whatIfNotNull { whatIf(it) } @@ -101,7 +107,10 @@ public inline fun Fragment?.whatIfNotNullActivity( whatIf: (FragmentActivity) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this?.activity.whatIfNotNull( whatIf = whatIf, whatIfNot = whatIfNot @@ -120,7 +129,9 @@ public inline fun Fragment?.whatIfNotNullActivity( public inline fun Fragment?.whatIfHasArguments( whatIf: (Bundle) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } whatIfHasArguments(whatIf) { } } @@ -138,7 +149,10 @@ public inline fun Fragment?.whatIfHasArguments( whatIf: (Bundle) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this?.arguments.whatIfNotNull(whatIf, whatIfNot) } @@ -154,7 +168,9 @@ public inline fun Fragment?.whatIfHasArguments( public inline fun Fragment?.whatIfFindParentInterface( whatIf: (T) -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + } whatIfFindParentInterface(whatIf) { } } @@ -172,6 +188,9 @@ public inline fun Fragment?.whatIfFindParentInterface( whatIf: (T) -> Unit, whatIfNot: () -> Unit ) { - + contract { + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) + callsInPlace(whatIfNot, InvocationKind.AT_MOST_ONCE) + } this?.activity.whatIfNotNullAs(whatIf, whatIfNot) } diff --git a/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfFragmentActivity.kt b/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfFragmentActivity.kt index f3ff91c..ccbc933 100644 --- a/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfFragmentActivity.kt +++ b/whatif-android/src/main/java/com/skydoves/whatif_android/WhatIfFragmentActivity.kt @@ -20,6 +20,8 @@ import androidx.annotation.IdRes import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import com.skydoves.whatif.whatIfNotNullAs +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract /** * @author skydoves (Jaewoong Eum) @@ -35,6 +37,9 @@ public inline fun FragmentActivity.whatIfFindFragment( @IdRes id: Int, whatIf: (T) -> Unit ) { + contract { + callsInPlace(whatIf, InvocationKind.EXACTLY_ONCE) + } whatIfFindFragment(id, whatIf, {}) } @@ -55,6 +60,9 @@ public inline fun FragmentActivity.whatIfFindFragment( whatIf: (T) -> Unit, whatIfNot: () -> Unit ) { + contract { + callsInPlace(whatIf, InvocationKind.EXACTLY_ONCE) + } supportFragmentManager.findFragmentById(id).whatIfNotNullAs(whatIf, whatIfNot) } @@ -72,6 +80,9 @@ public inline fun FragmentActivity.whatIfFindFragment( tag: String?, whatIf: (T) -> Unit ) { + contract { + callsInPlace(whatIf, InvocationKind.EXACTLY_ONCE) + } whatIfFindFragment(tag, whatIf, {}) } @@ -92,5 +103,8 @@ public inline fun FragmentActivity.whatIfFindFragment( whatIf: (T) -> Unit, whatIfNot: () -> Unit ) { + contract { + callsInPlace(whatIf, InvocationKind.EXACTLY_ONCE) + } supportFragmentManager.findFragmentByTag(tag).whatIfNotNullAs(whatIf, whatIfNot) } diff --git a/whatif/build.gradle b/whatif/build.gradle index 5665a19..72b031e 100644 --- a/whatif/build.gradle +++ b/whatif/build.gradle @@ -21,7 +21,10 @@ task coverageReport(type: JacocoReport, dependsOn: 'test') { } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { - kotlinOptions.freeCompilerArgs += ["-Xopt-in=kotlin.contracts.ExperimentalContracts"] + kotlinOptions.freeCompilerArgs += [ + "-Xexplicit-api=strict", + "-Xopt-in=kotlin.contracts.ExperimentalContracts" + ] } dependencies { diff --git a/whatif/src/main/java/com/skydoves/whatif/WhatIf.kt b/whatif/src/main/java/com/skydoves/whatif/WhatIf.kt index 5c0faed..ca0b8a2 100644 --- a/whatif/src/main/java/com/skydoves/whatif/WhatIf.kt +++ b/whatif/src/main/java/com/skydoves/whatif/WhatIf.kt @@ -375,7 +375,7 @@ public inline fun T?.whatIfNotNull( whatIf: (T) -> Unit ): T? { contract { - callsInPlace(whatIf, InvocationKind.EXACTLY_ONCE) + callsInPlace(whatIf, InvocationKind.AT_MOST_ONCE) } return this.whatIfNotNull( whatIf = whatIf,