Skip to content

Commit

Permalink
Updated to v1.4
Browse files Browse the repository at this point in the history
Added event cache, and fixed some problems.
  • Loading branch information
Prunoideae committed Mar 4, 2022
1 parent 5a70bca commit 6e83d92
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 60 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

A data dumper and typing generator for the KubeJS functions, constants and classes.

A recent migration to pure java makes the mod can function without any extra dependencies, enjoy the scripting!

Great thanks to @DAmNRelentless, @LatvianModder and @yesterday17 for invaluable suggestions during the development!

## 1. Showcase
Expand Down Expand Up @@ -35,6 +33,9 @@ Auto-completion, type-hinting for most of the functions and classes:
3. Reload your IDE if your IDE doesn't know about the changes of typings, you will see the `onEvent` and `captureEvent`
with correct typings now.
4. If you want to remove the mod, don't forget to replace all `captureEvent` back to `onEvent`.
5. v1.4 allows dumped events to be persisted between dumps, no matter actually they're fired or not in current dump, if
an event is missing (mostly from the removal of mods), cached events will be automatically removed too. If you want
to clear the cache manually, use `/probejs clear_cache`.

## 4. Beaning

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ apply from: 'https://files.latmod.com/public/markdown-git-changelog.gradle'
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17

def ENV = System.getenv()
version = "${mod_version}-build.18"
version = "${mod_version}-build.22"
archivesBaseName = project.archives_base_name
group = project.maven_group

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ org.gradle.daemon=false
loom.platform=forge
mod_id=probejs
archives_base_name=probejs
mod_version=1.3.0
mod_version=1.4.0
maven_group=com.prunoideae
mod_author=Prunoideae
minecraft_version=1.18.1
Expand Down
27 changes: 23 additions & 4 deletions src/main/java/com/prunoideae/probejs/ProbeCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.prunoideae.probejs.typings.KubeCompiler;
import com.prunoideae.probejs.typings.ProbeCompiler;
import com.prunoideae.probejs.typings.SpecialFormatters;
import dev.latvian.mods.kubejs.KubeJSPaths;
import dev.latvian.mods.kubejs.server.ServerSettings;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
Expand All @@ -16,6 +17,8 @@
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.world.level.storage.WorldData;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;

public class ProbeCommands {
Expand All @@ -28,20 +31,37 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
try {
export(context.getSource());
KubeCompiler.fromKubeDump();
context.getSource().sendSuccess(new TextComponent("KubeJS registry snippets generated."), false);
SpecialFormatters.init();
ProbeCompiler.compileDeclarations();
} catch (Exception e) {
e.printStackTrace();
context.getSource().sendSuccess(new TextComponent("Uncaught exception happened in wrapper, please report to the Github issue with complete latest.log."), false);
}
context.getSource().sendSuccess(new TextComponent("Typing generation finished."), false);
context.getSource().sendSuccess(new TextComponent("ProbeJS typing generation finished."), false);
return Command.SINGLE_SUCCESS;
}))
.then(Commands.literal("clear_cache"))
.requires(source -> source.getServer().isSingleplayer() || source.hasPermission(2))
.executes(context -> {
Path path = KubeJSPaths.EXPORTED.resolve("cachedEvents.json");
if (Files.exists(path)) {
if (path.toFile().delete()) {
context.getSource().sendSuccess(new TextComponent("Cache files removed."), false);
} else {
context.getSource().sendSuccess(new TextComponent("Failed to remove cache files."), false);
}
} else {
context.getSource().sendSuccess(new TextComponent("No cached files to be cleared."), false);
}
return Command.SINGLE_SUCCESS;
})
);
}

private static int export(CommandSourceStack source) {
private static void export(CommandSourceStack source) {
if (ServerSettings.dataExport != null) {
return 0;
return;
}

ServerSettings.source = source;
Expand All @@ -63,6 +83,5 @@ private static int export(CommandSourceStack source) {
}

ReloadCommand.reloadPacks(collection2, source);
return 1;
}
}
4 changes: 0 additions & 4 deletions src/main/java/com/prunoideae/probejs/toucher/ClassInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,6 @@ public ConstructorInfo(Constructor<?> constructor) {
this.constructor = constructor;
}

public String getName() {
return this.constructor.getName();
}

