Skip to content

Commit a747c5b

Browse files
authored
GroovyCompiler (#2)
* test using groovy * fix star imports * add new context * maven? * maven? * maven * fix * fix
1 parent f5d2380 commit a747c5b

File tree

9 files changed

+142
-11
lines changed

9 files changed

+142
-11
lines changed

build.gradle

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,24 @@ repositories {
9191
name 'CurseMaven'
9292
url 'https://curse.cleanroommc.com'
9393
}
94+
maven {
95+
name 'BlameJared Maven'
96+
url 'https://maven.blamejared.com'
97+
}
98+
maven {
99+
name 'GTNH Maven'
100+
url 'https://nexus.gtnewhorizons.com/repository/public/'
101+
}
102+
maven {
103+
name 'GTCEu Maven'
104+
url 'https://maven.gtceu.com'
105+
}
94106
}
95107

96108

97109
dependencies {
98110
implementation 'curse.maven:resource-mod-loader-945917:5768125+5768126'
111+
implementation 'com.cleanroommc:groovyscript:1.2.3'
99112
if (propertyBool('use_asset_mover')) {
100113
implementation "com.cleanroommc:assetmover:${propertyString('asset_mover_version')}"
101114
}

src/main/java/mods/Hileb/shotaasm/ScriptLoader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
import java.util.stream.Collectors;
1616

1717
public class ScriptLoader {
18-
private static Collection<IScriptLocator> locators;
19-
private static HashMap<String, IScriptCompiler> compilers = new HashMap<>();
18+
public static Collection<IScriptLocator> locators;
19+
public static HashMap<String, IScriptCompiler> compilers = new HashMap<>();
2020

2121
public static void initialize() {
2222
locators = loadServices(IScriptLocator.class).stream().map( aClass -> {

src/main/java/mods/Hileb/shotaasm/ShotaASM.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.google.common.eventbus.Subscribe;
55
import mods.Hileb.shotaasm.api.ShotaContext;
66
import mods.Hileb.shotaasm.impl.ShotaCompiler;
7+
import mods.Hileb.shotaasm.impl.EventHandler;
78
import net.minecraftforge.fml.common.LoadController;
89
import net.minecraftforge.fml.common.ModMetadata;
910
import net.minecraftforge.fml.common.event.FMLStateEvent;
@@ -71,7 +72,7 @@ public File getSource() {
7172

7273
@Subscribe
7374
public void onFMLState(FMLStateEvent event) {
74-
ShotaCompiler.executeEvent(event.getEventType());
75+
EventHandler.executeEvent(event.getEventType());
7576
}
7677

7778
}

src/main/java/mods/Hileb/shotaasm/api/ShotaContext.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ public static void initialize() {}
66
public static boolean isClassExist(String name) {
77
return net.minecraft.launchwrapper.Launch.classLoader.isClassExist(name);
88
}
9+
10+
public static java.util.Set<String> supportedCompilers() {
11+
return mods.Hileb.shotaasm.ScriptLoader.compilers.keySet();
12+
}
913
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package mods.Hileb.shotaasm.impl;
2+
3+
import com.google.common.collect.HashMultimap;
4+
5+
public class EventHandler {
6+
private static final HashMultimap<String, Runnable> eventTasks = HashMultimap.create();
7+
8+
public static void executeEvent(String evt) {
9+
eventTasks.get(evt).forEach(Runnable::run);
10+
eventTasks.removeAll(evt);
11+
}
12+
13+
public static void addEvent(String evt, Runnable r) {
14+
eventTasks.put(evt, r);
15+
}
16+
}

src/main/java/mods/Hileb/shotaasm/impl/ShotaCompiler.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@
1616
import java.lang.reflect.InvocationTargetException;
1717

1818
public class ShotaCompiler implements IScriptCompiler {
19-
private static final HashMultimap<String, Runnable> eventTasks = HashMultimap.create();
20-
21-
public static void executeEvent(String evt) {
22-
eventTasks.get(evt).forEach(Runnable::run);
23-
eventTasks.removeAll(evt);
24-
}
2519

2620
@Override
2721
public String name() {
@@ -35,7 +29,7 @@ public Runnable compile(final ScriptFile file) {
3529
if (file.property().containsKey("event")) {
3630
String event = Iterables.getFirst(file.property().get("event"), null);
3731
if (event != null) {
38-
eventTasks.put(event, () -> ShotaCompiler.this.compile(file));
32+
EventHandler.addEvent(event, () -> ShotaCompiler.this.compile(file));
3933
return () -> {};
4034
} else return null;
4135
} else {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package mods.Hileb.shotaasm.impl.groovy;
2+
3+
import com.google.common.collect.HashMultimap;
4+
import com.google.common.collect.Iterables;
5+
6+
import mods.Hileb.shotaasm.api.ShotaContext;
7+
import mods.Hileb.shotaasm.api.IScriptCompiler;
8+
import mods.Hileb.shotaasm.api.ScriptFile;
9+
import mods.Hileb.shotaasm.impl.EventHandler;
10+
11+
public class GroovyShotaCompiler implements IScriptCompiler {
12+
13+
@Override
14+
public String name() {
15+
return "groovyShota";
16+
}
17+
18+
@Override
19+
public Runnable compile(final ScriptFile file) {
20+
if (ShotaContext.isClassExist("groovy.lang.GroovyClassLoader")) {
21+
if (file.property().containsKey("event")) {
22+
String event = Iterables.getFirst(file.property().get("event"), null);
23+
if (event != null) {
24+
EventHandler.addEvent(event, () -> GroovyShotaCompiler.this.compile(file));
25+
return () -> {};
26+
} else throw new RuntimeException("Could not understand the first event property is null. At " + file.name());
27+
} else {
28+
String singleName = file.name().substring(0, file.name().lastIndexOf('.')).replace('.', '_') + file.hashCode();
29+
String name = "mods.Hileb.shotaasm.dynamic.groovy" + singleName;
30+
StringBuilder builder = new StringBuilder();
31+
for (String s : file.property().get("import")) {
32+
builder.append("import ").append(s).append(";\n");
33+
}
34+
builder.append("\n").append(file.text());
35+
try {
36+
return ShotaGroovySandbox.compileScript(name, builder.toString());
37+
} catch (Throwable e) {
38+
throw new RuntimeException("Unable to compile for " + file.name(), e);
39+
}
40+
}
41+
} else {
42+
throw new RuntimeException("Groovy Support not found. But " + file.name() + " required the compiler of groovyShota.");
43+
}
44+
}
45+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package mods.Hileb.shotaasm.impl.groovy;
2+
3+
import org.codehaus.groovy.control.customizers.ImportCustomizer;
4+
import org.codehaus.groovy.control.CompilerConfiguration;
5+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
6+
import groovy.lang.Binding;
7+
import groovy.lang.GroovyClassLoader;
8+
import groovy.lang.Script;
9+
import org.codehaus.groovy.runtime.InvokerHelper;
10+
import mods.Hileb.shotaasm.api.ScriptFile;
11+
import net.minecraft.launchwrapper.Launch;
12+
13+
import java.util.*;
14+
15+
public class ShotaGroovySandbox {
16+
17+
ImportCustomizer importCustomizer = new ImportCustomizer();
18+
CompilerConfiguration config = new CompilerConfiguration();
19+
Map<String, Object> bindings = new Object2ObjectOpenHashMap<>();
20+
Binding binding = new Binding(this.bindings);
21+
GroovyClassLoader classLoader;
22+
23+
public ShotaGroovySandbox() {
24+
importCustomizer = new ImportCustomizer();
25+
config = new CompilerConfiguration();
26+
27+
importCustomizer.addImports(
28+
"mods.Hileb.shotaasm.api.TransformerRegistry",
29+
"mods.Hileb.shotaasm.api.ShotaContext"
30+
);
31+
importCustomizer.addStarImports(
32+
"org.objectweb.asm",
33+
"org.objectweb.asm.tree",
34+
"org.objectweb.asm.util",
35+
"org.objectweb.asm.commons",
36+
"org.objectweb.asm.signature"
37+
);
38+
importCustomizer.addStaticStars("org.objectweb.asm.Opcodes");
39+
config.addCompilationCustomizers(importCustomizer);
40+
classLoader = new GroovyClassLoader(Launch.classLoader, config, false);
41+
}
42+
43+
public Class<?> compile(String name, String text) {
44+
return classLoader.parseClass(text, name);
45+
}
46+
47+
public Runnable makeScript(Class<?> cls){
48+
final Script script = InvokerHelper.createScript(cls, binding);
49+
return script::run ;
50+
}
51+
52+
static ShotaGroovySandbox box = null;
53+
public static Runnable compileScript(String name, String file){
54+
if (box == null) box = new ShotaGroovySandbox();
55+
return box.makeScript(box.compile(name, file));
56+
}
57+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
mods.Hileb.shotaasm.impl.ShotaCompiler
1+
mods.Hileb.shotaasm.impl.ShotaCompiler
2+
mods.Hileb.shotaasm.impl.groovy.GroovyShotaCompiler

0 commit comments

Comments
 (0)