README.md 6.6 KB
Newer Older
梦境迷离's avatar
梦境迷离 已提交
1 2 3 4
# scala-macro-tools [![Build](https://github.com/jxnu-liguobin/scala-macro-tools/actions/workflows/ScalaCI.yml/badge.svg)](https://github.com/jxnu-liguobin/scala-macro-tools/actions/workflows/ScalaCI.yml)

Motivation
--
梦境迷离's avatar
梦境迷离 已提交
5

梦境迷离's avatar
梦境迷离 已提交
6 7 8
Learn Scala macro and abstract syntax tree.

> The project is currently experimental
梦境迷离's avatar
梦境迷离 已提交
9

梦境迷离's avatar
梦境迷离 已提交
10 11 12
# Features

## @toString
梦境迷离's avatar
梦境迷离 已提交
13

梦境迷离's avatar
梦境迷离 已提交
14 15
The `@toString` used to generate `toString` for Scala classes or a `toString` with parameter names for the case classes.

梦境迷离's avatar
梦境迷离 已提交
16
- Note
17 18 19 20 21
  - `verbose` Whether to enable detailed log.
  - `includeFieldNames` Whether to include the names of the field in the `toString`.
  - `includeInternalFields` Whether to include the fields defined within a class. Not in a primary constructor.
  - `callSuper`             Whether to include the super's `toString`. Not support if super class is a trait.
  - Support `case class` and `class`.
梦境迷离's avatar
梦境迷离 已提交
22

梦境迷离's avatar
pre  
梦境迷离 已提交
23
- Example
梦境迷离's avatar
梦境迷离 已提交
24

梦境迷离's avatar
梦境迷离 已提交
25
```scala
梦境迷离's avatar
梦境迷离 已提交
26 27 28 29 30
class TestClass(val i: Int = 0, var j: Int) {
  val y: Int = 0
  var z: String = "hello"
  var x: String = "world"
}
梦境迷离's avatar
梦境迷离 已提交
31

梦境迷离's avatar
pre  
梦境迷离 已提交
32
println(new TestClass(1, 2));
梦境迷离's avatar
梦境迷离 已提交
33
```
梦境迷离's avatar
梦境迷离 已提交
34

35
|includeInternalFields / includeFieldNames| false  |true
梦境迷离's avatar
梦境迷离 已提交
36
|  ---------------------------------  | ----------------------------------  |----------------------------------|
梦境迷离's avatar
pre  
梦境迷离 已提交
37
|false|```TestClass(1, 2)``` |```TestClass(i=0, j=2)```|
梦境迷离's avatar
梦境迷离 已提交
38 39
|true|```TestClass(1, 2, 0, hello, world)```|```TestClass(i=1, j=2, y=0, z=hello, x=world)```|

梦境迷离's avatar
梦境迷离 已提交
40 41 42 43 44 45 46 47
## @json

The `@json` scala macro annotation is the quickest way to add a JSON format to your Play project's case classes.

