diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/groovy/ModuleNodeMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/groovy/ModuleNodeMixin.java new file mode 100644 index 000000000..f097be130 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/groovy/ModuleNodeMixin.java @@ -0,0 +1,60 @@ +package com.cleanroommc.groovyscript.core.mixin.groovy; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.sandbox.FileUtil; +import org.codehaus.groovy.ast.ModuleNode; +import org.codehaus.groovy.ast.PackageNode; +import org.codehaus.groovy.control.SourceUnit; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.File; + +@Mixin(value = ModuleNode.class, remap = false) +public abstract class ModuleNodeMixin { + + @Shadow private PackageNode packageNode; + + @Shadow private transient SourceUnit context; + + @Inject(method = "(Lorg/codehaus/groovy/control/SourceUnit;)V", at = @At("TAIL")) + public void init(SourceUnit context, CallbackInfo ci) { + // auto set package name + String script = context.getName(); + String rel = FileUtil.relativize(GroovyScript.getScriptPath(), script); + int i = rel.lastIndexOf(File.separatorChar); + if (i >= 0) { + // inject correct package declaration into script + String packageName = rel.substring(0, i).replace(File.separatorChar, '.') + '.'; + this.packageNode = new PackageNode(packageName); + } + } + + @Inject(method = "setPackage", at = @At("HEAD"), cancellable = true) + public void setPackage(PackageNode packageNode, CallbackInfo ci) { + if (this.packageNode == null || this.context == null) return; + // package name was already set -> only copy data of new node + String cur = this.packageNode.getName(); + String newName = packageNode.getName(); + if (!cur.equals(newName)) { + String rel = FileUtil.relativize(GroovyScript.getScriptPath(), this.context.getName()); + GroovyLog.get().error("Expected package {} but got {} in script {}", cur, newName, rel); + } + if (this.packageNode.getAnnotations() != null) { + this.packageNode.getAnnotations().clear(); + } + if (packageNode.getAnnotations() != null) { + this.packageNode.addAnnotations(packageNode.getAnnotations()); + } + this.packageNode.setMetaDataMap(null); + this.packageNode.copyNodeMetaData(packageNode); + this.packageNode.setDeclaringClass(packageNode.getDeclaringClass()); + this.packageNode.setSynthetic(packageNode.isSynthetic()); + this.packageNode.setSourcePosition(packageNode); + ci.cancel(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/sandbox/transformer/GroovyScriptEarlyCompiler.java b/src/main/java/com/cleanroommc/groovyscript/sandbox/transformer/GroovyScriptEarlyCompiler.java index bf1bfc33b..040d31c6f 100644 --- a/src/main/java/com/cleanroommc/groovyscript/sandbox/transformer/GroovyScriptEarlyCompiler.java +++ b/src/main/java/com/cleanroommc/groovyscript/sandbox/transformer/GroovyScriptEarlyCompiler.java @@ -1,11 +1,8 @@ package com.cleanroommc.groovyscript.sandbox.transformer; -import com.cleanroommc.groovyscript.GroovyScript; -import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.core.mixin.groovy.ModuleNodeAccessor; -import com.cleanroommc.groovyscript.sandbox.FileUtil; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.MethodNode; @@ -24,7 +21,6 @@ import org.codehaus.groovy.syntax.Token; import org.codehaus.groovy.syntax.Types; -import java.io.File; import java.util.List; public class GroovyScriptEarlyCompiler extends CompilationCustomizer { @@ -35,19 +31,7 @@ public GroovyScriptEarlyCompiler() { @Override public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException { - String root = GroovyScript.getScriptPath(); - String script = source.getName(); ModuleNode module = classNode.getModule(); - String rel = FileUtil.relativize(root, script); - int i = rel.lastIndexOf(File.separatorChar); - if (i >= 0) { - // inject correct package declaration into script - String packageName = rel.substring(0, i).replace(File.separatorChar, '.') + '.'; - if (module.getPackage() != null && !module.getPackage().getName().equals(packageName)) { - GroovyLog.get().error("Expected package {} but got {} in script {}", packageName, module.getPackage().getName(), rel); - } - module.setPackageName(packageName); - } List methods = module.getClasses().get(0).getMethods("run"); if (methods.isEmpty()) return; // class scripts don't have a run method BlockStatement scriptStatement = (BlockStatement) methods.get(0).getCode(); diff --git a/src/main/resources/mixin.groovyscript.json b/src/main/resources/mixin.groovyscript.json index 5fb8103ae..79cfe2a83 100644 --- a/src/main/resources/mixin.groovyscript.json +++ b/src/main/resources/mixin.groovyscript.json @@ -29,6 +29,7 @@ "groovy.Java8Mixin", "groovy.MetaClassImplMixin", "groovy.ModuleNodeAccessor", + "groovy.ModuleNodeMixin", "loot.LoadTableEventMixin", "loot.LootPoolAccessor", "loot.LootTableAccessor", @@ -36,6 +37,6 @@ ], "client": [ "DefaultResourcePackAccessor", - "GuiCreateWorldMixin", + "GuiCreateWorldMixin" ] -} \ No newline at end of file +}