ENT-11351 - Compiler warnings pass 5 (#7666)

* Reduce compiler warnings

* Address PR review comments

* Acually make use of capitalize(),decapitalize()
This commit is contained in:
Chris Cochrane 2024-01-30 18:09:55 +00:00 committed by GitHub
parent 9b794795a0
commit ee71bf5a78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 129 additions and 57 deletions

View File

@ -0,0 +1,5 @@
// Implement the new post-1.2 APIs which are used by core and serialization
@file:Suppress("unused")
package kotlin
inline val Char.code: Int get() = this.toInt()

View File

@ -0,0 +1,24 @@
// Implement the new post-1.2 APIs which are used by core and serialization
@file:Suppress("NOTHING_TO_INLINE", "unused")
package kotlin.text
import java.util.Locale
inline fun Char.isLowerCase(): Boolean = Character.isLowerCase(this)
public fun Char.lowercase(locale: Locale): String = toString().lowercase(locale)
inline fun Char.lowercaseChar(): Char = Character.toLowerCase(this)
inline fun Char.uppercase(): String = toString().uppercase()
fun Char.uppercase(locale: Locale): String = toString().uppercase(locale)
inline fun Char.titlecaseChar(): Char = Character.toTitleCase(this)
fun Char.titlecase(locale: Locale): String {
val localizedUppercase = uppercase(locale)
if (localizedUppercase.length > 1) {
return if (this == '\u0149') localizedUppercase else localizedUppercase[0] + localizedUppercase.substring(1).lowercase()
}
if (localizedUppercase != uppercase()) {
return localizedUppercase
}
return titlecaseChar().toString()
}

View File

@ -0,0 +1,12 @@
// Implement the new post-1.2 APIs which are used by core and serialization
@file:Suppress("NOTHING_TO_INLINE", "unused")
package kotlin.text
// StringBuilder
fun StringBuilder.append(vararg value: String?): StringBuilder {
for (item in value)
append(item)
return this
}
inline fun StringBuilder.appendLine(): StringBuilder = append('\n')
inline fun StringBuilder.appendLine(value: String?): StringBuilder = append(value).appendLine()

View File

@ -0,0 +1,8 @@
// Implement the new post-1.2 APIs which are used by core and serialization
@file:Suppress("unused")
package kotlin.text
inline fun String.replaceFirstChar(transform: (Char) -> CharSequence): String {
return if (isNotEmpty()) transform(this[0]).toString() + substring(1) else this
}

View File

@ -5,6 +5,8 @@ package kotlin.text
import java.util.Locale
// String extensions
inline fun String.lowercase(): String = (this as java.lang.String).toLowerCase(Locale.ROOT)
inline fun String.lowercase(locale: Locale): String = (this as java.lang.String).toLowerCase(locale)
inline fun String.uppercase(): String = (this as java.lang.String).toUpperCase(Locale.ROOT)
inline fun String.uppercase(locale: Locale): String = (this as java.lang.String).toUpperCase(locale)

View File

@ -11,6 +11,7 @@ import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.parseAsHex
import net.corda.core.utilities.toHexString
import java.security.MessageDigest
import java.util.Locale
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
import java.util.function.Supplier
@ -182,7 +183,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
*/
@JvmStatic
fun parse(str: String?): SHA256 {
return str?.toUpperCase()?.parseAsHex()?.let {
return str?.uppercase(Locale.getDefault())?.parseAsHex()?.let {
when (it.size) {
32 -> interner.intern(SHA256(it))
else -> throw IllegalArgumentException("Provided string is ${it.size} bytes not 32 bytes in hex: $str")

View File

@ -5,6 +5,7 @@ import net.corda.core.internal.loadClassOfType
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.Collections
import java.util.Locale
import java.util.concurrent.ConcurrentHashMap
sealed class DigestAlgorithmFactory {
@ -44,7 +45,7 @@ sealed class DigestAlgorithmFactory {
private val factories = ConcurrentHashMap<String, DigestAlgorithmFactory>()
private fun check(algorithm: String) {
require(algorithm.toUpperCase() == algorithm) { "Hash algorithm name $this must be in the upper case" }
require(algorithm.uppercase(Locale.getDefault()) == algorithm) { "Hash algorithm name $this must be in the upper case" }
require(algorithm !in BANNED) { "$algorithm is forbidden!" }
}

View File

@ -292,7 +292,7 @@ abstract class SignTransactionFlow @JvmOverloads constructor(val otherSideSessio
try {
checkTransaction(stx)
} catch (e: Exception) {
if (e is IllegalStateException || e is IllegalArgumentException || e is AssertionError)
if (e is IllegalStateException || e is IllegalArgumentException)
throw FlowException(e)
else
throw e

View File

@ -26,7 +26,7 @@ class PartyAndCertificate(val certPath: CertPath) {
require(certs.size >= 2) { "Certificate path must at least include subject and issuing certificates" }
certificate = certs[0] as X509Certificate
val role = CertRole.extract(certificate)
require(role?.isIdentity ?: false) { "Party certificate ${certificate.subjectDN} does not have a well known or confidential identity role. Found: $role" }
require(role?.isIdentity ?: false) { "Party certificate ${certificate.getSubjectX500Principal()} does not have a well known or confidential identity role. Found: $role" }
}
@Transient
@ -46,6 +46,7 @@ class PartyAndCertificate(val certPath: CertPath) {
fun verify(trustAnchor: TrustAnchor): PKIXCertPathValidatorResult = verify(setOf(trustAnchor))
/** Verify the certificate path is valid against one of the specified trust anchors. */
@Suppress("UNCHECKED_CAST")
fun verify(trustAnchors: Set<TrustAnchor>): PKIXCertPathValidatorResult {
val result = certPath.validate(trustAnchors)
// Apply Corda-specific validity rules to the chain. This only applies to chains with any roles present, so
@ -60,7 +61,7 @@ class PartyAndCertificate(val certPath: CertPath) {
throw CertPathValidatorException("Child certificate whose issuer includes a Corda role, must also specify Corda role")
}
if (!role.isValidParent(parentRole)) {
val certificateString = certificate.subjectDN.toString()
val certificateString = certificate.getSubjectX500Principal().toString()
throw CertPathValidatorException("The issuing certificate for $certificateString has role $parentRole, expected one of ${role.validParents}")
}
}

View File

@ -11,6 +11,7 @@ import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.security.PublicKey
import java.util.Locale
import java.util.jar.JarInputStream
const val DEPLOYED_CORDAPP_UPLOADER = "app"
@ -60,6 +61,7 @@ abstract class AbstractAttachment(dataLoader: () -> ByteArray, val uploader: Str
openAsJAR().use(JarSignatureCollector::collectSigners)
}
@Suppress("OVERRIDE_DEPRECATION")
override val signers: List<Party> by lazy {
openAsJAR().use(JarSignatureCollector::collectSigningParties)
}
@ -71,7 +73,7 @@ abstract class AbstractAttachment(dataLoader: () -> ByteArray, val uploader: Str
@Throws(IOException::class)
fun JarInputStream.extractFile(path: String, outputTo: OutputStream) {
fun String.norm() = toLowerCase().split('\\', '/') // XXX: Should this really be locale-sensitive?
fun String.norm() = lowercase(Locale.getDefault()).split('\\', '/') // XXX: Should this really be locale-sensitive?
val p = path.norm()
while (true) {
val e = nextJarEntry ?: break

View File

@ -52,6 +52,7 @@ import java.security.cert.X509Certificate
import java.time.Duration
import java.time.temporal.Temporal
import java.util.Collections
import java.util.Locale
import java.util.PrimitiveIterator
import java.util.Spliterator
import java.util.Spliterator.DISTINCT
@ -341,9 +342,7 @@ val <T : Any> Class<T>.kotlinObjectInstance: T? get() {
field?.let {
if (it.type == this && it.isPublic && it.isStatic && it.isFinal) {
it.isAccessible = true
// TODO JDK17: Why does uncheckedCast(...) cause class cast exception?
// uncheckedCast(it.get(null))
@Suppress("UNCHECKED_CAST")
it.get(null) as T
} else {
null
@ -624,3 +623,14 @@ val Logger.level: Level
const val JAVA_1_2_CLASS_FILE_FORMAT_MAJOR_VERSION = 46
const val JAVA_17_CLASS_FILE_FORMAT_MAJOR_VERSION = 61
/**
* String extension functions - to keep calling code readable following upgrade to Kotlin 1.9
*/
fun String.capitalize() : String {
return this.replaceFirstChar { it.titlecase(Locale.getDefault()) }
}
fun String.decapitalize() : String {
return this.replaceFirstChar { it.lowercase(Locale.getDefault()) }
}

View File

@ -123,24 +123,24 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
override fun toString(): String {
val sb = StringBuilder()
sb.appendln("${consumed.size} consumed, ${produced.size} produced")
sb.appendln("")
sb.appendln("Consumed:")
sb.appendLine("${consumed.size} consumed, ${produced.size} produced")
sb.appendLine("")
sb.appendLine("Consumed:")
consumed.forEach {
sb.appendln("${it.ref}: ${it.state}")
sb.appendLine("${it.ref}: ${it.state}")
}
sb.appendln("")
sb.appendln("Produced:")
sb.appendLine("")
sb.appendLine("Produced:")
produced.forEach {
sb.appendln("${it.ref}: ${it.state}")
sb.appendLine("${it.ref}: ${it.state}")
}
sb.appendln("References:")
sb.appendLine("References:")
references.forEach {
sb.appendln("${it.ref}: ${it.state}")
sb.appendLine("${it.ref}: ${it.state}")
}
sb.appendln("Consuming TxIds:")
sb.appendLine("Consuming TxIds:")
consumingTxIds.forEach {
sb.appendln("${it.key}: ${it.value}")
sb.appendLine("${it.key}: ${it.value}")
}
return sb.toString()
}

View File

@ -26,7 +26,7 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
/** X500Name of participant parties **/
@Transient
open var participants: MutableSet<AbstractParty>? = null,
var participants: MutableSet<AbstractParty>? = null,
/**
* Represents a [LinearState] [UniqueIdentifier]
@ -51,7 +51,7 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
/** X500Name of participant parties **/
@Transient
open var participants: MutableSet<AbstractParty?>? = null,
var participants: MutableSet<AbstractParty?>? = null,
/** [OwnableState] attributes */

View File

@ -362,29 +362,29 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
override fun toString(): String {
val buf = StringBuilder()
buf.appendln("Transaction:")
buf.appendLine("Transaction:")
for (reference in references) {
val emoji = Emoji.rightArrow
buf.appendln("${emoji}REFS: $reference")
buf.appendLine("${emoji}REFS: $reference")
}
for (input in inputs) {
val emoji = Emoji.rightArrow
buf.appendln("${emoji}INPUT: $input")
buf.appendLine("${emoji}INPUT: $input")
}
for ((data) in outputs) {
val emoji = Emoji.leftArrow
buf.appendln("${emoji}OUTPUT: $data")
buf.appendLine("${emoji}OUTPUT: $data")
}
for (command in commands) {
val emoji = Emoji.diamond
buf.appendln("${emoji}COMMAND: $command")
buf.appendLine("${emoji}COMMAND: $command")
}
for (attachment in attachments) {
val emoji = Emoji.paperclip
buf.appendln("${emoji}ATTACHMENT: $attachment")
buf.appendLine("${emoji}ATTACHMENT: $attachment")
}
if (networkParametersHash != null) {
buf.appendln("PARAMETERS HASH: $networkParametersHash")
buf.appendLine("PARAMETERS HASH: $networkParametersHash")
}
return buf.toString()
}

View File

@ -60,6 +60,7 @@ sealed class Try<out A> {
* Maps the given function to the values from this [Success] and [other], or returns `this` if this is a [Failure]
* or [other] if [other] is a [Failure].
*/
@Suppress("UNCHECKED_CAST")
inline fun <B, C> combine(other: Try<B>, function: (A, B) -> C): Try<C> = when (this) {
is Success -> when (other) {
is Success -> Success(function(value, other.value))

View File

@ -89,10 +89,10 @@ open class InternalUtilsTest {
@Test(timeout=300_000)
fun `Stream toTypedArray works`() {
val a: Array<String> = Stream.of("one", "two").toTypedArray() as Array<String>
val a: Array<String> = uncheckedCast(Stream.of("one", "two").toTypedArray())
assertEquals(Array<String>::class.java, a.javaClass)
assertArrayEquals(arrayOf("one", "two"), a)
val b: Array<String?> = Stream.of("one", "two", null).toTypedArray() as Array<String?>
val b: Array<String?> = uncheckedCast(Stream.of("one", "two", null).toTypedArray())
assertEquals(Array<String?>::class.java, b.javaClass)
assertArrayEquals(arrayOf("one", "two", null), b)
}

View File

@ -21,7 +21,7 @@ class CordaFutureTest {
assertEquals(100, e.fork { 100 }.getOrThrow())
val x = Exception()
val f = e.fork { throw x }
Assertions.assertThatThrownBy { f.getOrThrow() }.isSameAs(x)
Assertions.assertThatThrownBy { f.getOrThrow<Nothing>() }.isSameAs(x)
} finally {
e.shutdown()
}
@ -54,7 +54,7 @@ class CordaFutureTest {
val x = Exception()
val g = f.map { throw x }
f.set(100)
Assertions.assertThatThrownBy { g.getOrThrow() }.isSameAs(x)
Assertions.assertThatThrownBy { g.getOrThrow<Nothing>() }.isSameAs(x)
}
run {
val block = mock<(Any?) -> Any?>()

View File

@ -48,7 +48,6 @@ object AllButBlacklisted : ClassWhitelist {
Runtime::class.java.name,
ZipFile::class.java.name,
Provider::class.java.name,
SecurityManager::class.java.name,
Random::class.java.name,
// Known blacklisted interfaces.

View File

@ -255,7 +255,7 @@ object AMQPCharPropertyReadStrategy : PropertyReadStrategy {
override fun readProperty(obj: Any?, schemas: SerializationSchemas,
input: DeserializationInput, context: SerializationContext
): Any? {
return if (obj == null) null else (obj as Short).toChar()
return if (obj == null) null else (obj as Short).toInt().toChar()
}
}
@ -266,6 +266,6 @@ class AMQPCharPropertyWriteStategy(private val reader: PropertyReader) : Propert
context: SerializationContext, debugIndent: Int
) {
val input = reader.read(obj)
if (input != null) data.putShort((input as Char).toShort()) else data.putNull()
if (input != null) data.putShort((input as Char).code.toShort()) else data.putNull()
}
}

View File

@ -1,6 +1,7 @@
package net.corda.serialization.internal.amqp
import com.google.common.reflect.TypeToken
import net.corda.core.internal.decapitalize
import net.corda.core.internal.isPublic
import net.corda.core.serialization.SerializableCalculatedProperty
import net.corda.serialization.internal.amqp.MethodClassifier.*
@ -20,9 +21,9 @@ import java.util.*
*/
data class PropertyDescriptor(val field: Field?, val setter: Method?, val getter: Method?) {
override fun toString() = StringBuilder("").apply {
appendln("Property - ${field?.name ?: "null field"}\n")
appendln(" getter - ${getter?.name ?: "no getter"}")
appendln(" setter - ${setter?.name ?: "no setter"}")
appendLine("Property - ${field?.name ?: "null field"}\n")
appendLine(" getter - ${getter?.name ?: "no getter"}")
appendLine(" setter - ${setter?.name ?: "no setter"}")
}.toString()
/**
@ -159,7 +160,7 @@ private fun getPropertyNamedMethod(method: Method): PropertyNamedMethod? {
return propertyMethodRegex.find(method.name)?.let { result ->
PropertyNamedMethod(
result.groups[2]!!.value,
MethodClassifier.valueOf(result.groups[1]!!.value.toUpperCase()),
MethodClassifier.valueOf(result.groups[1]!!.value.uppercase(Locale.getDefault())),
method)
}
}

View File

@ -322,22 +322,22 @@ data class TransformsSchema(val types: Map<String, EnumMap<TransformTypes, Mutab
val sb = StringBuilder("")
val indent = Indent("")
sb.appendln("$indent<type-transforms>")
sb.appendLine("$indent<type-transforms>")
types.forEach { type ->
val indent = Indent(indent)
sb.appendln("$indent<type name=${type.key.esc()}>")
sb.appendLine("$indent<type name=${type.key.esc()}>")
type.value.forEach { transform ->
val indent = Indent(indent)
sb.appendln("$indent<transforms type=${transform.key.name.esc()}>")
sb.appendLine("$indent<transforms type=${transform.key.name.esc()}>")
transform.value.forEach {
val indent = Indent(indent)
sb.appendln("$indent<transform ${it.params()} />")
sb.appendLine("$indent<transform ${it.params()} />")
}
sb.appendln("$indent</transforms>")
sb.appendLine("$indent</transforms>")
}
sb.appendln("$indent</type>")
sb.appendLine("$indent</type>")
}
sb.appendln("$indent</type-transforms>")
sb.appendLine("$indent</type-transforms>")
return sb.toString()
}

View File

@ -2,6 +2,7 @@ package net.corda.serialization.internal.amqp.custom
import net.corda.core.CordaRuntimeException
import net.corda.core.CordaThrowable
import net.corda.core.internal.capitalize
import net.corda.core.serialization.SerializationFactory
import net.corda.core.utilities.contextLogger
import net.corda.serialization.internal.amqp.*

View File

@ -2,6 +2,8 @@
package net.corda.serialization.internal.carpenter
import com.google.common.base.MoreObjects
import net.corda.core.internal.capitalize
import net.corda.core.internal.decapitalize
import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.contextLogger

View File

@ -1,5 +1,6 @@
package net.corda.serialization.internal.model
import net.corda.core.internal.decapitalize
import net.corda.core.internal.isAbstractClass
import net.corda.core.internal.isConcreteClass
import net.corda.core.internal.isJdkClass

View File

@ -364,7 +364,7 @@ class DeserializeNeedingCarpentrySimpleTypesTest : AmqpCarpenterBase(AllWhitelis
assertNotEquals(clazz, deserializedObj::class.java)
assertTrue(deserializedObj is I)
assertEquals(testVal, (deserializedObj as I).getName())
assertEquals(testVal, deserializedObj.getName())
}
@Test(timeout=300_000)

View File

@ -133,7 +133,7 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase(AllWhitelist) {
val deserializedObj = DeserializationInput(sf2).deserializeWithoutAndWithCarpenter(serialisedBytes)
assertTrue(deserializedObj is I)
assertEquals(testVal, (deserializedObj as I).getName())
assertEquals(testVal, deserializedObj.getName())
}
@Test(timeout=300_000)
@ -270,7 +270,7 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase(AllWhitelist) {
val deserializedObj = DeserializationInput(sf2).deserializeWithoutAndWithCarpenter(serialisedBytes)
assertTrue(deserializedObj is I)
assertEquals("timmy", (deserializedObj as I).getName())
assertEquals("timmy", deserializedObj.getName())
assertEquals("timmy", deserializedObj::class.java.getMethod("getName").invoke(deserializedObj))
assertEquals(12, deserializedObj::class.java.getMethod("getAge").invoke(deserializedObj))
}

View File

@ -8,9 +8,9 @@ import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.hamcrest.Matchers.equalTo
import org.hamcrest.Matchers.`is`
import org.junit.Assert
import org.junit.Test
import java.util.Optional
import org.hamcrest.MatcherAssert.assertThat
class OptionalSerializationTests {
@ -28,7 +28,7 @@ class OptionalSerializationTests {
val deserialized = DeserializationInput(factory).deserialize(bytes)
val deserialized2 = DeserializationInput(deserializerFactory).deserialize(bytes)
Assert.assertThat(deserialized, `is`(equalTo(deserialized2)))
Assert.assertThat(obj, `is`(equalTo(deserialized2)))
assertThat(deserialized, `is`(equalTo(deserialized2)))
assertThat(obj, `is`(equalTo(deserialized2)))
}
}

View File

@ -3,10 +3,10 @@ package net.corda.serialization.internal.amqp.custom
import net.corda.serialization.internal.amqp.SerializerFactory
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.nullValue
import org.junit.Assert.assertThat
import org.junit.Test
import org.mockito.Mockito
import java.util.*
import org.hamcrest.MatcherAssert.assertThat
class OptionalSerializerTest {
@Test(timeout=300_000)

View File

@ -1,6 +1,7 @@
package net.corda.serialization.internal.carpenter
import com.google.common.reflect.TypeToken
import net.corda.core.internal.capitalize
import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.SerializedBytes

View File

@ -214,7 +214,7 @@ class LocalTypeModelTests {
TWO;
override fun toString(): String {
return "[${name.toLowerCase()}]"
return "[${name.lowercase(Locale.getDefault())}]"
}
}

View File

@ -2,7 +2,7 @@ package net.corda.coretesting.internal
import org.assertj.core.api.Assertions.catchThrowable
import org.hamcrest.Matchers.isA
import org.junit.Assert.assertThat
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import java.io.Closeable
import java.io.InputStream