Skip to content

Commit 056f50b

Browse files
committed
improve documentation
1 parent 8feb22e commit 056f50b

File tree

2 files changed

+110
-33
lines changed

2 files changed

+110
-33
lines changed

README.adoc

Lines changed: 81 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,20 @@
22

33
# Better Strings - Java String Interpolation
44

5-
image:https://travis-ci.com/antkorwin/better-strings.svg?branch=master["Build Status", link="https://travis-ci.com/antkorwin/better-strings"]
5+
image:https://travis-ci.com/antkorwin/better-strings.svg?branch=master["Build Status",link="https://travis-ci.com/antkorwin/better-strings"]
66
image:https://codecov.io/gh/antkorwin/better-strings/branch/master/graph/badge.svg[link ="https://codecov.io/gh/antkorwin/better-strings"]
77
image:https://maven-badges.herokuapp.com/maven-central/com.antkorwin/better-strings/badge.svg[link="https://search.maven.org/search?q=g:com.antkorwin%20AND%20a:better-strings"]
88

99
The Java Plugin to use string interpolation for Java (like in Kotlin).
1010
Supports Java 8, 9, 10, 11, ...
1111

12-
1312
## Motivation
1413

15-
In the latest JEPs https://openjdk.java.net/jeps/355, we have the only expectation of the RAW string literals,
16-
but there is nothing about the string interpolation.
14+
In the latest JEPs https://openjdk.java.net/jeps/355, we have the only expectation of the RAW string literals, but there is nothing about the string interpolation.
1715

1816
And it’s so sad, that we need writing code like this in the 2020 year:
1917

20-
[source, java]
18+
[source,java]
2119
----
2220
int a = 3;
2321
int b = 4;
@@ -29,7 +27,7 @@ just to print the string: `3 + 4 = 7`
2927

3028
of course, we can use a `var` since Java 10:
3129

