Skip to content

Commit 7e56d0c

Browse files
authored
Merge pull request #1 from tejas-warake/feature/implementation
Initial implementation of Java Preprocessing Library (Maven)
2 parents 877645b + 68bdbf7 commit 7e56d0c

29 files changed

Lines changed: 2073 additions & 2 deletions

File tree

README.md

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,132 @@
1-
# java-preprocessing-lib
2-
Trying to create a library to somehow preprocess the java code using directives.
1+
# Java Preprocessing Library
2+
3+
A lightweight Java library and Maven plugin that brings C++ style preprocessor directives (`#if`, `#ifdef`, etc.) to Java. This allows for conditional compilation based on build-time symbols, enabling feature toggles, multi-version builds, and platform-specific code generation.
4+
5+
## Features
6+
7+
* **Standard Directives**: Support for `#if`, `#ifdef`, `#ifndef`, `#else`, `#endif`.
8+
* **Expression Evaluation**: Support for complex boolean expressions in `#if` directives (e.g., `#if DEBUG && VERSION > 1`).
9+
* **Maven Plugin**: Seamless integration into the Maven build lifecycle (`generate-sources`).
10+
* **Zero Runtime Dependencies**: The preprocessor runs at build time; the generated code is pure Java with no extra runtime requirements.
11+
12+
## Installation
13+
14+
Currently, you need to build and install the library locally:
15+
16+
```bash
17+
git clone https://github.com/your-repo/java-preprocessing-lib.git
18+
cd java-preprocessing-lib
19+
mvn install
20+
```
21+
22+
## Usage
23+
24+
### Maven Configuration
25+
26+
Add the `preprocessor-maven-plugin` to your `pom.xml`. It should be configured to run during the `generate-sources` phase.
27+
28+
**Note**: To use the preprocessor effectively, it is recommended to keep your source files with directives in a separate directory (e.g., `src/main/preprocess`) to prevent the standard Java compiler from trying to compile the unprocessed files.
29+
30+
```xml
31+
<build>
32+
<plugins>
33+
<plugin>
34+
<groupId>com.github.javapreprocessor</groupId>
35+
<artifactId>preprocessor-maven-plugin</artifactId>
36+
<version>1.0.0-SNAPSHOT</version>
37+
<executions>
38+
<execution>
39+
<id>preprocess-sources</id>
40+
<phase>generate-sources</phase>
41+
<goals>
42+
<goal>process</goal>
43+
</goals>
44+
<configuration>
45+
<!-- Directory containing source files with directives -->
46+
<sourceDirectory>${project.basedir}/src/main/preprocess</sourceDirectory>
47+
48+
<!-- Define symbols for conditional compilation -->
49+
<symbols>
50+
<DEBUG>true</DEBUG>
51+
<VERSION>2</VERSION>
52+
<FEATURE_X>false</FEATURE_X>
53+
</symbols>
54+
</configuration>
55+
</execution>
56+
</executions>
57+
</plugin>
58+
</plugins>
59+
</build>
60+
```
61+
62+
### Supported Directives
63+
64+
#### `#ifdef` / `#ifndef`
65+
Checks if a symbol is defined (or not defined).
66+
67+
```java
68+
#ifdef DEBUG
69+
System.out.println("Debug logging enabled");
70+
#endif
71+
72+
#ifndef PRODUCTION
73+
// Test helper code
74+
#endif
75+
```
76+
77+
#### `#if` / `#else` / `#endif`
78+
Evaluates a boolean expression. Supports `&&`, `||`, `!`, `>`, `<`, `>=`, `<=`, `==`, `!=`, and `defined()`.
79+
80+
```java
81+
#if VERSION > 1 && defined(FEATURE_NEW_UI)
82+
renderNewUI();
83+
#else
84+
renderClassicUI();
85+
#endif
86+
```
87+
88+
#### `#else`
89+
Alternative branch for `#if`, `#ifdef`, or `#ifndef`.
90+
91+
## Example
92+
93+
**Input (`src/main/preprocess/com/example/App.java`):**
94+
```java
95+
package com.example;
96+
97+
public class App {
98+
public static void main(String[] args) {
99+
#if DEBUG
100+
System.out.println("Debugging...");
101+
#endif
102+
103+
System.out.println("Running App");
104+
}
105+
}
106+
```
107+
108+
**Configuration (pom.xml):**
109+
```xml
110+
<symbols>
111+
<DEBUG>true</DEBUG>
112+
</symbols>
113+
```
114+
115+
**Generated Output (`target/generated-sources/preprocessed/com/example/App.java`):**
116+
```java
117+
package com.example;
118+
119+
public class App {
120+
public static void main(String[] args) {
121+
122+
System.out.println("Debugging...");
123+
124+
125+
System.out.println("Running App");
126+
}
127+
}
128+
```
129+
130+
## License
131+
132+
[MIT License](LICENSE)