- Note
    - This annotation is drawn from [json-annotation](https://github.com/kifi/json-annotation) and have some
      optimization.
    - It can also be used when there are other annotations on the case classes.
梦境迷离's avatar
梦境迷离 已提交
48
    - Only an implicit `val` was generated automatically(Maybe generate a companion object if it not exists), and there are no other
梦境迷离's avatar
梦境迷离 已提交
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
      operations.
- Example

```scala
@json case class Person(name: String, age: Int)
```

You can now serialize/deserialize your objects using Play's convenience methods:

```scala
import play.api.libs.json._

val person = Person("Victor Hugo", 46)
val json = Json.toJson(person)
Json.fromJson[Person](json)
```

梦境迷离's avatar
梦境迷离 已提交
66
## @builder
梦境迷离's avatar
梦境迷离 已提交
67 68 69 70 71

The `@builder` used to generate builder pattern for Scala classes.

- Note
    - Support `case class` / `class`.
梦境迷离's avatar
梦境迷离 已提交
72
    - It can be used with `@toString`. But it needs to be put in the back.
73
    - If there is no companion object, one will be generated to store the `builder` method and `Builder` class.
梦境迷离's avatar
梦境迷离 已提交
74 75 76 77 78 79 80
    - IDE support is not very good, a red prompt will appear, but the compilation is OK.

- Example

```scala
@builder
case class TestClass1(val i: Int = 0, var j: Int, x: String, o: Option[String] = Some(""))
梦境迷离's avatar
梦境迷离 已提交
81

梦境迷离's avatar
梦境迷离 已提交
82 83 84 85 86
val ret = TestClass1.builder().i(1).j(0).x("x").build()
assert(ret.toString == "TestClass1(1,0,x,Some())")
```

Compiler intermediate code:
梦境迷离's avatar
梦境迷离 已提交
87

梦境迷离's avatar
梦境迷离 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
```scala
object TestClass1 extends scala.AnyRef {
  def <init>() = {
    super.<init>();
    ()
  };
  def builder(): Builder = new Builder();
  class Builder extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };
    private var i: Int = 0;
    private var j: Int = _;
    private var x: String = _;
    private var o: Option[String] = Some("");
    def i(i: Int): Builder = {
      this.i = i;
      this
    };
    def j(j: Int): Builder = {
      this.j = j;
      this
    };
    def x(x: String): Builder = {
      this.x = x;
      this
    };
    def o(o: Option[String]): Builder = {
      this.o = o;
      this
    };
    def build(): TestClass1 = TestClass1(i, j, x, o)
  }
}
```

梦境迷离's avatar
梦境迷离 已提交
125 126 127
# How to use

Add library dependency
梦境迷离's avatar
梦境迷离 已提交
128

梦境迷离's avatar
梦境迷离 已提交
129 130 131 132
```scala
"io.github.jxnu-liguobin" %% "scala-macro-tools" % "<VERSION>"
```

梦境迷离's avatar
梦境迷离 已提交
133
The artefacts have been uploaded to Maven Central.
梦境迷离's avatar
梦境迷离 已提交
134 135 136

| Library Version | Scala 2.11 | Scala 2.12 | Scala 2.13 |
|---------|------------|------------|------------|
梦境迷离's avatar
梦境迷离 已提交
137
| 0.0.4   | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.11/0.0.4)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.11/0.0.4/jar)        | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.12/0.0.4)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.12/0.0.4/jar)        | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.13/0.0.4)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.13/0.0.4/jar)        |
梦境迷离's avatar
up  
梦境迷离 已提交
138
| 0.0.3   | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.11/0.0.3)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.11/0.0.3/jar)        | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.12/0.0.3)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.12/0.0.3/jar)        | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.13/0.0.3)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.13/0.0.3/jar)        |
梦境迷离's avatar
梦境迷离 已提交
139 140
| 0.0.2   | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.11/0.0.2)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.11/0.0.2/jar)        | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.12/0.0.2)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.12/0.0.2/jar)        | [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.13/0.0.2)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.13/0.0.2/jar)        |
| 0.0.1   |-|-| [![Maven Central](https://img.shields.io/maven-central/v/io.github.jxnu-liguobin/scala-macro-tools_2.13/0.0.1)](https://search.maven.org/artifact/io.github.jxnu-liguobin/scala-macro-tools_2.13/0.0.1/jar)        |
梦境迷离's avatar
梦境迷离 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155

Importing the library into your build system (e.g gradle, sbt), is not enough. You need to follow an extra step.

| Scala 2.11 | Scala 2.12 | Scala 2.13 |
|------------|-------------|------------|
| Import macro paradise plugin  | Import macro paradise plugin | Enable compiler flag `-Ymacro-annotations` required |

```scala
addCompilerPlugin("org.scalamacros" % "paradise_<your-scala-version>" % "<plugin-version>")
```

Where `<your-scala-version>` must be the full scala version. For example 2.12.13, and not 2.12.

If that doesn't work, google for alternatives.

梦境迷离's avatar
梦境迷离 已提交
156
In version scala`2.13.x`, the functionality of macro paradise has been included in the scala compiler directly. However,
梦境迷离's avatar
梦境迷离 已提交
157
you must still enable the compiler flag `-Ymacro-annotations`.