All Projects → AhmedMourad0 → No Copy

AhmedMourad0 / No Copy

Licence: apache-2.0
A Kotlin compiler plugin that removes the `copy` method of data classes.

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to No Copy

Gradle Changelog Plugin
Plugin for parsing and managing the Changelog in a "keep a changelog" style.
Stars: ✭ 102 (+13.33%)
Mutual labels:  gradle-plugin, intellij-plugin
Scabbard
🗡 A tool to visualize Dagger 2 dependency graphs
Stars: ✭ 615 (+583.33%)
Mutual labels:  gradle-plugin, intellij-plugin
Kotlin
The Kotlin Programming Language.
Stars: ✭ 39,664 (+43971.11%)
Mutual labels:  gradle-plugin, intellij-plugin
Ktargeter
Kotlin compiler plugin that allows overriding annotation use-site targets for properties
Stars: ✭ 24 (-73.33%)
Mutual labels:  gradle-plugin, annotations
gradle-cleaner-intellij-plugin
Force clear delaying & no longer needed Gradle tasks.
Stars: ✭ 26 (-71.11%)
Mutual labels:  gradle-plugin, intellij-plugin
I18nplugin
Intellij idea i18next support plugin
Stars: ✭ 43 (-52.22%)
Mutual labels:  intellij-plugin, annotations
Debug Badge
Add badge(version code, version name, etc) for your DEBUG APK.
Stars: ✭ 75 (-16.67%)
Mutual labels:  gradle-plugin
Gradle Site Plugin
Documents Gradle tasks and plugins registered by your Gradle project
Stars: ✭ 83 (-7.78%)
Mutual labels:  gradle-plugin
Gradle Android Javadoc Plugin
Gradle plugin that generates Java Documentation from an Android Gradle project.
Stars: ✭ 73 (-18.89%)
Mutual labels:  gradle-plugin
Intellij Haskell
IntelliJ plugin for Haskell
Stars: ✭ 1,169 (+1198.89%)
Mutual labels:  intellij-plugin
Retrofit Cjs
retrofit-cjs 是一个基于JavaScript装饰器(Decorator)和 axios 实现的网络请求库, 支持Vue / React / react-native 等常用框架
Stars: ✭ 87 (-3.33%)
Mutual labels:  annotations
Androidanimationexercise
Android 动画各种实现,包括帧动画、补间动画和属性动画的总结分享
Stars: ✭ 1,254 (+1293.33%)
Mutual labels:  gradle-plugin
Intellij Gdscript
Godot Engine and GDScript support plugin for IntelliJ based IDEs
Stars: ✭ 83 (-7.78%)
Mutual labels:  intellij-plugin
Apkscale
A Gradle plugin to measure the app size impact of Android libraries
Stars: ✭ 76 (-15.56%)
Mutual labels:  gradle-plugin
Apiinspect
An api compatibility inspect gradle plugin.(一个Api兼容性检测的Gradle插件)
Stars: ✭ 84 (-6.67%)
Mutual labels:  gradle-plugin
Intellij Plugin Golangci Lint
GolangCI-Lint integration for IDEA
Stars: ✭ 74 (-17.78%)
Mutual labels:  intellij-plugin
Methodtraceman
用于快速找到高耗时方法,定位解决Android App卡顿问题。通过gradle plugin+ASM实现可配置范围的方法插桩来统计所有方法的耗时,并提供友好的界面展示,支持耗时筛选、线程筛选、方法名筛选等。(A Tool for Discovering High Time-consuming Methods for Android App)
Stars: ✭ 1,258 (+1297.78%)
Mutual labels:  gradle-plugin
Textannotationgraphs
A modular annotation system that supports complex, interactive annotation graphs embedded on top of sequences of text.
Stars: ✭ 73 (-18.89%)
Mutual labels:  annotations
Wsdl Creator
PHP WSDL Creator using PHPdoc (annotations, reflections).
Stars: ✭ 79 (-12.22%)
Mutual labels:  annotations
Rambuild
A plugin to make builds in gradle run on ram instead of the hard drive
Stars: ✭ 84 (-6.67%)
Mutual labels:  gradle-plugin

NoCopy Compiler Plugin CI Maven Central

A Kotlin compiler plugin that removes the `copy` method from data classes and enables using them as value-based classes.

Usage

Include the gradle plugin in your project and apply @NoCopy to your data class.

@NoCopy

@NoCopy prevents the kotlin compiler from generating the copy method:

@NoCopy
data class User(val name: String, val phoneNumber: String)
User("Ahmed", "+201234567890").copy(phoneNumber = "Happy birthday!") // Unresolved reference: copy

Why? I hear you ask.

The copy method of Kotlin data classes is a known language design problem, normally, you can't remove it, you can't override it, and you can document it.

Why would you want to do that? Well, there are a couple of reasons:

  • copy is a guaranteed source of binary incompatibility as you add new properties to the type when all you wanted was value semantics.
  • If you want value-based classes, copy will break your constructor invariants.
  • Private constructors are basically meaningless as long as copy exists.

Consider something like this:

data class User private constructor(val name: String, val phoneNumber: String) {
    companion object {
        fun of(name: String, phoneNumber: String): Either<UserException, User> {
            return if (bad) {
                exception.left() //You can throw an exception here if you like instead.
            } else {
                User(name, phoneNumber).right()
            }
        }
    }
}

It would look like all instances of User must be valid and can't be bad, right?

Wrong:

User.of("Ahmed", "+201234567890").copy(phoneNumber = "Gotcha")

copy can bypass all the validations of your data class, it breaks your domain rules!

For more detailed explanation, check out this article.

Installation

Using plugins DSL

  • In your module-level build.gradle:
plugins {
  id "dev.ahmedmourad.nocopy.nocopy-gradle-plugin" version "1.2.0"
}

Using legacy plugin application

  • In your project-level build.gradle:
buildscript {
    repositories {
        mavenCentral()
        // Or
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath "dev.ahmedmourad.nocopy:nocopy-gradle-plugin:1.2.0"
    }  
}
  • In your module-level build.gradle:
// For each module that needs to use the annotations
apply plugin: 'dev.ahmedmourad.nocopy.nocopy-gradle-plugin'

IDE Support

  • Install the IDEA plugin File -> Settings -> plugins -> Marketplace -> Kotlin NoCopy

  • Disable the default inspection File -> Settings -> Editor -> Inspections -> Kotlin -> Probably bugs -> Private data class constructor is.... Currently, you have to do this manually due to a bug with the Kotlin plugin, upvote.

Caveats

  • Currently, you cannot have a method named copy with the same signature (return type included) in your @NoCopy annotated data class or you will get IDE and compilation errors. (Attempting this, however, can be considered a bad practice as copy has a very defined behaviour in Kotlin, replacing it with your own custom implementation can be misleading)

  • Kotlin compiler plugins are not a stable API. Compiled outputs from this plugin should be stable, but usage in newer versions of kotlinc are not guaranteed to be stable.

Versions

Kotlin Version NoCopy Version
1.4.20 1.2.0
1.4.0 1.1.0
1.3.72 1.0.0

License

Copyright (C) 2020 Ahmed Mourad

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].