Skip to content

Releases: Pelemenguin/ClassJS

ClassJS v0.1-alpha.6

27 Dec 12:16

Choose a tag to compare

ClassJS v0.1-alpha.6 Pre-release
Pre-release

New Features

  • annotated

    • Use annotated on ClassCreator, MethodCreator, or FieldCreator to add annotations on them.

      let test = ClassCreator.create("AnnotationTest")
      .toPublic()
      .defaultConstructor()
      .annotated("java.lang.Deprecated")
          .build()
      .createField("testField", "int")
          .toPublic().toStatic()
          .annotated("java.lang.Deprecated")
              .withString("since", "1230912-39")
              .build()
          .build()
      .createMethod("test", [], "void")
          .toPublic().toStatic()
          .annotated("java.lang.Deprecated")
              .withBoolean("forRemoval", true)
              .build()
          .annotated("dev.latvian.mods.kubejs.typings.Info")
              .withString("value", "method")
              .withAnnotationArray("params", "dev.latvian.mods.kubejs.typings.Param", [
                  a => a.withString("value", "AAA"),
                  a => a.withString("value", "BBB"),
              ])
              .build()
          .codeJS(() => console.info("TEST METHOD"))
      .defineClass();
      
      console.info(test.__javaObject__.getMethods()[0].getAnnotations());
      // Output in startup.log:
      // [@java.lang.Deprecated(forRemoval=true, since=""), @dev.latvian.mods.kubejs.typings.Info(params={@dev.latvian.mods.kubejs.typings.Param(name="", value="AAA"), @dev.latvian.mods.kubejs.typings.Param(name="", value="BBB")}, value="method")] [java.util.ArrayList]
      
      console.info(test.__javaObject__.getFields()[0].getAnnotations());
      // Output in startup.log:
      // [@java.lang.Deprecated(forRemoval=false, since="1230912-39")] [java.util.ArrayList]
  • ClassCreator.createAnnotationMethod

    • Add an anntation method to an @interface class.
    • There is possibly some bug, so currently no example is provided.

Fixed Bug

  • Could not invokeJS when parameter list is empty.

ClassJS v0.1-alpha.5

20 Oct 07:53

Choose a tag to compare

ClassJS v0.1-alpha.5 Pre-release
Pre-release

New Features

  • ClassCreator.createClassInitMethod

    • createClassInitMethod creates a <clinit> method, which is called to initialize the class.

      const ArrayList = Java.loadClass("java.util.ArrayList")
      
      let ExampleClass = ClassCreator.create("ExampleClass")
          .createField("listField", ArrayList)
              .toPublic().toStatic().toFinal()
              .build()
          .createClassInitMethod()
              .code(method => {
                  method
                      // Creates a new ArrayList
                      .newAndConstructObject(ArrayList)
                      // Put the created ArrayList into the `listField` static field.
                      .putStaticField(
                          ClassJSUtils.getCustomClassName("ExampleClass"),
                          "listField",
                          ArrayList
                      )
                      .returnVoid();
              })
          .defineClass();
      
      console.info(ExampleClass.listField);
      // Output in "startup.log":
      // [] [java.util.ArrayList]
    • This is equivalent to the following Java code:

      import java.util.ArrayList;
      
      public class ExampleClass {
          public static final ArrayList<Object> listField;
          static {
              listField = new ArrayList<>();
          }
      }
    • or:

      import java.util.ArrayList;
      
      public class ExampleClass {
          public static final ArrayList<Object> listField = new ArrayList<>();
      }
  • ClassCreator.createConstructor

    • createClassInitMethod creates a <init> method, that is, a constructor method.

      let ExampleClass = ClassCreator.create("ExampleClass")
          .createField("value", "int")
              .toPublic().toFinal()
              .build()
          .createConstructor(["int"])
              .toPublic()
              .code(m => {
                  // Standard way to call super constructor,
                  // as Java expect every constructor of any class
                  // to call a super constructor as the first operation.
                  // (Should we add a new method to automate this process?)
                  m.loadObject("this")
                      .duplicate()
                      .invokeSpecial("java.lang.Object", "<init>", [], "void")
                  // Load the input integer
                      .loadInt("arg0")
                  // Put it into the field 'value'
                      .putField(ClassJSUtils.getCustomClassName("ExampleClass"), "value", "int")
                      .returnVoid();
              })
          .defineClass();
      
      console.info(new ExampleClass(12345).value);
      // Output in "startup.log":
      // 12345.0
      
      // (This is because KubeJS represents all numbers as doubles.)
    • This is equivalent to the following Java code:

      public class ExampleClass {
          public final int value;
          
          public ExampleClass(int arg0) {
              this.value = arg0;
          }
      }