example-usage/pom.xml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>com.example</groupId>
5+
<artifactId>example-usage</artifactId>
6+
<version>1.0-SNAPSHOT</version>
7+
8+
<build>
9+
<plugins>
10+
<plugin>
11+
<groupId>com.github.javapreprocessor</groupId>
12+
<artifactId>preprocessor-maven-plugin</artifactId>
13+
<version>1.0.0-SNAPSHOT</version>
14+
<executions>
15+
<execution>
16+
<id>preprocess-sources</id>
17+
<phase>generate-sources</phase>
18+
<goals>
19+
<goal>process</goal>
20+
</goals>
21+
<configuration>
22+
<sourceDirectory>${project.basedir}/src/main/preprocess</sourceDirectory>
23+
<symbols>
24+
<DEBUG>true</DEBUG>
25+
<VERSION>2</VERSION>
26+
</symbols>
27+
</configuration>
28+
</execution>
29+
</executions>
30+
</plugin>
31+
32+
<!-- Configure compiler to look at generated sources -->
33+
<!-- Actually, the plugin adds the source root automatically. But we need to make sure standard compiler doesn't complain about missing methods in original source if we were modifying in place.
34+
But here we are generating to target/generated-sources.
35+
Wait, if we have src/main/java/App.java, and it has #ifdef, it's not valid Java.
36+
So standard compiler will fail if it tries to compile src/main/java/App.java.
37+
38+
We need to tell Maven Compiler Plugin to IGNORE src/main/java?
39+
Or, we should put our *template* sources in a different directory, e.g. src/main/java-templates?
40+
The plugin defaults to src/main/java.
41+
42+
If we use src/main/java as input, we must ensure the compiler doesn't try to compile it directly.
43+
Or we just assume the user puts valid Java code "around" the directives?
44+
No, directives start with #, which is illegal in Java.
45+
46+
So users CANNOT keep their source in src/main/java if they want to use standard `compile`.
47+
They should put it in `src/main/preprocessed` or similar.
48+
49+
Let's change the default source directory in the Mojo, or override it here.
50+
Let's use `src/main/preprocess` for this example.
51+
-->
52+
</plugins>
53+
</build>
54+
55+
<properties>
56+
<maven.compiler.source>1.8</maven.compiler.source>
57+
<maven.compiler.target>1.8</maven.compiler.target>
58+
</properties>
59+
</project>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.example;
2+
3+
public class App {
4+
public static void main(String[] args) {
5+
System.out.println("Hello World!");
6+
7+
#if DEBUG
8+
System.out.println("Debug mode enabled");
9+
#endif
10+
11+
#if VERSION > 1
12+
System.out.println("Version is greater than 1");
13+
#endif
14+
15+
#if VERSION < 1
16+
System.out.println("Version is less than 1");
17+
#endif
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.example;
2+
3+
public class App {
4+
public static void main(String[] args) {
5+
System.out.println("Hello World!");
6+
7+
8+
System.out.println("Debug mode enabled");
9+
10+
11+
12+
System.out.println("Version is greater than 1");
13+
14+
15+
16+
17+
18+
}
19+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com/example/App.class
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/home/tejas-warake/Desktop/open-source/java-preprocessing-lib/example-usage/target/generated-sources/preprocessed/com/example/App.java

pom.xml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>com.github.javapreprocessor</groupId>
5+
<artifactId>java-preprocessing-lib-parent</artifactId>
6+
<packaging>pom</packaging>
7+
<version>1.0.0-SNAPSHOT</version>
8+
<name>Java Preprocessing Library Parent</name>
9+
10+
<modules>
11+
<module>preprocessor-core</module>
12+
<module>preprocessor-maven-plugin</module>
13+
</modules>
14+
15+
<properties>
16+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17+
<maven.compiler.source>1.8</maven.compiler.source>
18+
<maven.compiler.target>1.8</maven.compiler.target>
19+
</properties>
20+
21+
<dependencyManagement>
22+
<dependencies>
23+
<dependency>
24+
<groupId>junit</groupId>
25+
<artifactId>junit</artifactId>
26+
<version>4.13.2</version>
27+
<scope>test</scope>
28+
</dependency>
29+
</dependencies>
30+
</dependencyManagement>
31+
</project>

preprocessor-core/pom.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<parent>
5+
<groupId>com.github.javapreprocessor</groupId>
6+
<artifactId>java-preprocessing-lib-parent</artifactId>
7+
<version>1.0.0-SNAPSHOT</version>
8+
</parent>
9+
<artifactId>preprocessor-core</artifactId>
10+
<packaging>jar</packaging>
11+
<name>Preprocessor Core</name>
12+
13+
<dependencies>
14+
<dependency>
15+
<groupId>junit</groupId>
16+
<artifactId>junit</artifactId>
17+
<scope>test</scope>
18+
</dependency>
19+
</dependencies>
20+
</project>

0 commit comments

Comments
 (0)