All Downloads are FREE. Search and download functionalities are using the official Maven repository.

codegen.PreferencesClasses.kt Maven / Gradle / Ivy

/*
 * Copyright (C) 2024 Meowool 
 *
 * This file is part of the MMKV-KTX project .
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.meowool.mmkv.ktx.compiler.codegen

import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.meowool.mmkv.ktx.compiler.Names.MMKV
import com.meowool.mmkv.ktx.compiler.Names.StateFlow
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.UNIT
import com.squareup.kotlinpoet.ksp.toClassName
import com.squareup.kotlinpoet.LambdaTypeName.Companion.get as lambdaType

class PreferencesClasses : CodegenStep() {
  override fun generate() = context.preferences.process(::generatePreferences)

  private fun generatePreferences(preferences: KSClassDeclaration) {
    val className = context.preferencesClassName(preferences)

    val mmkvSpec = PropertySpec.builder("mmkv", MMKV)
      .addModifiers(KModifier.ABSTRACT)
      .build()

    val getSpec = FunSpec.builder("get")
      .addModifiers(KModifier.ABSTRACT)
      .returns(preferences.toClassName())
      .build()

    val mutableSpec = FunSpec.builder("mutable")
      .addModifiers(KModifier.ABSTRACT)
      .returns(context.mutableClassName(preferences))
      .build()

    val updateSpec = FunSpec.builder("update")
      .addModifiers(KModifier.ABSTRACT)
      .addParameter("mutable", context.mutableClassName(preferences))
      .build()

    val asStateFlowSpec = FunSpec.builder("asStateFlow")
      .addModifiers(KModifier.ABSTRACT)
      .returns(StateFlow.parameterizedBy(preferences.toClassName()))
      .build()

    val mapStateFlowSpec = FunSpec.builder("mapStateFlow")
      .addModifiers(KModifier.ABSTRACT)
      .addTypeVariable(TypeVariableName("R"))
      .addParameter(
        name = "transform",
        type = lambdaType(
          parameters = arrayOf(preferences.toClassName()),
          returnType = TypeVariableName("R")
        )
      )
      .returns(StateFlow.parameterizedBy(TypeVariableName("R")))
      .build()

    val classSpec = TypeSpec.interfaceBuilder(className)
      .addProperty(mmkvSpec)
      .addFunction(getSpec)
      .addFunction(mutableSpec)
      .addFunction(updateSpec)
      .addFunction(asStateFlowSpec)
      .addFunction(mapStateFlowSpec)
      .build()

    val updateInlineSpec = FunSpec.builder("update")
      .addModifiers(KModifier.INLINE)
      .addParameter(
        name = "block",
        type = lambdaType(
          parameters = arrayOf(context.mutableClassName(preferences)),
          returnType = UNIT
        )
      )
      .receiver(className)
      .addStatement("return update(this.mutable().apply(block))")
      .build()

    // TODO: Add KDoc for generated symbols.
    FileSpec.builder(className)
      .addType(classSpec)
      .addFunction(updateInlineSpec)
      .build()
      .write(preferences)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy