Skip to content

Latest commit

 

History

History
142 lines (124 loc) · 6.02 KB

README.md

File metadata and controls

142 lines (124 loc) · 6.02 KB

! This Project is reworking under https://www.github.com/DeeChael/dcg ! Check new project! !

Dynamic Class Generator

Maven Central License CodeFactor Forks Stars

Allow you to generate classes while the program is running!

I have made a plan that I will make DCG 2.00.0 for jdk17+

Go to wiki to learn more!

Known Issues:

  1. Cannot load a class from other class loaders, so even generated the class, maybe it will cause NoDefClassException

Importation:

For Maven

<dependency>
    <groupId>net.deechael</groupId>
    <artifactId>dcg</artifactId>
    <version>1.05.0</version>
    <scope>compile</scope>
</dependency>

For Gradle

dependencies { 
    //...
    implementation 'net.deechael:dcg:1.05.0'
}

Example:

JClass clazz = new JClass(Level.PUBLIC, "net.deechael.test", "DynamicClassGeneratorTest");
JField field = clazz.addField(Level.PUBLIC, JType.classType(String.class), "parent", false, false);
field.initialize(JStringVar.stringVar("aaaaaaaaaaaaaaaaaaaaaaa"));
JConstructor constructor = clazz.addConstructor(Level.PUBLIC);
Var testing = constructor.addParameter(JType.classType(String.class), "testing");
Var human = constructor.addParameter(JType.classType(Human.class), "human");
Var second = constructor.createVar(JType.classType(String.class), "second", Var.constructor(JType.classType(String.class), testing));
Var age = constructor.createVar(JType.classType(int.class), "age", Var.invokeMethod(human, "getAge"));
Var name = constructor.createVar(JType.classType(String.class), "name", Var.invokeMethod(human, "getName"));
constructor.invokeMethod(human, "print", testing);
constructor.invokeMethod(human, "print", second);
constructor.invokeMethod(human, "print", human);
constructor.invokeMethod(human, "print", age);
constructor.invokeMethod(human, "print", name);
constructor.ifElse(Requirement.isEqual(age, JStringVar.intVar(16)), (executable) -> {
executable.invokeMethod(human, "print", JStringVar.stringVar("You entered if executable body"));
}).setElse(((executable) -> {
executable.invokeMethod(human, "print", JStringVar.stringVar("You entered else executable body"));
}));

JMethod method = clazz.addMethod(Level.PUBLIC, "testing", false, false, false);
Var method_human = method.addParameter(JType.classType(Human.class), "human");
Var method_age = method.createVar(JType.classType(int.class), "age", Var.invokeMethod(human, "getAge"));
method.invokeMethod(method_human, "print", JStringVar.stringVar("Method testing"));
method.ifElse(Requirement.isEqual(method_age, JStringVar.intVar(16)), (executable) -> {
executable.invokeMethod(method_human, "print", JStringVar.stringVar("Method if body"));
}).setElse((executable) -> {
executable.invokeMethod(method_human, "print", JStringVar.stringVar("Method else body"));
});
method.invokeMethod(method_human, "print", field);
method.setFieldValue(field, JStringVar.stringVar("bbbbbbbbbbbbbbbbbbbb"));
method.invokeMethod(method_human, "print", field);

Class<?> generated = JGenerator.generate(clazz);
Constructor<?> cons = generated.getConstructor(String.class, Human.class);
Object instance = cons.newInstance("Test message!", new Human("Name", 16));
generated.getMethod("testing", Human.class).invoke(instance, new Human("DeeChael", 16));
generated.getMethod("testing", Human.class).invoke(instance, new Human("DeeChael", 39));

Generated code:

package net.deechael.test;

import java.lang.String;
import net.deechael.library.dcg.test.Human;

/**
 * The generated code as you can see is formatted by hand,
 * there is no space at the start of the lines in the real generated code
 */
public class DynamicClassGeneratorTest {

    public java.lang.String jfield_parent = ("aaaaaaaaaaaaaaaaaaaaaaa");

    public DynamicClassGeneratorTest (java.lang.String jparam_testing, net.deechael.library.dcg.test.Human jparam_human) {
        java.lang.String jvar_second = new java.lang.String(jparam_testing);
        int jvar_age = jparam_human.getAge();
        java.lang.String jvar_name = jparam_human.getName();
        jparam_human.print(jparam_testing);
        jparam_human.print(jvar_second);
        jparam_human.print(jparam_human);
        jparam_human.print(jvar_age);
        jparam_human.print(jvar_name);
        if (jvar_age == 16) {
            jparam_human.print("You entered if executable body");
        } else {
            jparam_human.print("You entered else executable body");
        }
    }

    public void testing(net.deechael.library.dcg.test.Human jparam_human) {
        int jvar_age = jparam_human.getAge();
        jparam_human.print("Method testing");
        if (jvar_age == 16) {
            jparam_human.print("Method if body");
        } else {
            jparam_human.print("Method else body");
        }

        jparam_human.print(this.jfield_parent);
        this.jfield_parent = ("bbbbbbbbbbbbbbbbbbbb");
        jparam_human.print(this.jfield_parent);
    }

}

Coming Soon:

1.Extending class
2.Implementing interfaces
3.Creating annotation
4.Creating enum
5.Creating interface
6.Try & Catch
7.Try & multi Catch
8.Try & 1 Catch with multi exceptions
9.If & multi Else-ifs & else
10.If & multi Else-ifs
11.More requirements for If-block and Else If-block
12.Convenient variables managing
13.Try & Catch & Finally
14.Abstract class
...