All platforms working with a smoke test, seems theres a bug with JS compiler (TODO in smoke test desccribes it)

This commit is contained in:
Ugljesa Jovanovic authored and Ugljesa Jovanovic committed 2020-08-08 19:54:48 +02:00
1 parent 1f0eaf59ca
commit 5d61858f81
14 files changed
+231 -62

No files matched your search

@@ -72,6 +72,7 @@ class ParameterDefinition(
val isActuallyAnOutputParam: Boolean = false,
val isStateType: Boolean = false,
val dropParameterFromDefinition: Boolean = false,
val specificJvmInitializer: String? = null,
)
interface GeneralTypeDefinition {
@@ -108,6 +109,7 @@ fun innerClassDef(
javaName: String,
jsName: String,
nativeName: String,
specificConstructor : String? = null,
body: InnerClassDefinition.() -> Unit = {}
): InnerClassDefinition {
val genClass = InnerClassDefinition(
@@ -14,7 +14,7 @@ fun ClassDefinition.defineGenericHashFunctions() {
+innerClassDef(
"GenericHashState",
"ByteArray",
"kotlin.ByteArray",
"Uint8Array",
"crypto_generichash_blake2b_state"
)
@@ -29,7 +29,8 @@ fun ClassDefinition.defineGenericHashFunctions() {
"state",
CustomTypeDefinition((withPackageName("GenericHashState"))),
isStateType = true,
dropParameterFromDefinition = true
dropParameterFromDefinition = true,
specificJvmInitializer = "sodium.crypto_generichash_statebytes()"
)
+ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES)
+ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true)
@@ -18,6 +18,9 @@ fun ClassDefinition.defineHashFunctions() {
"crypto_hash_sha256_state"
)
+funcDef(
"crypto_hash_sha256_init_spec",
"crypto_hash_sha256_init",
"crypto_hash_sha256_init",
"crypto_hash_sha256_init",
CustomTypeDefinition(ClassName(packageName, "Sha256State")),
dynamicJsReturn = true,
@@ -73,19 +73,19 @@ object JsLibsodiumGenerator {
val constructJsCall = StringBuilder()
when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
constructJsCall.append("return getSodium().${methodDefinition.javaName}")
constructJsCall.append("return getSodium().${methodDefinition.jsName}")
constructJsCall.append(paramsToString(methodDefinition) + ".toUByteArray()")
}
TypeDefinition.INT -> {
constructJsCall.append("return getSodium().${methodDefinition.javaName}")
constructJsCall.append("return getSodium().${methodDefinition.jsName}")
constructJsCall.append(paramsToString(methodDefinition))
}
TypeDefinition.UNIT -> {
constructJsCall.append("getSodium().${methodDefinition.javaName}")
constructJsCall.append("getSodium().${methodDefinition.jsName}")
constructJsCall.append(paramsToString(methodDefinition))
}
is CustomTypeDefinition -> {
constructJsCall.append("return getSodium().${methodDefinition.javaName}")
constructJsCall.append("return getSodium().${methodDefinition.jsName}")
constructJsCall.append(paramsToString(methodDefinition))
}
}
@@ -1,7 +1,18 @@
package com.ionspin.kotlin.crypto.generator.libsodium.generator
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.*
import com.squareup.kotlinpoet.*
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.CustomTypeDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ParameterDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeAliasSpec
/**
* Created by Ugljesa Jovanovic
@@ -49,10 +60,17 @@ object JvmLibsodiumGenerator {
methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList
var returnModifierFound = false
var returnModifierName = ""
lateinit var actualReturnParameterDefinition: ParameterDefinition
var actualReturnTypeFound: Boolean = false
for (paramDefinition in methodDefinition.parameterList) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
if (paramDefinition.isStateType && methodDefinition.isStateCreationFunction) {
createStateParam(paramDefinition, methodBuilder)
}
if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
}
if (paramDefinition.modifiesReturn) {
if (returnModifierFound == true) {
throw RuntimeException("Return modifier already found")
@@ -60,33 +78,98 @@ object JvmLibsodiumGenerator {
returnModifierFound = true
returnModifierName = paramDefinition.parameterName
}
if (paramDefinition.isActuallyAnOutputParam) {
actualReturnParameterDefinition = paramDefinition
actualReturnTypeFound = true
}
}
if (actualReturnTypeFound) {
if (returnModifierFound) {
createOutputParam(
actualReturnParameterDefinition,
returnModifierName,
methodBuilder
)
} else {
if (methodDefinition.outputLengthWhenArray == -1) {
throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}")
}
createOutputParam(
actualReturnParameterDefinition,
methodDefinition.outputLengthWhenArray.toString(),
methodBuilder
)
}
}
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
constructJvmCall.append("return sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
}
TypeDefinition.INT -> {
constructJvmCall.append("return sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
}
TypeDefinition.UNIT -> {
constructJvmCall.append("sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
}
is CustomTypeDefinition -> {
constructJvmCall.append("return sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
if (methodDefinition.isStateCreationFunction) {
constructJvmCall.append("sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.addStatement("return state")
} else if (actualReturnTypeFound) {
constructJvmCall.append("sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.addStatement("return out")
} else {
when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.addStatement("return result")
}
TypeDefinition.INT -> {
constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.addStatement("return result")
}
TypeDefinition.UNIT -> {
constructJvmCall.append("sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
is CustomTypeDefinition -> {
constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.addStatement("return result")
}
}
}
methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.returns(methodDefinition.returnType.typeName)
return methodBuilder.build()
}
fun createOutputParam(outputParam: ParameterDefinition, length: String?, methodBuilder: FunSpec.Builder) {
/*
val hashed = ByteArray(Sha256Properties.MAX_HASH_BYTES)
sodium.crypto_hash_sha256_final(state, hashed)
return hashed.asUByteArray()
*/
when (outputParam.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
methodBuilder.addStatement("val out = UByteArray($length)")
}
else -> {
throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}")
}
}
}
fun createStateParam(stateParameterDefinition: ParameterDefinition, methodBuilder: FunSpec.Builder) {
/*
val state = Hash.State256()
*/
val specificInitializer = stateParameterDefinition.specificJvmInitializer ?: ""
methodBuilder.addStatement("val state = ${stateParameterDefinition.parameterType.typeName}($specificInitializer)")
}
fun paramsToString(methodDefinition: FunctionDefinition) : String {
val paramsBuilder = StringBuilder()
paramsBuilder.append("(")
@@ -49,7 +49,7 @@ object NativeLibsodiumGenerator {
val byteEmitter = PropertySpec.builder("_emitByte", Byte::class.asTypeName())
byteEmitter.initializer(CodeBlock.of("0"))
val byteArrayEmitter = PropertySpec.builder("_emitByteArray", ByteArray::class.asTypeName())
byteArrayEmitter.initializer(CodeBlock.of("ByteArray(0) {}"))
byteArrayEmitter.initializer(CodeBlock.of("ByteArray(0)"))
commonClassSpec.addProperty(byteEmitter.build())
commonClassSpec.addProperty(byteArrayEmitter.build())
fileBuilder.addType(commonClassSpec.build())
@@ -4,6 +4,7 @@ import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ClassDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.TypeSpec
/**
@@ -17,6 +18,15 @@ fun createClass(
methodCreator: (FunctionDefinition) -> FunSpec
): TypeSpec.Builder {
val commonClassBuilder = TypeSpec.classBuilder(classDefinition.name)
// Ugly
val primaryConstructor = FunSpec.constructorBuilder()
if (multiplatformModifier == MultiplatformModifier.EXPECT) {
primaryConstructor.addModifiers(KModifier.INTERNAL)
} else {
primaryConstructor.addModifiers(KModifier.INTERNAL, KModifier.ACTUAL)
}
commonClassBuilder.primaryConstructor(primaryConstructor.build())
commonClassBuilder.modifiers += multiplatformModifier.modifierList
for (methodDefinition in classDefinition.methods) {
commonClassBuilder.addFunction(methodCreator(methodDefinition))