32-
[source, java]
30+
[source,java]
3331
----
3432
var a = 3;
3533
var b = 4;
@@ -42,7 +40,7 @@ But this code is still sad =(
4240

4341
### Using variables in string literals
4442

45-
[source, java]
43+
[source,java]
4644
----
4745
var a = 3;
4846
var b = 4;
@@ -53,24 +51,26 @@ prints: `3 + 4 = 7`
5351

5452
### Using expressions
5553

56-
[source, java]
54+
[source,java]
5755
----
5856
var a = 3;
5957
var b = 4;
6058
System.out.println("flag = ${a > b ? true : false}");
6159
----
60+
6261
prints: `flag = false`
6362

64-
[source, java]
63+
[source,java]
6564
----
6665
var a = 3;
6766
System.out.println("pow = ${a * a}");
6867
----
68+
6969
prints: `pow = 9`
7070

7171
### Using functions
7272

73-
[source, java]
73+
[source,java]
7474
----
7575
@Test
7676
void functionCall() {
@@ -85,21 +85,77 @@ long factorial(int n) {
8585
return fact;
8686
}
8787
----
88+
8889
prints: `fact(5) = 120`
8990

91+
### Using string interpolation in class fields
92+
93+
you can use better-string for string interpolation in class fields, for example:
94+
95+
[source,java]
96+
----
97+
public class Test {
98+
public String field = "${3+4}";
99+
public String getField(){
100+
return "field = ${field}";
101+
}
102+
}
103+
----
104+
105+
`new Test().getField()` prints : `field = 7`
106+
107+
### Using string interpolation in default methods of interfaces
108+
109+
also you can use string interpolation with default methods in interfaces like this:
110+
111+
[source,java]
112+
----
113+
public interface InterfaceWithDefaultMethod {
114+
default String sum(){
115+
return "sum = ${1+2}";
116+
}
117+
}
118+
119+
public class Test implements InterfaceWithDefaultMethod {
120+
public String test() {
121+
return sum();
122+
}
123+
}
124+
----
125+
126+
The result of `new Test().test()` is `sum = 3`
127+
128+
### Using string interpolation in enums
129+
130+
In addition you can use string interpolation for code of enums:
131+
132+
[source, java]
133+
----
134+
public enum EnumCode {
135+
FIRST,
136+
SECOND,
137+
THIRD;
138+
139+
@Override
140+
public String toString() {
141+
return "value: ${this.name()}, order: ${this.ordinal() + 1}";
142+
}
143+
}
144+
----
145+
146+
`EnumCode.THIRD.toString();` should print: `value: THIRD, order: 3`
90147

91148
### Disclaimer
92149

93150
NOTE: Keep in mind that this feature should be used carefully.
94-
You shouldn't write too much code inside string literals
95-
because it is too difficult to maintain and maybe not obvious for debugging.
151+
You shouldn't write too much code inside string literals because it is too difficult to maintain and maybe not obvious for debugging.
96152

97153

98154
## Getting started
99155

100156
You need to add the following dependency:
101157

102-
[source, xml]
158+
[source,xml]
103159
----
104160
<dependency>
105161
<groupId>com.antkorwin</groupId>
@@ -114,7 +170,7 @@ And you can use string interpolation anywhere in your code.
114170

115171
To skip the string interpolation for class, method or field you can use the `@DisabledStringInterpolation` annotation:
116172

117-
[source, java]
173+
[source,java]
118174
----
119175
@DisabledStringInterpolation
120176
class Foo {
@@ -126,66 +182,58 @@ class Foo {
126182

127183
this code prints: `${a+b}`
128184

129-
Also, you can use the following workaround
130-
to escape string interpolation locally in your code:
185+
Also, you can use the following workaround to escape string interpolation locally in your code:
131186

132-
[source, java]
187+
[source,java]
133188
----
134189
System.out.println("${'$'}{a+b}");
135190
----
136191

137192
the result is : `${a+b}`
138193

139-
140194
## How to control the generated code
141195

142-
Better Strings is a Java Annotation Processor,
143-
but it does not process specific annotations, it makes AST modification of your code while javac compiling it.
196+
Better Strings is a Java Annotation Processor, but it does not process specific annotations, it makes AST modification of your code while javac compiling it.
144197

145198
By default, each `${...}` occurrence translates into an invocation of `String#valueOf`.
146199
For instance, a string:
147200

148-
[source, java]
201+
[source,java]
149202
----
150203
"Result: ${obj}.method() = ${obj.method()}"
151204
----
152205

153206
will yield:
154207

155-
[source, java]
208+
[source,java]
156209
----
157210
"Result: "
158211
+ String.valueOf(obj)
159212
+ ".method() = "
160213
+ String.valueOf(obj.method())
161214
----
162215

163-
Under certain circumstances (e.g. with certain static code analyzers), however,
164-
it might be preferred that the generated code contains an explicit `toString` invocation for each `${...}` occurrence containing a non-null value.
216+
Under certain circumstances (e.g. with certain static code analyzers), however, it might be preferred that the generated code contains an explicit `toString` invocation for each `${...}` occurrence containing a non-null value.
165217
This can be controlled with `-AcallToStringExplicitlyInInterpolations` compiler option, which will instead make the above string translate into:
166218

167-
[source, java]
219+
[source,java]
168220
----
169221
"Result: "
170222
+ (java.util.Objects.nonNull(obj) ? java.util.Objects.requireNonNull(obj).toString() : "null")
171223
+ ".method() = "
172224
+ (java.util.Objects.nonNull(obj.method()) ? java.util.Objects.requireNonNull(obj.method()).toString() : "null")
173225
----
174226

175-
NOTE: this causes the inner part of each `${...}` to be evaluated twice,
176-
which might be problematic if the expression is side-effecting, non-deterministic or expensive to compute.
177-
227+
NOTE: this causes the inner part of each `${...}` to be evaluated twice, which might be problematic if the expression is side-effecting, non-deterministic or expensive to compute.
178228

179229
## How to use with other annotation processors
180230

181-
If you need to use multiple annotation processors (for example `better-strings` with `lombok` or `mapstruct`)
182-
and the order of processing is necessary for you then you can set the order in your building tool.
231+
If you need to use multiple annotation processors (for example `better-strings` with `lombok` or `mapstruct`) and the order of processing is necessary for you then you can set the order in your building tool.
183232

184-
In maven, you should declare dependencies as usually,
185-
then describe annotation processors in the configuration of the `maven-compiler-plugin`
233+
In maven, you should declare dependencies as usually, then describe annotation processors in the configuration of the `maven-compiler-plugin`
186234
in the build section:
187235

188-
[source, xml]
236+
[source,xml]
189237
----
190238
<plugin>
191239
<groupId>org.apache.maven.plugins</groupId>

src/test/java/com/antkorwin/betterstrings/BetterStringsProcessorTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,35 @@ void useEnumValue() {
250250

251251
assertThat(result).isEqualTo("SECOND = 7");
252252
}
253+
254+
255+
256+
@Test
257+
void enumToString() {
258+
@Language("Java") String enumCode = "public enum EnumCode {" +
259+
" FIRST," +
260+
" SECOND," +
261+
" THIRD;" +
262+
" @Override" +
263+
" public String toString() {" +
264+
" return \"value: ${this.name()}, order: ${this.ordinal() + 1}\";" +
265+
" }"+
266+
"}";
267+
@Language("Java") String classCode = "public class Test { " +
268+
" public static String test(){ " +
269+
" return EnumCode.THIRD.toString();" +
270+
" }" +
271+
"}";
272+
273+
Object result = new CompileTest().classCode("Test", classCode)
274+
.classCode("EnumCode", enumCode)
275+
.processor(new BetterStringsProcessor())
276+
.compile()
277+
.loadClass("Test")
278+
.invokeStatic("test");
279+
280+
assertThat(result).isEqualTo("value: THIRD, order: 3");
281+
}
253282
}
254283

255284
@Nested

0 commit comments

Comments
 (0)