Fixed Bug

  • JSDoc for FieldCreator.defaultNumericValue and FieldCreator.defaultStringValue said these methods were only for static final fields. However, they can be used in static, non-final fields.

ClassJS v0.1-alpha.4

17 Oct 12:25

Choose a tag to compare

ClassJS v0.1-alpha.4 Pre-release
Pre-release

New Features

  • ClassJSUtils.loadClass

    • Allows to load a class that was created by ClassCreator.
    let TestClass = ClassCreator.create("TestClass")
        .toPublic()
        .defaultConstructor()
        .defineClass();
    
    let loaded = ClassJSUtils.loadClass("TestClass");
    console.info(loaded === TestClass); // true
  • MethodCreator.codeJSWithThis

    • Allows to define a method where the first parameter is this.
    let TestClass = ClassCreator.create("TestClass")
        .toPublic()
        .defaultConstructor()
        .createField("testField", "int")
            .toPublic()
            .build()
        .createMethod("testMethod", ["java.lang.String", "int"], "void")
            .toPublic()
            .codeJSWithThis((thisObj, s, r) => {
                // Now, `thisObj` represents the instance of TestClass
                console.info(s + 's'.repeat(r));
                thisObj.testField = r;
            })
        .defineClass();

Fixed Bugs

  • Reloading methods written in invokeJS that are never used caused NullPointerException.
  • Specifying a method's parameter types or its return type as the currently defining class caused TypeNotPresentException.

ClassJS v0.1-alpha.3

16 Oct 15:12

Choose a tag to compare

ClassJS v0.1-alpha.3 Pre-release
Pre-release

Changes

  • code method of MethodCreator can now accept a Consumer<MethodCodeBuilder> as argument. Previously code() method with no parameter can still be used, but is marked with @deprecated.
  • Every parameter that requires a full qualified name of a class can now also accept an already loaded class.

Before

let clazz = ClassCreator.create("TestClass")
    .toPublic()
    .defaultConstructor()
    .createMethod("testMethod", ["java.lang.String", "char", "char"], "java.lang.String")
        .toPublic()
        .code()
            .loadObject("arg0")
            .loadInt("arg1")
            .loadInt("arg2")
            .invokeVirtual("java.lang.String", "replace", ["char", "char"], "java.lang.String")
            .returnObject()
            .build()
    .defineClass();

Now

// You can load the needed class in advance
const $String = Java.loadClass("java.lang.String");

let clazz = ClassCreator.create("TestClass")
    .toPublic()
    .defaultConstructor()
    // Use the loaded class instead of the long name of a class
    .createMethod("testMethod", [$String, "char", "char"], $String)
        .toPublic()
        .code(builder => builder
            .loadObject("arg0")
            .loadInt("arg1")
            .loadInt("arg2")
            // Class names are still supported
            .invokeVirtual($String, "replace", ["char", "char"], "java.lang.String")
            .returnObject()
        )
    .defineClass();

ClassJS v0.1-alpha.2

14 Oct 14:51

Choose a tag to compare

ClassJS v0.1-alpha.2 Pre-release
Pre-release

ClassJS v0.1-alpha.2

Fixed Bugs

  • Did not handle void return when using invokeJS.
  • Used system class loader when creating MethodTypes, causing TypeNotPresentExceptions.
  • dots were not replaced to slashes in custom classes' class names.
  • Function identifiers used in invokeJS with the same name but different descriptors cannot be seperated.
  • The class ClassJSClassLoader was not denied by the ClassFilter.

ClassJS v0.1-alpha.1

14 Oct 08:44

Choose a tag to compare

ClassJS v0.1-alpha.1 Pre-release
Pre-release

Initial release.