Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 132 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,132 @@
# java-preprocessing-lib
Trying to create a library to somehow preprocess the java code using directives.
# Java Preprocessing Library

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.

## Features

* **Standard Directives**: Support for `#if`, `#ifdef`, `#ifndef`, `#else`, `#endif`.
* **Expression Evaluation**: Support for complex boolean expressions in `#if` directives (e.g., `#if DEBUG && VERSION > 1`).
* **Maven Plugin**: Seamless integration into the Maven build lifecycle (`generate-sources`).
* **Zero Runtime Dependencies**: The preprocessor runs at build time; the generated code is pure Java with no extra runtime requirements.

## Installation

Currently, you need to build and install the library locally:

```bash
git clone https://github.com/your-repo/java-preprocessing-lib.git
cd java-preprocessing-lib
mvn install
```

## Usage

### Maven Configuration

Add the `preprocessor-maven-plugin` to your `pom.xml`. It should be configured to run during the `generate-sources` phase.

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

```xml
<build>
<plugins>
<plugin>
<groupId>com.github.javapreprocessor</groupId>
<artifactId>preprocessor-maven-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<executions>
<execution>
<id>preprocess-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<!-- Directory containing source files with directives -->
<sourceDirectory>${project.basedir}/src/main/preprocess</sourceDirectory>

<!-- Define symbols for conditional compilation -->
<symbols>
<DEBUG>true</DEBUG>
<VERSION>2</VERSION>
<FEATURE_X>false</FEATURE_X>
</symbols>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
```

### Supported Directives

#### `#ifdef` / `#ifndef`
Checks if a symbol is defined (or not defined).

```java
#ifdef DEBUG
System.out.println("Debug logging enabled");
#endif

#ifndef PRODUCTION
// Test helper code
#endif
```

#### `#if` / `#else` / `#endif`
Evaluates a boolean expression. Supports `&&`, `||`, `!`, `>`, `<`, `>=`, `<=`, `==`, `!=`, and `defined()`.

```java
#if VERSION > 1 && defined(FEATURE_NEW_UI)
renderNewUI();
#else
renderClassicUI();
#endif
```

#### `#else`
Alternative branch for `#if`, `#ifdef`, or `#ifndef`.

## Example

**Input (`src/main/preprocess/com/example/App.java`):**
```java
package com.example;

public class App {
public static void main(String[] args) {
#if DEBUG
System.out.println("Debugging...");
#endif

System.out.println("Running App");
}
}
```

**Configuration (pom.xml):**
```xml
<symbols>
<DEBUG>true</DEBUG>
</symbols>
```

**Generated Output (`target/generated-sources/preprocessed/com/example/App.java`):**
```java
package com.example;

public class App {
public static void main(String[] args) {

System.out.println("Debugging...");


System.out.println("Running App");
}
}
```

## License

[MIT License](LICENSE)
59 changes: 59 additions & 0 deletions example-usage/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>example-usage</artifactId>
<version>1.0-SNAPSHOT</version>

<build>
<plugins>
<plugin>
<groupId>com.github.javapreprocessor</groupId>
<artifactId>preprocessor-maven-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<executions>
<execution>
<id>preprocess-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/preprocess</sourceDirectory>
<symbols>
<DEBUG>true</DEBUG>
<VERSION>2</VERSION>
</symbols>
</configuration>
</execution>
</executions>
</plugin>

<!-- Configure compiler to look at generated sources -->
<!-- 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.
But here we are generating to target/generated-sources.
Wait, if we have src/main/java/App.java, and it has #ifdef, it's not valid Java.
So standard compiler will fail if it tries to compile src/main/java/App.java.

We need to tell Maven Compiler Plugin to IGNORE src/main/java?
Or, we should put our *template* sources in a different directory, e.g. src/main/java-templates?
The plugin defaults to src/main/java.

If we use src/main/java as input, we must ensure the compiler doesn't try to compile it directly.
Or we just assume the user puts valid Java code "around" the directives?
No, directives start with #, which is illegal in Java.

So users CANNOT keep their source in src/main/java if they want to use standard `compile`.
They should put it in `src/main/preprocessed` or similar.

Let's change the default source directory in the Mojo, or override it here.
Let's use `src/main/preprocess` for this example.
-->
</plugins>
</build>

<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
19 changes: 19 additions & 0 deletions example-usage/src/main/preprocess/com/example/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example;

public class App {
public static void main(String[] args) {
System.out.println("Hello World!");

#if DEBUG
System.out.println("Debug mode enabled");
#endif

#if VERSION > 1
System.out.println("Version is greater than 1");
#endif

#if VERSION < 1
System.out.println("Version is less than 1");
#endif
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example;

public class App {
public static void main(String[] args) {
System.out.println("Hello World!");


System.out.println("Debug mode enabled");



System.out.println("Version is greater than 1");





}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com/example/App.class
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/home/tejas-warake/Desktop/open-source/java-preprocessing-lib/example-usage/target/generated-sources/preprocessed/com/example/App.java
31 changes: 31 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.javapreprocessor</groupId>
<artifactId>java-preprocessing-lib-parent</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<name>Java Preprocessing Library Parent</name>

<modules>
<module>preprocessor-core</module>
<module>preprocessor-maven-plugin</module>
</modules>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
20 changes: 20 additions & 0 deletions preprocessor-core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.javapreprocessor</groupId>
<artifactId>java-preprocessing-lib-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>preprocessor-core</artifactId>
<packaging>jar</packaging>
<name>Preprocessor Core</name>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Loading