https://github.com/junkdog/constexpr-java
build-time code-execution for java, a bit like constexpr in C++11
https://github.com/junkdog/constexpr-java
constexpr
Last synced: 11 months ago
JSON representation
build-time code-execution for java, a bit like constexpr in C++11
- Host: GitHub
- URL: https://github.com/junkdog/constexpr-java
- Owner: junkdog
- License: apache-2.0
- Created: 2016-10-31T00:10:14.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2016-10-31T19:07:03.000Z (over 9 years ago)
- Last Synced: 2025-04-23T02:48:46.144Z (11 months ago)
- Topics: constexpr
- Language: Java
- Homepage:
- Size: 33.2 KB
- Stars: 57
- Watchers: 3
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
## `@ConstExpr`
Simulates `constexpr` from C++11, build-time code-execution, from
[cppreference.com][cppref]:
> The constexpr specifier declares that it is possible
> to evaluate the value of the function or variable at
> compile time.
#### But Why?
- embed build-time variables directly into class files
- naive string obfuscation
- maven's resource filtering can be clunky for certain use-cases
## Usage
The API is restricted to the `@ConstExpr` annotation. The maven plugin does
its thing using [ASM](http://asm.ow2.org/).
#### On Fields
Fields must satisfy the following prerequisiites to be eligible:
- `static final` modifiers
- primitive value or string.
The final value is written to the transformed class.
#### On Methods
In contrast to C++1x, `@ConstExpr` on static methods turn them into
build-time only methods. Consequently, do not annotate any methods required
during runtime.
#### Sample
```java
public class Exhibit {
@ConstExpr // recording the time at build
public static final long timestamp = System.currentTimeMillis();
@ConstExpr
public static final long seed = generateSeed();
@ConstExpr // this method will be completely removed
private static int generateSeed() {
String s = "hellooooo";
int sum = 0;
for (char c : s.toCharArray())
sum += c;
return new Random(sum).nextInt();
}
}
```
#### Usage: Maven
```xml
net.onedaybeard.constexpr
constexpr-api
0.1.0
net.onedaybeard.constexpr
constexpr-maven-plugin
0.1.0
transform
constexpr
false
false
```
Running the plugin should result in output similar to:
```
[INFO] --- constexpr-maven-plugin:0.1.0:constexpr (transform) @ map ---
[INFO] Scanned 499 classes ............................................... 86ms
[INFO] Transformed 1 classes ............................................. 46ms
[INFO]
[INFO] @ConstExpr Log
[INFO] ------------------------------------------------------------------------
[INFO] s.f.m.u.BuildProperties ....................................... fields:1
[INFO] ------------------------------------------------------------------------
[INFO]
```
#### The Details
- scan class files for `@ConstExpr` and validate
- for each annotated type:
- remove annotation
- resolve the value of each `@ConstExpr` field via reflection
- write the result to the field signature
- remove old field initialization bytecode from the static initializer
- remove any methods annotated with `@ConstExpr`
- if static initializer is left empty, remove it completely
- write transformed `byte[]` to source class file
- (entries no longer required by the _constant pool_ are cleared)
#### Bytecode: before and after
- Bytecode disassembly of [PlainString.java][ps-java], [diff view][diff].
[cppref]: http://en.cppreference.com/w/cpp/language/constexpr
[ps-java]: https://github.com/junkdog/constexpr-java/blob/d4ad613fb6dbc8a9b762af8407f0d9963485ae94/core/src/test/java/net/onedaybeard/constexpr/model/PlainString.java
[diff]: https://github.com/junkdog/constexpr-java/compare/reference-before...reference-after#diff-f98d296c19afdc978656a8813c42be81