Add audit trail support for ModLauncher 4.2, update checkstyle

This commit is contained in:
Mumfrey committed 2019-11-09 18:38:45 +00:00
1 parent 5ada553610
commit d4fa032d7d
16 files changed
+297 -28

No files matched your search

+2 -2
View File
@@ -154,7 +154,7 @@ dependencies {
modlauncherCompile "org.ow2.asm:asm-tree:$modlauncherAsmVersion"
modlauncherCompile "org.ow2.asm:asm-commons:$modlauncherAsmVersion"
modlauncherCompile "org.ow2.asm:asm-util:$modlauncherAsmVersion"
modlauncherCompile ('cpw.mods:modlauncher:4.0.0') {
modlauncherCompile ('cpw.mods:modlauncher:4.2.0') {
exclude module: 'log4j-core'
}
@@ -220,7 +220,7 @@ checkstyle {
"year" : project.inceptionYear
]
configFile = file("checkstyle.xml")
toolVersion = '8.10'
toolVersion = '8.24'
}
// Source compiler configuration
+19 -13
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Check Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
This configuration file was written by the eclipse-cs plugin configuration editor
@@ -18,13 +18,6 @@
<property name="format" value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message" value="Avoid using corresponding octal or Unicode escape."/>
</module>
<module name="LineLength">
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
<property name="max" value="150"/>
</module>
<module name="LineLength">
<property name="ignorePattern" value="^[ ]*([a-zA-Z0-9\{\}\+\|\&amp;\&quot;@\(\)\?\.\:]|//)"/>
</module>
<module name="EmptyBlock">
<property name="option" value="TEXT"/>
<property name="tokens" value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
@@ -34,7 +27,11 @@
<module name="RightCurly"/>
<module name="RightCurly">
<property name="option" value="alone"/>
<property name="tokens" value="CLASS_DEF,METHOD_DEF,CTOR_DEF,LITERAL_FOR,LITERAL_WHILE,STATIC_INIT,INSTANCE_INIT"/>
<property name="tokens" value="CLASS_DEF,METHOD_DEF,LITERAL_FOR,LITERAL_WHILE,STATIC_INIT,INSTANCE_INIT"/>
</module>
<module name="RightCurly">
<property name="option" value="alone_or_singleline"/>
<property name="tokens" value="CTOR_DEF"/>
</module>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
@@ -65,7 +62,6 @@
</module>
<module name="LocalVariableName">
<property name="format" value="^[a-z](([a-z0-9])|([a-z0-9][a-zA-Z0-9]*))?$"/>
<property name="tokens" value="VARIABLE_DEF"/>
<message key="name.invalidPattern" value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ClassTypeParameterName">
@@ -130,9 +126,7 @@
</module>
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<module name="TypecastParenPad">
<property name="tokens" value="RPAREN,TYPECAST"/>
</module>
<module name="TypecastParenPad"/>
<module name="ConstantName">
<property name="applyToProtected" value="false"/>
<property name="applyToPackage" value="false"/>
@@ -142,7 +136,19 @@
<module name="UncommentedMain"/>
<module name="SuppressionCommentFilter"/>
</module>
<module name="LineLength">
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
<property name="max" value="150"/>
</module>
<module name="LineLength">
<property name="ignorePattern" value="^[ ]*([a-zA-Z0-9\{\}\+\|\&amp;\&quot;@\(\)\?\.\:]|//)"/>
</module>
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="SuppressWithPlainTextCommentFilter">
<property name="offCommentFormat" value="\*.*&lt;pre&gt;"/>
<property name="onCommentFormat" value="\*.*&lt;/pre&gt;"/>
<property name="checkFormat" value="LineLength"/>
</module>
</module>
@@ -28,7 +28,6 @@ import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.processing.Filer;
@@ -54,6 +54,7 @@ import org.spongepowered.asm.service.IClassBytecodeProvider;
import org.spongepowered.asm.service.IClassProvider;
import org.spongepowered.asm.service.IClassTracker;
import org.spongepowered.asm.service.ILegacyClassTransformer;
import org.spongepowered.asm.service.IMixinAuditTrail;
import org.spongepowered.asm.service.ITransformer;
import org.spongepowered.asm.service.ITransformerProvider;
import org.spongepowered.asm.service.MixinServiceAbstract;
@@ -277,6 +278,14 @@ public class MixinServiceLaunchWrapper extends MixinServiceAbstract implements I
return this.classLoaderUtil;
}
/* (non-Javadoc)
* @see org.spongepowered.asm.service.IMixinService#getAuditTrail()
*/
@Override
public IMixinAuditTrail getAuditTrail() {
return null;
}
/* (non-Javadoc)
* @see org.spongepowered.asm.service.IClassProvider#findClass(
* java.lang.String)
@@ -39,7 +39,6 @@ import org.spongepowered.asm.mixin.transformer.throwables.InvalidMixinException;
@Retention(RetentionPolicy.RUNTIME)
public @interface Shadow {
// CHECKSTYLE:OFF
/**
* <p>In general, shadow methods can be declared using their name in the
* target class as you would expect, however we run into a problem when we
@@ -86,7 +85,6 @@ public @interface Shadow {
* @return the shadow prefix
*/
public String prefix() default "shadow$";
// CHECKSTYLE:ON
/**
* By default, the annotation processor will attempt to locate an
@@ -147,6 +147,15 @@ public final class ArgsClassGenerator implements IClassGenerator {
public ArgsClassGenerator(IConsumer<ISyntheticClassInfo> registry) {
this.registry = registry;
}
/* (non-Javadoc)
* @see org.spongepowered.asm.mixin.transformer.ext.IClassGenerator
* #getName()
*/
@Override
public String getName() {
return "args";
}
/**
* Get (or generate) the class name for the specified descriptor. The class
@@ -264,6 +264,15 @@ final class InnerClassGenerator implements IClassGenerator {
this.registry = registry;
}
/* (non-Javadoc)
* @see org.spongepowered.asm.mixin.transformer.ext.IClassGenerator
* #getName()
*/
@Override
public String getName() {
return "inner";
}
/**
* @param owner Mixin which owns the original inner class
* @param originalName Original inner class name
@@ -57,6 +57,8 @@ import org.spongepowered.asm.mixin.transformer.meta.MixinMerged;
import org.spongepowered.asm.mixin.transformer.meta.MixinRenamed;
import org.spongepowered.asm.mixin.transformer.throwables.InvalidMixinException;
import org.spongepowered.asm.mixin.transformer.throwables.MixinApplicatorException;
import org.spongepowered.asm.service.IMixinAuditTrail;
import org.spongepowered.asm.service.MixinService;
import org.spongepowered.asm.util.Annotations;
import org.spongepowered.asm.util.Bytecode;
import org.spongepowered.asm.util.Bytecode.DelegateInitialiser;
@@ -241,6 +243,11 @@ class MixinApplicatorStandard {
*/
protected final Profiler profiler = MixinEnvironment.getProfiler();
/**
* Audit trail (if available);
*/
protected final IMixinAuditTrail auditTrail;
/**
* Activity tracker
*/
@@ -263,6 +270,8 @@ class MixinApplicatorStandard {
ExtensionClassExporter exporter = context.getExtensions().<ExtensionClassExporter>getExtension(ExtensionClassExporter.class);
this.mergeSignatures = exporter.isDecompilerActive()
&& MixinEnvironment.getCurrentEnvironment().getOption(Option.DEBUG_EXPORT_DECOMPILE_MERGESIGNATURES);
this.auditTrail = MixinService.getService().getAuditTrail();
}
/**
@@ -276,6 +285,9 @@ class MixinApplicatorStandard {
try {
this.logger.log(mixin.getLoggingLevel(), "Mixing {} from {} into {}", mixin.getName(), mixin.getParent(), this.targetName);
mixinContexts.add(mixin.createContextFor(this.context));
if (this.auditTrail != null) {
this.auditTrail.onApply(this.targetName, mixin.toString());
}
} catch (InvalidMixinException ex) {
if (mixin.isRequired()) {
throw ex;
@@ -32,6 +32,8 @@ import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.transformer.ext.Extensions;
import org.spongepowered.asm.mixin.transformer.ext.IClassGenerator;
import org.spongepowered.asm.service.IMixinAuditTrail;
import org.spongepowered.asm.service.MixinService;
import org.spongepowered.asm.util.perf.Profiler;
import org.spongepowered.asm.util.perf.Profiler.Section;
@@ -45,8 +47,20 @@ public class MixinClassGenerator {
*/
static final Logger logger = LogManager.getLogger("mixin");
/**
* Transformer extensions
*/
private final Extensions extensions;
/**
* Profiler
*/
private final Profiler profiler;
/**
* Audit trail (if available);
*/
private final IMixinAuditTrail auditTrail;
/**
* ctor
@@ -54,6 +68,7 @@ public class MixinClassGenerator {
MixinClassGenerator(MixinEnvironment environment, Extensions extensions) {
this.extensions = extensions;
this.profiler = MixinEnvironment.getProfiler();
this.auditTrail = MixinService.getService().getAuditTrail();
}
synchronized boolean generateClass(MixinEnvironment environment, String name, ClassNode classNode) {
@@ -67,6 +82,7 @@ public class MixinClassGenerator {
boolean success = generator.generate(name, classNode);
genTimer.end();
if (success) {
this.auditTrail.onGenerate(name, generator.getName());
this.extensions.export(environment, name.replace('.', '/'), false, classNode);
return true;
}
@@ -53,6 +53,7 @@ import org.spongepowered.asm.mixin.transformer.meta.MixinMerged;
import org.spongepowered.asm.mixin.transformer.throwables.InvalidMixinException;
import org.spongepowered.asm.mixin.transformer.throwables.MixinTransformerError;
import org.spongepowered.asm.mixin.transformer.throwables.ReEntrantTransformerError;
import org.spongepowered.asm.service.IMixinAuditTrail;
import org.spongepowered.asm.service.IMixinService;
import org.spongepowered.asm.service.MixinService;
import org.spongepowered.asm.util.PrettyPrinter;
@@ -183,6 +184,11 @@ public class MixinProcessor {
* Profiler
*/
private final Profiler profiler;
/**
* Audit trail (if available);
*/
private final IMixinAuditTrail auditTrail;
/**
* Current environment
@@ -215,6 +221,7 @@ public class MixinProcessor {
this.postProcessor = new MixinPostProcessor(this.sessionId);
this.profiler = MixinEnvironment.getProfiler();
this.auditTrail = this.service.getAuditTrail();
}
/**
@@ -282,6 +289,9 @@ public class MixinProcessor {
try {
if (this.postProcessor.canProcess(name)) {
if (this.auditTrail != null) {
this.auditTrail.onPostProcess(name);
}
Section postTimer = this.profiler.begin("postprocessor");
success = this.postProcessor.processClass(name, targetClassNode);
postTimer.end();
@@ -30,6 +30,11 @@ import org.objectweb.asm.tree.ClassNode;
* Base interface for class generators
*/
public interface IClassGenerator {
/**
* Get the name of this generator for logging and auditing purposes
*/
public abstract String getName();
/**
* Generate (if possible) the specified class name. The generator should
@@ -0,0 +1,63 @@
/*
* This file is part of Mixin, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.asm.service;
/**
* Audit trail is responsible for logging activities during mixin application to
* target classes for use as debugging information later on. An audit trail
* service can either log audit entries internally for retrieval on crash, or
* can delegate to an underlying subsystem which handles this behaviour.
*
* <p>This service component is entirely optional and services can elect to
* return <tt>null</tt> if the platform does not support this functionality.</p>
*/
public interface IMixinAuditTrail {
/**
* Called when a class has a mixin applied to it by mixin.
*
* @param className Target class name
* @param mixinName Mixin name
*/
public abstract void onApply(String className, String mixinName);
/**
* Called when a class is post-processed by mixin. This is the case for
* synthetic inner classes (eg. switch table) and for accessor interfaces.
*
* @param className Class being post-processed
*/
public abstract void onPostProcess(String className);
/**
* Called when a class is generated by mixin. This is the case for fully
* synthetic classes such as Args and non-synthetic inner classes in mixins
*
* @param className Class being generated
* @param generatorName Name of the generator
*/
public abstract void onGenerate(String className, String generatorName);
}
@@ -88,30 +88,38 @@ public interface IMixinService {
public abstract ReEntranceLock getReEntranceLock();
/**
* Return the class provider for this service
* Return the class provider for this service. <b>This component is required
* and services must not return <tt>null</tt>.</b>
*/
public abstract IClassProvider getClassProvider();
/**
* Return the class bytecode provider for this service
* Return the class bytecode provider for this service. <b>This component is
* required and services must not return <tt>null</tt>.</b>
*/
public abstract IClassBytecodeProvider getBytecodeProvider();
/**
* Return the transformer provider for this service. <b>Note that unlike
* other service components, this component is allowed to be <tt>null</tt>
* for services which do not support transformers, or don't support
* interacting with them</b>!
* Return the transformer provider for this service. <b>This component is
* optional and is allowed to be <tt>null</tt> for services which do not
* support transformers, or don't support interacting with them.</b>
*/
public abstract ITransformerProvider getTransformerProvider();
/**
* Return the class tracker for this service. <b>Note that unlike
* other service components, this component is allowed to be <tt>null</tt>
* for services which do not support this functionality</b>!
* Return the class tracker for this service. <b>This component is optional
* and is allowed to be <tt>null</tt> for services which do not support this
* functionality.</b>
*/
public abstract IClassTracker getClassTracker();
/**
* Return the audit trail for this service. <b>This component is optional
* and is allowed to be <tt>null</tt> for services which do not support this
* functionality.</b>
*/
public abstract IMixinAuditTrail getAuditTrail();
/**
* Get additional platform agents for this service
*/
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.function.Consumer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;
@@ -40,6 +41,7 @@ import org.spongepowered.asm.service.IClassBytecodeProvider;
import org.spongepowered.asm.service.IMixinService;
import org.spongepowered.asm.service.MixinService;
import org.spongepowered.asm.service.modlauncher.MixinServiceModLauncher;
import org.spongepowered.asm.service.modlauncher.ModLauncherAuditTrail;
import com.google.common.io.Resources;
@@ -59,7 +61,7 @@ public class MixinLaunchPlugin implements ILaunchPluginService, IClassBytecodePr
/**
* Class processing components
*/
private List<IClassProcessor> processors = new ArrayList<IClassProcessor>();
private final List<IClassProcessor> processors = new ArrayList<IClassProcessor>();
/**
* Mixin config names specified on the command line
@@ -70,6 +72,8 @@ public class MixinLaunchPlugin implements ILaunchPluginService, IClassBytecodePr
private MixinServiceModLauncher service;
private ModLauncherAuditTrail auditTrail;
/* (non-Javadoc)
* @see cpw.mods.modlauncher.serviceapi.ILaunchPluginService#name()
*/
@@ -145,6 +149,7 @@ public class MixinLaunchPlugin implements ILaunchPluginService, IClassBytecodePr
throw new IllegalStateException("Unsupported service type for ModLauncher Mixin Service");
}
this.service = (MixinServiceModLauncher)service;
this.auditTrail = (ModLauncherAuditTrail)this.service.getAuditTrail();
synchronized (this.processors) {
this.processors.addAll(this.service.getProcessors());
}
@@ -152,6 +157,17 @@ public class MixinLaunchPlugin implements ILaunchPluginService, IClassBytecodePr
this.service.onInit(this);
}
/* (non-Javadoc)
* @see cpw.mods.modlauncher.serviceapi.ILaunchPluginService
* #customAuditConsumer(java.lang.String, java.util.function.Consumer)
*/
@Override
public void customAuditConsumer(String className, Consumer<String[]> auditDataAcceptor) {
if (this.auditTrail != null) {
this.auditTrail.setConsumer(className, auditDataAcceptor);
}
}
@Override
@Deprecated
public void addResource(Path resource, String name) {
@@ -35,6 +35,7 @@ import org.spongepowered.asm.mixin.transformer.MixinTransformationHandler;
import org.spongepowered.asm.service.IClassBytecodeProvider;
import org.spongepowered.asm.service.IClassProvider;
import org.spongepowered.asm.service.IClassTracker;
import org.spongepowered.asm.service.IMixinAuditTrail;
import org.spongepowered.asm.service.ITransformerProvider;
import org.spongepowered.asm.service.MixinServiceAbstract;
import org.spongepowered.asm.util.IConsumer;
@@ -73,6 +74,11 @@ public class MixinServiceModLauncher extends MixinServiceAbstract {
* Class tracker, tracks class loads and registered invalid classes
*/
private ModLauncherClassTracker classTracker;
/**
* Audit trail adapter
*/
private ModLauncherAuditTrail auditTrail;
/**
* Environment phase consumer, TEMP
@@ -191,6 +197,17 @@ public class MixinServiceModLauncher extends MixinServiceAbstract {
}
return this.classTracker;
}
/* (non-Javadoc)
* @see org.spongepowered.asm.service.IMixinService#getAuditTrail()
*/
@Override
public IMixinAuditTrail getAuditTrail() {
if (this.auditTrail == null) {
this.auditTrail = new ModLauncherAuditTrail();
}
return this.auditTrail;
}
/**
* Get (or create) the transformation handler
@@ -0,0 +1,92 @@
/*
* This file is part of Mixin, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.asm.service.modlauncher;
import java.util.function.Consumer;
import org.spongepowered.asm.service.IMixinAuditTrail;
/**
* Audit trail adapter for ModLauncher
*/
public class ModLauncherAuditTrail implements IMixinAuditTrail {
private static final String APPLY_MIXIN_ACTIVITY = "APP";
private static final String POST_PROCESS_ACTIVITY = "DEC";
private static final String GENERATE_ACTIVITY = "GEN";
/**
* Current audit trail class name
*/
private String currentClass;
/**
* Audit trail consumer
*/
private Consumer<String[]> consumer;
/**
* @param className current class name
* @param consumer audit trail consumer which sinks audit trail actions
*/
public void setConsumer(String className, Consumer<String[]> consumer) {
this.currentClass = className;
this.consumer = consumer;
}
/* (non-Javadoc)
* @see org.spongepowered.asm.service.IMixinAuditTrail#onApply(
* java.lang.String, java.lang.String)
*/
@Override
public void onApply(String className, String mixinName) {
this.writeActivity(className, ModLauncherAuditTrail.APPLY_MIXIN_ACTIVITY, mixinName);
}
/* (non-Javadoc)
* @see org.spongepowered.asm.service.IMixinAuditTrail#onPostProcess(
* java.lang.String)
*/
@Override
public void onPostProcess(String className) {
this.writeActivity(className, ModLauncherAuditTrail.POST_PROCESS_ACTIVITY);
}
/* (non-Javadoc)
* @see org.spongepowered.asm.service.IMixinAuditTrail#onGenerate(
* java.lang.String, java.lang.String)
*/
@Override
public void onGenerate(String className, String generatorName) {
this.writeActivity(className, ModLauncherAuditTrail.GENERATE_ACTIVITY);
}
private void writeActivity(String className, String... activity) {
if (this.consumer != null && className.equals(this.currentClass)) {
this.consumer.accept(activity);
}
}
}