public List<ParamInfo> getParamsInfo() {
return Arrays.stream(this.constructor.getParameters()).map(ParamInfo::new).collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

import com.google.common.primitives.Primitives;

import javax.lang.model.SourceVersion;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class ClassToucher {
Expand All @@ -15,10 +13,6 @@ public class ClassToucher {
private boolean dumpFields;
private boolean dumpConstructors;

public static boolean isClassName(String name) {
return name.contains(".") && SourceVersion.isName(name) && !SourceVersion.isKeyword(name);
}

private static Class<?> getClassOrComponent(Class<?> clazz) {
if (clazz == null)
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import dev.latvian.mods.kubejs.script.BindingsEvent;
import dev.latvian.mods.kubejs.script.ScriptManager;
import dev.latvian.mods.rhino.BaseFunction;
import dev.latvian.mods.rhino.util.DynamicFunction;

import java.util.HashMap;

Expand Down
20 changes: 10 additions & 10 deletions src/main/java/com/prunoideae/probejs/typings/KubeCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ public JsonObject toSnippet() {
byModMembers.put(rl[0], new ArrayList<>());
byModMembers.get(rl[0]).add(rl[1]);
});
byModMembers.forEach((mod, mems) -> {
JsonObject modMembers = new JsonObject();
byModMembers.forEach((mod, modMembers) -> {
JsonObject modMembersJson = new JsonObject();
JsonArray prefixes = new JsonArray();
prefixes.add("@%s.%s".formatted(mod, type));
modMembers.add("prefix", prefixes);
modMembers.addProperty("body", "\"%s:${1|%s|}\"".formatted(mod, String.join(",", mems)));
resultJson.add("%s_%s".formatted(type, mod), modMembers);
modMembersJson.add("prefix", prefixes);
modMembersJson.addProperty("body", "\"%s:${1|%s|}\"".formatted(mod, String.join(",", modMembers)));
resultJson.add("%s_%s".formatted(type, mod), modMembersJson);
});
}

Expand All @@ -66,13 +66,13 @@ public JsonObject toSnippet() {
byModMembers.put(rl[0], new ArrayList<>());
byModMembers.get(rl[0]).add(rl[1]);
});
byModMembers.forEach((mod, mems) -> {
JsonObject modMembers = new JsonObject();
byModMembers.forEach((mod, modMembers) -> {
JsonObject modMembersJson = new JsonObject();
JsonArray prefixes = new JsonArray();
prefixes.add("@%s.tags.%s".formatted(mod, type));
modMembers.add("prefix", prefixes);
modMembers.addProperty("body", "\"#%s:${1|%s|}\"".formatted(mod, String.join(",", mems)));
resultJson.add("%s_tag_%s".formatted(type, mod), modMembers);
modMembersJson.add("prefix", prefixes);
modMembersJson.addProperty("body", "\"#%s:${1|%s|}\"".formatted(mod, String.join(",", modMembers)));
resultJson.add("%s_tag_%s".formatted(type, mod), modMembersJson);
});
}

Expand Down
55 changes: 44 additions & 11 deletions src/main/java/com/prunoideae/probejs/typings/ProbeCompiler.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.prunoideae.probejs.typings;

import com.google.common.primitives.Primitives;
import com.google.gson.Gson;
import com.mojang.datafixers.util.Pair;
import com.prunoideae.probejs.ProbeJS;
import com.prunoideae.probejs.plugin.WrappedEventHandler;
import com.prunoideae.probejs.toucher.ClassInfo;
import com.prunoideae.probejs.toucher.ClassToucher;
import dev.latvian.mods.kubejs.KubeJSPaths;
import dev.latvian.mods.kubejs.event.EventJS;
import dev.latvian.mods.kubejs.recipe.RecipeTypeJS;
import dev.latvian.mods.kubejs.recipe.RegisterRecipeHandlersEvent;
import dev.latvian.mods.kubejs.server.ServerScriptManager;
Expand Down Expand Up @@ -36,12 +38,16 @@ private static void resolveClassname(Set<Class<?>> globalClasses, Set<Class<?>>
}
}

public static Set<Class<?>> compileGlobal(Path outFile, Map<ResourceLocation, RecipeTypeJS> typeMap, DummyBindingEvent bindingEvent) {
public static Set<Class<?>> compileGlobal(Path outFile, Map<ResourceLocation, RecipeTypeJS> typeMap, DummyBindingEvent bindingEvent, Set<Class<?>> cachedClasses) {
Set<Class<?>> touchableClasses = new HashSet<>(bindingEvent.getClassDumpMap().values());


bindingEvent.getClassDumpMap().forEach((k, v) -> {
TSGlobalClassFormatter.resolvedClassName.put(v.getName(), k);
touchableClasses.add(v);
});

touchableClasses.addAll(cachedClasses);
touchableClasses.addAll(typeMap.values().stream().map(recipeTypeJS -> recipeTypeJS.factory.get().getClass()).collect(Collectors.toList()));
touchableClasses.addAll(bindingEvent.getConstantDumpMap().values().stream().map(Object::getClass).collect(Collectors.toList()));
touchableClasses.addAll(WrappedEventHandler.capturedEvents.values());
Expand Down Expand Up @@ -88,9 +94,7 @@ public static Set<Class<?>> compileGlobal(Path outFile, Map<ResourceLocation, Re
});

List<TSGlobalClassFormatter.ClassFormatter> dummyRecipeClasses = new ArrayList<>();
recipeMethodClassPlaceholder.forEach((k, v) -> {
dummyRecipeClasses.add(new TSDummyClassFormatter.DummyMethodClassFormatter(k, v));
});
recipeMethodClassPlaceholder.forEach((k, v) -> dummyRecipeClasses.add(new TSDummyClassFormatter.DummyMethodClassFormatter(k, v)));
namespacedClasses.put("stub.probejs.recipes", dummyRecipeClasses);
namespacedClasses.put("stub.probejs", List.of(new TSDummyClassFormatter.DummyFieldClassFormatter("RecipeHolder", recipeHolderFields.stream().toList())));

Expand All @@ -112,10 +116,11 @@ public static Set<Class<?>> compileGlobal(Path outFile, Map<ResourceLocation, Re
return globalClasses;
}

public static void compileEvent(Path outFile) {
public static void compileEvent(Path outFile, Map<String, Class<? extends EventJS>> cachedEvents) {
ProbeJS.LOGGER.info("Compiling captured events...");
try (BufferedWriter writer = Files.newBufferedWriter(outFile)) {
writer.write("/// <reference path=\"./globals.d.ts\" />\n");
WrappedEventHandler.capturedEvents.putAll(cachedEvents);
WrappedEventHandler.capturedEvents.forEach(
(capture, event) -> {
try {
Expand All @@ -139,9 +144,11 @@ public static void compileConstants(Path outFile, DummyBindingEvent bindingEvent
(name, value) -> {
try {
if (TSGlobalClassFormatter.staticValueTransformer.containsKey(value.getClass()))
writer.write("declare const %s: %s;\n".formatted(name, TSGlobalClassFormatter.staticValueTransformer.get(value.getClass()).apply(value)));
else
writer.write("declare const %s: %s;\n".formatted(name, TSGlobalClassFormatter.resolvedClassName.get(value.getClass().getName())));
if (TSGlobalClassFormatter.staticValueTransformer.get(value.getClass()).apply(value) != null) {
writer.write("declare const %s: %s;\n".formatted(name, TSGlobalClassFormatter.staticValueTransformer.get(value.getClass()).apply(value)));
return;
}
writer.write("declare const %s: %s;\n".formatted(name, TSGlobalClassFormatter.resolvedClassName.get(value.getClass().getName())));
} catch (IOException e) {
e.printStackTrace();
}
Expand All @@ -161,7 +168,7 @@ public static void compileJava(Path outFile, Set<Class<?>> classes) {
.filter(clazz -> ServerScriptManager.instance.scriptManager.isClassAllowed(clazz.getName()))
.forEach(clazz -> {
try {
writer.write("declare function java(name: \"%s\"): %s;\n".formatted(clazz.getName(), TSGlobalClassFormatter.resolvedClassName.get(clazz.getName())));
writer.write("declare function java(name: \"%s\"): typeof %s;\n".formatted(clazz.getName(), TSGlobalClassFormatter.resolvedClassName.get(clazz.getName())));
} catch (IOException e) {
e.printStackTrace();
}
Expand Down Expand Up @@ -207,11 +214,37 @@ public static void compileDeclarations() throws IOException {
KubeJSPlugins.forEachPlugin(plugin -> plugin.addRecipes(recipeEvent));
KubeJSPlugins.forEachPlugin(plugin -> plugin.addBindings(bindingEvent));

Set<Class<?>> touchedClasses = compileGlobal(typingDir.resolve("globals.d.ts"), typeMap, bindingEvent);
compileEvent(typingDir.resolve("events.d.ts"));
Map<String, Class<? extends EventJS>> cachedEvents = new HashMap<>();
Path cachedEventPath = KubeJSPaths.EXPORTED.resolve("cachedEvents.json");
if (Files.exists(cachedEventPath)) {
Map<?, ?> cachedMap = new Gson().fromJson(Files.newBufferedReader(cachedEventPath), Map.class);
cachedMap.forEach((k, v) -> {
if (k instanceof String && v instanceof String) {
try {
Class<?> clazz = Class.forName((String) v);
if (EventJS.class.isAssignableFrom(clazz))
cachedEvents.put((String) k, (Class<? extends EventJS>) clazz);
} catch (ClassNotFoundException e) {
ProbeJS.LOGGER.warn("Class %s was in the cache, but disappeared in packages now.".formatted(v));
}
}
});
}

Set<Class<?>> cachedClasses = new HashSet<>(cachedEvents.values());
Set<Class<?>> touchedClasses = compileGlobal(typingDir.resolve("globals.d.ts"), typeMap, bindingEvent, cachedClasses);
compileEvent(typingDir.resolve("events.d.ts"), cachedEvents);
compileConstants(typingDir.resolve("constants.d.ts"), bindingEvent);
compileJava(typingDir.resolve("java.d.ts"), touchedClasses);
compileIndex(typingDir.resolve("index.d.ts"));
try (BufferedWriter writer = Files.newBufferedWriter(cachedEventPath)) {
Map<String, String> eventsCache = new HashMap<>();
WrappedEventHandler.capturedEvents.forEach((k, v) -> eventsCache.put(k, v.getName()));
new Gson().toJson(eventsCache, writer);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
if (Files.notExists(KubeJSPaths.DIRECTORY.resolve("jsconfig.json")))
compileJSConfig(KubeJSPaths.DIRECTORY.resolve("jsconfig.json"));
ProbeJS.LOGGER.info("All done!");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.prunoideae.probejs.typings;

import com.google.common.primitives.Primitives;
import com.google.gson.Gson;
import com.prunoideae.probejs.toucher.ClassInfo;
import com.prunoideae.probejs.toucher.ClassToucher;
import dev.latvian.mods.kubejs.recipe.RecipeEventJS;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
Expand Down Expand Up @@ -54,6 +56,27 @@ private static Function<ClassInfo.TypeInfo, String> generateParamFunction(int pa
};
}

private static String formatMapKV(Object obj) {
//Only Map<string, Object> is allowed
//Others are discarded, if there are others
Map<?, ?> map = (Map<?, ?>) obj;
if (map.keySet().stream().anyMatch(o -> o instanceof String)) {
return "{%s}".formatted(map.entrySet()
.stream()
.filter(entry -> entry.getKey() != null)
.filter(entry -> entry.getKey() instanceof String)
.map(entry -> {
if (TSGlobalClassFormatter.FieldFormatter.formatValue(entry.getValue()) != null) {
return "%s: %s".formatted(new Gson().toJson(entry.getKey()), TSGlobalClassFormatter.FieldFormatter.formatValue(entry.getValue()));
}
return "%s: %s".formatted(new Gson().toJson(entry.getKey()), new TSGlobalClassFormatter.TypeFormatter(new ClassInfo.TypeInfo(entry.getValue().getClass(), entry.getValue().getClass())).format());
})
.collect(Collectors.joining(", ")));
} else {
return null;
}
}

private static void putStaticValueTransformer(Function<Object, String> transformer, Class<?>... types) {
for (Class<?> type : types)
TSGlobalClassFormatter.staticValueTransformer.put(type, transformer);
Expand Down Expand Up @@ -91,6 +114,8 @@ public static void init() {
Long.TYPE, Long.class,
Short.TYPE, Short.class,
Void.TYPE, Void.class);
putStaticValueTransformer(o -> new Gson().toJson(((ResourceLocation) o).toString()), ResourceLocation.class);
putStaticValueTransformer(SpecialFormatters::formatMapKV, HashMap.class, Map.class);
putStaticValueTransformer(o -> new Gson().toJson(o), String.class, Character.TYPE, Character.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public DummyMethodClassFormatter(String name, List<Pair<String, TSGlobalClassFor
@Override
public String format() {
List<String> innerLines = new ArrayList<>();
innerLines.add("%sclass %s {".formatted(" ".repeat(this.indentation), this.name));
innerLines.add(" ".repeat(this.indentation) + "class %s {".formatted(this.name));
pairs.forEach(pair -> innerLines.add("%s%s(...args: object): %s".formatted(" ".repeat(this.indentation + this.stepIndentation), pair.getFirst(), pair.getSecond().format())));
innerLines.add("}\n");
return String.join("\n", innerLines);
Expand All @@ -42,7 +42,7 @@ public DummyFieldClassFormatter(String name, List<Pair<String, String>> pairs) {
@Override
public String format() {
List<String> innerLines = new ArrayList<>();
innerLines.add("%sclass %s {".formatted(" ".repeat(this.indentation), this.name));
innerLines.add(" ".repeat(this.indentation) + "class %s {".formatted(this.name));
pairs.forEach(pair -> innerLines.add("%s%s: %s".formatted(" ".repeat(this.indentation + this.stepIndentation), pair.getFirst(), pair.getSecond())));
innerLines.add("}\n");
return String.join("\n", innerLines);
Expand Down
Loading

0 comments on commit 6e83d92

Please sign in to comment.