Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Commit 3961614

Browse files
Merge pull request #1 from ThinkingLogic/develop
Merging develop into master
2 parents 683f67a + 94b5eb2 commit 3961614

File tree

32 files changed

+1092
-270
lines changed

32 files changed

+1092
-270
lines changed

README.md

+94-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,103 @@
22
A builder annotation for Kotlin interoperability with Java.
33
This project aims to be a minimal viable replacement for the Lombok @Builder plugin for Kotlin code.
44

5-
[![Build Status](https://travis-ci.com/ThinkingLogic/kotlin-builder-annotation.svg?branch=master)](https://travis-ci.com/ThinkingLogic/kotlin-builder-annotation.svg?branch=master)
5+
[![Build Status](https://travis-ci.com/ThinkingLogic/kotlin-builder-annotation.svg?branch=master)](https://travis-ci.com/ThinkingLogic/kotlin-builder-annotation)
6+
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
67

7-
Named constructor parameters with optional values mean that Kotlin code doesn't require the builder pattern any more,
8-
_unless_ you're writing code that will be used by Java projects
9-
(else you consign your java clients to using unhelpful constructors with many parameters).
8+
## Usage
9+
TODO: gradle and maven
1010

11+
#### Annotate your class with the @Builder annotation
12+
```kotlin
13+
import com.thinkinglogic.builder.annotation.Builder
1114

15+
@Builder
16+
data class MyDataClass(
17+
val notNullString: String,
18+
val nullableString: String?
19+
)
20+
```
21+
That's it! Client code can now use a builder to construct instances of your class.
22+
23+
Unlike Lombok there's no bytecode manipulation, so we don't have a `MyDataClass.builder()` static method.
24+
Instead we create a `new MyDataClassBuilder()`:
25+
26+
```java
27+
public class MyDataFactory {
28+
public MyDataClass create() {
29+
return new MyDataClassBuilder()
30+
.notNullString("Foo")
31+
.nullableString("Bar")
32+
.build();
33+
}
34+
}
35+
```
36+
The builder will check for required fields, so
37+
`new MyDataClassBuilder().notNullString(null);`
38+
would throw an `IllegalArgumentException` and
39+
`new MyDataClassBuilder().nullableString("Bar").build();`
40+
would throw an `IllegalStateException` naming the required field ('notNullString' in this case), while
41+
`new MyDataClassBuilder().notNullString("Foo").build();`
42+
would return a new instance with a null value for 'nullableString'.
43+
44+
#### Default values
45+
Kotlin doesn't retain information about default values after compilation, so it cannot be accessed during annotation processing.
46+
Instead we must use the `@DefaultValue` annotation to tell the builder about it:
47+
```kotlin
48+
import com.thinkinglogic.builder.annotation.Builder
49+
import com.thinkinglogic.builder.annotation.DefaultValue
50+
51+
@Builder
52+
data class MyDataClass(
53+
val notNullString: String,
54+
val nullableString: String?,
55+
@DefaultValue("myDefaultValue") val stringWithDefault: String = "myDefaultValue",
56+
@DefaultValue("LocalDate.MIN") val defaultDate: LocalDate = LocalDate.MIN
57+
)
58+
```
59+
(The text value of `@DefaultValue` is interpreted directly as Kotlin code, but for convenience double quotes are added around a String value).
60+
61+
#### Collections containing nullable elements
62+
Information about the nullability of elements in a collection is lost during compilation, so there is a `@NullableType` annotation:
63+
```kotlin
64+
import com.thinkinglogic.builder.annotation.Builder
65+
import com.thinkinglogic.builder.annotation.NullableType
66+
67+
@Builder
68+
data class MyDataClass(
69+
val setOfLongs: Set<Long>,
70+
@NullableType val setOfNullableLongs: Set<Long?>
71+
)
72+
```
73+
74+
#### Mutable collections
75+
Information about the mutability of collections and maps is lost during compilation, so there is a `@Mutable` annotation:
76+
```kotlin
77+
import com.thinkinglogic.builder.annotation.Builder
78+
import com.thinkinglogic.builder.annotation.Mutable
79+
80+
@Builder
81+
data class MyDataClass(
82+
val setOfLongs: Set<Long>,
83+
@Mutable val listOfStrings: MutableList<String>
84+
)
85+
```
86+
87+
#### Constructor parameters
88+
The `@Builder` annotation should be placed on a constructor instead of the class if you have constructor-only parameters:
89+
```kotlin
90+
import com.thinkinglogic.builder.annotation.Builder
91+
92+
class MyClass
93+
@Builder
94+
constructor(
95+
forename: String,
96+
surname: String,
97+
val nickName: String?
98+
) {
99+
val fullName = "$forename $surname"
100+
}
101+
```
12102

13103
## License
14104
This software is Licenced under the [MIT License](LICENSE.md).

build.gradle

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
21
buildscript {
32
ext.kotlin_version = '1.2.60'
43

54
repositories {
65
mavenCentral()
6+
jcenter()
77
}
88

99
dependencies {
1010
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11+
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.+'
1112
}
1213
}
1314

15+
allprojects {
16+
group = 'com.thinkinglogic'
17+
version = '1.0.0'
18+
}
19+
1420

15-
allprojects{
21+
allprojects {
1622
apply plugin: "kotlin"
17-
23+
1824
repositories {
1925
mavenCentral()
2026
}

builder-annotation/build.gradle

-4
This file was deleted.

builder-annotation/src/main/kotlin/com/thinkinglogic/builder/annotation/Builder.kt

-10
This file was deleted.

builder-processor/build.gradle

-9
This file was deleted.

builder-processor/src/main/java/com/thinkinglogic/builder/processor/BuilderProcessor.kt

-151
This file was deleted.

client/src/main/kotlin/com/thinkinglogic/example/CollectionsDataClass.kt

-30
This file was deleted.

client/src/main/kotlin/com/thinkinglogic/example/ConstructorArgDataClass.kt

-8
This file was deleted.

client/src/main/kotlin/com/thinkinglogic/example/SimpleDataClass.kt

-13
This file was deleted.

0 commit comments

Comments
 (0)