All Projects → junkdog → constexpr-java

junkdog / constexpr-java

Licence: Apache-2.0 license
build-time code-execution for java, a bit like constexpr in C++11

Programming Languages

java
68154 projects - #9 most used programming language

Labels

Projects that are alternatives of or similar to constexpr-java

flags17
A comparison of different options to implement binary flags in C++17
Stars: ✭ 16 (-72.41%)
Mutual labels:  constexpr
opzioni
The wanna-be-simplest command line arguments library for C++
Stars: ✭ 29 (-50%)
Mutual labels:  constexpr
Compile Time Regular Expressions
A Compile time PCRE (almost) compatible regular expression matcher.
Stars: ✭ 2,144 (+3596.55%)
Mutual labels:  constexpr
fixed string
C++17 string with fixed size
Stars: ✭ 64 (+10.34%)
Mutual labels:  constexpr
uninttp
A universal type for non-type template parameters for C++20 or later.
Stars: ✭ 16 (-72.41%)
Mutual labels:  constexpr
bitset2
std::bitset with constexpr implementations plus additional features.
Stars: ✭ 76 (+31.03%)
Mutual labels:  constexpr
literal ipaddr
C++17 constexpr implementation of inet_addr / inet_aton / inet_pton
Stars: ✭ 19 (-67.24%)
Mutual labels:  constexpr

@ConstExpr

Simulates constexpr from C++11, build-time code-execution, from cppreference.com:

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.

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

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

<dependencies>
    <dependency>
        <groupId>net.onedaybeard.constexpr</groupId>
        <artifactId>constexpr-api</artifactId>
        <version>0.1.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>net.onedaybeard.constexpr</groupId>
            <artifactId>constexpr-maven-plugin</artifactId>
            <version>0.1.0</version>
            <executions>
                <execution>
                    <id>transform</id>
                    <goals>
                        <goal>constexpr</goal>
                    </goals>
                </execution>
            </executions>
            <!-- default configuration -->
            <configuration>
                <!-- property: constexpr.skip -->
                <skip>false</skip>
                <!-- property: constexpr.verbose -->
                <verbose>false</verbose>
            </configuration>
        </plugin>
    </plugins>
</build>

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

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].