Kotlin Symbol Processor library to create Mutable and Immutable variants of objects.

Overview

Maven metadata URL

implier

Kotlin Symbol Processor plugin to create Mutable and Immutable variants of objects.

Examples

@ImmutableImpl
@MutableImpl
public interface Sample {
    val sample: String
}

Will generate next classes and functions:

public fun Sample.toImmutable(): ImmutableSample = ImmutableSample(sample)

public class ImmutableSample(
    public override val sample: String
) : Sample

public fun Sample.toMutable(): MutableSample = MutableSample(sample)

public class MutableSample(
    public override var sample: String
) : Sample

Implementation

For first, we need to add repository:

repositories {
    maven("https://maven.y9vad9.com")
}

And then we need to add dependency:

dependencies {
    implementation("com.y9vad9.implier:implier:$version") // annotations
    ksp("com.y9vad9.implier:ksp:$version") // ksp implementation of annotations
}
Comments
  • Generate mutable interface?

    Generate mutable interface?

    As you can see in https://github.com/y9vad9/implier/pull/10 I've added marker interfaces like Mutable<T> to allow slightly generic use of the generated APIs but in practice it would be far more useful if

    @ImmutableImpl
    @MutableImpl
    interface Sample {
        val sample: String
        val number: Int
    }
    

    generated:

    interface MutableSample: Sample {
        override var sample: String
        override var number: Int
    }
    
    class ImmutableSampleImpl(
      public override val sample: String,
      public override val number: Int
    ) : Sample
    
    class MutableSampleImpl(
      public override var sample: String,
      public override var number: Int
    ) : MutableSample
    

    Would happily update my PR to include this one.

    opened by manosbatsis 1
  • WiP: Add DTO codegen

    WiP: Add DTO codegen

    Nice work! Thought best to try contributing for my personal needs VS forking. This WiP PR adds support for generating DTOs, i.e. #9 nullable mutables that can be used for partial updates, e.g.

    @FactoryFunctionImpl(Visibility.INTERNAL)
    @ImmutableImpl(Visibility.INTERNAL)
    @DtoImpl(Visibility.INTERNAL)
    @MutableImpl(Visibility.INTERNAL)
    @BuilderImpl(visibility = Visibility.INTERNAL)
    @DSLBuilderImpl("sampleDSL", type = DSLBuilderImpl.Type.WITH_ACCESSORS, visibility = Visibility.INTERNAL)
    interface Sample {
        val sample: String
        val number: Int
    }
    

    Will generate:

    internal class DtoSample(
      public var sample: String?,
      public var number: Int?
    ) : Dto<Sample>
    
    internal fun Sample.toDto(): DtoSample = DtoSample(sample, number)
    
    internal fun Sample.toPatched(patch: Sample): Sample {
      val isMutable = this is MutableSample
      val base = if(isMutable) this as MutableSample else this.toMutable()
      patch.sample?.let{ 
        base.sample = it
      }
      patch.number?.let{ 
        base.number = it
      }
      return if(isMutable) this else base.toImmutable()
    }
    
    

    The toPatched shouldn't be so dependent on the generated MutableSample of course, see https://github.com/y9vad9/implier/issues/11

    enhancement 
    opened by manosbatsis 0
  • fix generated code

    fix generated code

    Generated code should be better. I suggest next:

    • adding kdoc to generated properties / functions from primary class / interface.
    • hiding DSL Implementation behine some interface:
      // note: just example name, you can change it via annotation argument
      fun buildSample(block: SampleDSLScope.() -> Unit) = ...
      
      interface SampleDSLScope {
          public fun setName(name: String)
          public fun setDescription(description: String)
      }
      
      internal class SampleDSLScopeImpl : SampleDSLScope { ... } // or we can implement it in function as anonymous object
      
    enhancement 
    opened by y9vad9 0
  • Generic marker forces to expose implier dependency

    Generic marker forces to expose implier dependency

    Describe the bug I have multimoduled project where I use implier. When I am trying to use generated entities I got next error:

    Cannot access 'com.y9vad9.implier.GenericMarker' which is a supertype of 'com.x.DtoUserEntity'. Check your module classpath for missing or conflicting dependencies
    

    To Reproduce Steps to reproduce the behavior:

    1. Create two modules
    2. Make a generation of some entity in module a.
    3. Implement a in b and use entity.
    4. See error

    Expected behavior I think it shouldn't expose implier dependency.

    bug 
    opened by y9vad9 1
  • Exclude specific properties from generation-related stuff

    Exclude specific properties from generation-related stuff

    Is your feature request related to a problem? Please describe. I'm using implier for generating database-related entities. My case is to not generate mutable property of identifier (I am not supposed to change it), but to make other properties mutable.

    Describe the solution you'd like Probably, we need to have annotation for such stuff. For example ShouldNotMutate or using existing Immutable annotation.

    enhancement 
    opened by y9vad9 1
  • `toPatched` requires Mutable variant even though it doesn't need it

    `toPatched` requires Mutable variant even though it doesn't need it

    Describe the bug toPatched function requires Mutable variant of entity even though it doesn't need it. It generates next code:

    public fun UserEntity.toPatched(patch: UserEntity): UserEntity {
      val isMutable = this is MutableUserEntity
      val base = if(isMutable) this as MutableUserEntity else this.toMutable()
      patch.id?.let{ 
        base.id = it
      }
      patch.firstName?.let{ 
        base.firstName = it
      }
      patch.lastName?.let{ 
        base.lastName = it
      }
      return if(isMutable) this else base.toImmutable()
    }
    

    To Reproduce Steps to reproduce the behavior:

    1. Create entity with annotation DtoImpl without using MutableImpl (use ImmutableImpl)
    2. Run generation
    3. Try to build the project
    4. See error

    Expected behavior I think it shouldn't use mutable variant (almost useless) at all or use it only when mutable variant is available (if we don't need producing instances).

    bug invalid 
    opened by y9vad9 0
  • Keep annotations on generated declarations

    Keep annotations on generated declarations

    Would be great if

    @MutableImpl(annotationPackages = [foo.Bar::class])
    interface Sample {
       @foo.Bar
        val sample: String
       @get:foo.Baz
        val number: Int
    }
    

    generated

    class MutableSample(
       @foo.Bar
       public override var sample: String,
       @get:foo.Baz
       public override var number: Int
    ) : Sample
    

    Happy to add a PR!

    enhancement 
    opened by manosbatsis 2
  • Data validation

    Data validation

    The most complex thing here is how to design validators. I see three ways:

    • (Not convenient for me, but still the way) design it with notations and annotations:
      // object here is notation, we assuming that user will
      // create object here, but not class. Anyway this will
      // be checked at compile time
      object NameValidator : Validator<String> {
          override fun validate(value: String): Boolean = ...
      }
      
      @Validate(NameValidator::class)
      val name: String = ""
      
    • (Not convenient for me, but still the way) design it with function name notations:
      var name: String = ...
      fun _checkName_(): Boolean = ...
      

      Transformed to →

      private var _name: String
      var name: String get() = _name set() = if(/* code from _checkName_() */) ... else ...
      
    • (Now I'm looking forward this) Wrap it with a type:
      val name: Validate<String> = Validate(default = ...) { name -> require(name.length in 1..30) { "Provide a correct name" } }
      

      Transformed to →

      var _name: String = default
      var name get() = _name set() = if(/* code from name.validate() */) ... else ...
      

    Originally posted by @y9san9 in https://github.com/y9vad9/implier/issues/1#issuecomment-984492558

    enhancement wontfix 
    opened by y9vad9 3
Releases(1.0.4)
Owner
Vadim Yaroschuk
Kotlin frontend (android) & backend developer. Currently working on Warscape (@warscapeorg).
Vadim Yaroschuk
glide's ksp compiler ,use kotlin symbol processor

glide-ksp glide's ksp compiler ,use kotlin symbol processor requirements library version kotlin >= 1.6.10 ksp 1.6.10-1.0.2 usage add jitpack repositor

Mistletoe 24 Oct 17, 2022
A Kotlin Symbol Processor to list sealed object instances.

Sealed Object Instances A Kotlin Symbol Processor to list sealed object instances. Usage Let's say you have a similar structure of sealed classes (or

Simon Marquis 17 Nov 17, 2022
BindsAdapter is an Android library to help you create and maintain Adapter class easier via ksp( Kotlin Symbol Processing).

BindsAdapter BindsAdapter is an Android library to help you create and maintain Adapter class easier via ksp( Kotlin Symbol Processing). Installation

Jintin 5 Jul 30, 2022
Mutator for Immutable Object

Mutator Why Mutator? As the immutable object becomes the default pattern of functional programming language, such as Value Object in Java, and Data Cl

Johnson Lee 4 Jun 12, 2022
Mocking for Kotlin/Native and Kotlin Multiplatform using the Kotlin Symbol Processing API (KSP)

Mockative Mocking for Kotlin/Native and Kotlin Multiplatform using the Kotlin Symbol Processing API (KSP). Installation Mockative uses KSP to generate

Mockative 121 Dec 26, 2022
Exploring Kotlin Symbol Processing - KSP. This is just an experiment.

KSP example Exploring Kotlin Symbol Processing - KSP. This is just an experiment. Project contains 2 modules Processing Example Processing module is t

Merab Tato Kutalia 12 Aug 23, 2022
Kotlin Symbol Processing (KSP) sample project

Kotlin Symbol Processing (KSP) Sample Project Sample annotation processor created with Kotlin Symbol Processing (KSP) API. The repository supplements

Pavlo Stavytskyi 33 Dec 23, 2022
An annotation processor library that automatically creates Hilt's `@Binds` functions and modules.

HiltBinder An annotation processor library that automatically creates Hilt's @Binds functions and modules. If you think this library is useful, please

SangMin Park 5 Sep 19, 2022
A library that extends the existing JDBC API so that data objects can be used as input (to set parameters) and output (from ResultSet's rows).

SqlObjectMapper This is a library that extends the existing JDBC API so that data objects can be used as input (to set parameters) and output (from Re

Qualified Cactus 2 Nov 7, 2022
Event State Processor Generator plugin is compatible with IntelliJ and Android Studio.

Event State Processor Generator plugin is compatible with IntelliJ and Android Studio. It provides source code generation for the EventStateProcessor Library to increase code productivity in Flutter apps development.

Extreme Vietnam Public 2 Dec 7, 2021
KSP annotation processor for Toothpick

toothpick-ksp KSP annotation processor for Toothpick. All credits go to olivierperez/ksp for the initial work on a KSP processor. Bear in mind this is

null 0 Oct 19, 2021
Kafka Streams Processor to unwrap CØSMOS blocks into CØSMOS transactions

Kafka Processor CØSMOS-Block A Kafka Streams Processor to unwrap CØSMOS blocks into CØSMOS transactions. Purpose The Kafka Processor CØSMOS-Block is b

OKP4 – Open Knowledge Protocol For 4 Dec 15, 2022
SeatBookView is an Android Studio Library that helps to make it easier to create Bus, Train, Cinema Theater Seat UI and all functionalities are given.

SeatBookView SeatBookView is an Android Studio Library that helps to make it easier to create Bus ?? , Train ?? , Cinema Theater Seat UI and all funct

Md. Zahidul Islam 3 Oct 15, 2022
Create libraries for all types of Kotlin projects: android, JVM, Multiplatform, Gradle plugins, and so on.

JavierSC Kotlin template Create libraries for all types of Kotlin projects: android, JVM, Multiplatform, Gradle plugins, and so on. Features Easy to p

Javier Segovia Córdoba 2 Dec 14, 2022
In this Repo i create public apis to serve apps, like muslim apps using Spring, kotlin, and microservices

spring-freelance-apis-kotlin In this Repo i create public apis to serve apps, like muslim apps using Spring, kotlin, and microservices This repo for l

null 6 Feb 13, 2022
To-Do-List - Create a To Do List-style App from scratch and drive the entire development process using Kotlin

To-Do-List! Crie um App no estilo "To Do List" do zero e conduza todo o processo

River Diniz 0 Feb 14, 2022
A simple android library which helps you to create a curved bottom navigation

CurvedBottomNavigation A simple android library which helps you to create a curved bottom navigation DEMO Setup Update your module level build.gradle

Qama A. Safadi 92 Dec 29, 2022
An application to follow popular movies and tv series and create watch list

MoviesAndTV MoviesAndTV is an application to follow popular movies and tv series and create watch list from your favorite tv series and movies. Also y

Elvan Erdem 3 May 25, 2022