mirror of
https://github.com/zaaarf/lillero-processor.git
synced 2024-11-22 10:24:50 +01:00
chore: added container class for options
This commit is contained in:
parent
15dece7d33
commit
d3ebad7260
8 changed files with 170 additions and 185 deletions
|
@ -1,15 +1,17 @@
|
||||||
package ftbsc.lll.processor;
|
package ftbsc.lll.processor;
|
||||||
|
|
||||||
import com.squareup.javapoet.*;
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.JavaFile;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import ftbsc.lll.IInjector;
|
import ftbsc.lll.IInjector;
|
||||||
import ftbsc.lll.exceptions.AmbiguousDefinitionException;
|
import ftbsc.lll.exceptions.AmbiguousDefinitionException;
|
||||||
import ftbsc.lll.exceptions.InvalidResourceException;
|
|
||||||
import ftbsc.lll.exceptions.OrphanElementException;
|
import ftbsc.lll.exceptions.OrphanElementException;
|
||||||
import ftbsc.lll.processor.annotations.*;
|
import ftbsc.lll.processor.annotations.*;
|
||||||
|
import ftbsc.lll.processor.tools.ProcessorOptions;
|
||||||
import ftbsc.lll.processor.tools.containers.ClassContainer;
|
import ftbsc.lll.processor.tools.containers.ClassContainer;
|
||||||
import ftbsc.lll.processor.tools.containers.InjectorInfo;
|
import ftbsc.lll.processor.tools.containers.InjectorInfo;
|
||||||
import ftbsc.lll.processor.tools.containers.MethodContainer;
|
import ftbsc.lll.processor.tools.containers.MethodContainer;
|
||||||
import ftbsc.lll.processor.tools.obfuscation.ObfuscationMapper;
|
|
||||||
import ftbsc.lll.proxies.ProxyType;
|
import ftbsc.lll.proxies.ProxyType;
|
||||||
import ftbsc.lll.proxies.impl.TypeProxy;
|
import ftbsc.lll.proxies.impl.TypeProxy;
|
||||||
|
|
||||||
|
@ -22,10 +24,8 @@ import javax.tools.Diagnostic;
|
||||||
import javax.tools.FileObject;
|
import javax.tools.FileObject;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.StandardLocation;
|
import javax.tools.StandardLocation;
|
||||||
import java.io.*;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.io.PrintWriter;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -47,79 +47,9 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
private final Set<String> injectors = new HashSet<>();
|
private final Set<String> injectors = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ObfuscationMapper} used to convert classes and variables
|
* An object representing the various options passed to the processor.
|
||||||
* to their obfuscated equivalent. Will be null when no mapper is in use.
|
|
||||||
*/
|
*/
|
||||||
private ObfuscationMapper mapper = null;
|
public final ProcessorOptions options = new ProcessorOptions(processingEnv);
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the processor should issue warnings when compiling code anonymous
|
|
||||||
* classes which can't be checked for validity.
|
|
||||||
*/
|
|
||||||
public static boolean anonymousClassWarning = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether injector metadata (what is returned by the functions of {@link IInjector})
|
|
||||||
* is to use obfuscated names instead of its normal names.
|
|
||||||
*/
|
|
||||||
public static boolean obfuscateInjectorMetadata = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the processor with the processing environment by setting the
|
|
||||||
* {@code processingEnv} field to the value of the {@code processingEnv} argument.
|
|
||||||
* @param processingEnv environment to access facilities the tool framework
|
|
||||||
* provides to the processor
|
|
||||||
* @throws IllegalStateException if this method is called more than once.
|
|
||||||
* @since 0.3.0
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
|
||||||
super.init(processingEnv);
|
|
||||||
String location = processingEnv.getOptions().get("mappingsFile");
|
|
||||||
if(location == null)
|
|
||||||
mapper = null;
|
|
||||||
else {
|
|
||||||
InputStream targetStream;
|
|
||||||
try {
|
|
||||||
URI target = new URI(location);
|
|
||||||
targetStream = target.toURL().openStream();
|
|
||||||
} catch(URISyntaxException | IOException e) {
|
|
||||||
//may be a local file path
|
|
||||||
File f = new File(location);
|
|
||||||
if(!f.exists())
|
|
||||||
throw new InvalidResourceException(location);
|
|
||||||
try {
|
|
||||||
targetStream = new FileInputStream(f);
|
|
||||||
} catch(FileNotFoundException ex) {
|
|
||||||
throw new InvalidResourceException(location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//assuming its tsrg file
|
|
||||||
//todo: replace crappy homebaked parser with actual library
|
|
||||||
this.mapper = new ObfuscationMapper(new BufferedReader(new InputStreamReader(targetStream,
|
|
||||||
StandardCharsets.UTF_8)).lines());
|
|
||||||
}
|
|
||||||
String anonymousClassWarn = processingEnv.getOptions().get("anonymousClassWarning");
|
|
||||||
if(anonymousClassWarn != null)
|
|
||||||
anonymousClassWarning = parseBooleanArg(anonymousClassWarn);
|
|
||||||
String obfuscateInj = processingEnv.getOptions().get("obfuscateInjectorMetadata");
|
|
||||||
if(obfuscateInj != null)
|
|
||||||
obfuscateInjectorMetadata = parseBooleanArg(obfuscateInj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a boolean arg from a String.
|
|
||||||
* @param arg the arg to parse
|
|
||||||
* @return the parsed boolean
|
|
||||||
*/
|
|
||||||
private static boolean parseBooleanArg(String arg) {
|
|
||||||
try { // 0 = false, any other integer = true
|
|
||||||
int i = Integer.parseInt(arg);
|
|
||||||
return i != 0;
|
|
||||||
} catch(NumberFormatException ignored) {
|
|
||||||
return Boolean.parseBoolean(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Where the actual processing happens.
|
* Where the actual processing happens.
|
||||||
|
@ -196,11 +126,7 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
//find class information
|
//find class information
|
||||||
Patch patchAnn = cl.getAnnotation(Patch.class);
|
Patch patchAnn = cl.getAnnotation(Patch.class);
|
||||||
ClassContainer targetClass = ClassContainer.from(
|
ClassContainer targetClass = ClassContainer.from(
|
||||||
patchAnn,
|
patchAnn, Patch::value, patchAnn.innerName(), this.options
|
||||||
Patch::value,
|
|
||||||
patchAnn.innerName(),
|
|
||||||
this.processingEnv,
|
|
||||||
this.mapper
|
|
||||||
);
|
);
|
||||||
//find package information
|
//find package information
|
||||||
Element packageElement = cl.getEnclosingElement();
|
Element packageElement = cl.getEnclosingElement();
|
||||||
|
@ -231,11 +157,10 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
if(type == ProxyType.TYPE) {
|
if(type == ProxyType.TYPE) {
|
||||||
//find and validate
|
//find and validate
|
||||||
ClassContainer clazz = ClassContainer.findOrFallback(
|
ClassContainer clazz = ClassContainer.findOrFallback(
|
||||||
ClassContainer.from(cl, this.processingEnv, this.mapper),
|
ClassContainer.from(cl, this.options),
|
||||||
patchAnn,
|
patchAnn,
|
||||||
proxyVar.getAnnotation(Find.class),
|
proxyVar.getAnnotation(Find.class),
|
||||||
this.processingEnv,
|
this.options
|
||||||
this.mapper
|
|
||||||
);
|
);
|
||||||
//types can be generated with a single instruction
|
//types can be generated with a single instruction
|
||||||
constructorBuilder.addStatement(
|
constructorBuilder.addStatement(
|
||||||
|
@ -251,8 +176,7 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
constructorBuilder,
|
constructorBuilder,
|
||||||
this.processingEnv,
|
this.options
|
||||||
this.mapper
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +235,7 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
matchedInjectors.add(injector);
|
matchedInjectors.add(injector);
|
||||||
toGenerate.put(
|
toGenerate.put(
|
||||||
String.format("%sInjector%d", cl.getSimpleName(), iterationNumber),
|
String.format("%sInjector%d", cl.getSimpleName(), iterationNumber),
|
||||||
new InjectorInfo(injector, tg, targetAnn, this.processingEnv, this.mapper)
|
new InjectorInfo(injector, tg, targetAnn, this.options)
|
||||||
);
|
);
|
||||||
iterationNumber++; //increment is only used by injectors
|
iterationNumber++; //increment is only used by injectors
|
||||||
} else {
|
} else {
|
||||||
|
@ -323,8 +247,7 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
tg,
|
tg,
|
||||||
targetAnn,
|
targetAnn,
|
||||||
constructorBuilder,
|
constructorBuilder,
|
||||||
this.processingEnv,
|
this.options
|
||||||
this.mapper
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,9 +272,9 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
.addMethod(constructorBuilder.build())
|
.addMethod(constructorBuilder.build())
|
||||||
.addMethod(buildStringReturnMethod("name", injName))
|
.addMethod(buildStringReturnMethod("name", injName))
|
||||||
.addMethod(buildStringReturnMethod("reason", toGenerate.get(injName).reason))
|
.addMethod(buildStringReturnMethod("reason", toGenerate.get(injName).reason))
|
||||||
.addMethod(buildStringReturnMethod("targetClass", obfuscateInjectorMetadata ? targetClass.fqnObf : targetClass.fqn))
|
.addMethod(buildStringReturnMethod("targetClass", this.options.obfuscateInjectorMetadata ? targetClass.fqnObf : targetClass.fqn))
|
||||||
.addMethod(buildStringReturnMethod("methodName", obfuscateInjectorMetadata ? target.nameObf : target.name))
|
.addMethod(buildStringReturnMethod("methodName", this.options.obfuscateInjectorMetadata ? target.nameObf : target.name))
|
||||||
.addMethod(buildStringReturnMethod("methodDesc", obfuscateInjectorMetadata ? target.descriptorObf : target.descriptor))
|
.addMethod(buildStringReturnMethod("methodDesc", this.options.obfuscateInjectorMetadata ? target.descriptorObf : target.descriptor))
|
||||||
.addMethods(generateDummies(cl))
|
.addMethods(generateDummies(cl))
|
||||||
.addMethod(generateInjector(toGenerate.get(injName), this.processingEnv))
|
.addMethod(generateInjector(toGenerate.get(injName), this.processingEnv))
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -212,13 +212,13 @@ public class ASTUtils {
|
||||||
/**
|
/**
|
||||||
* Finds the class name and maps it to the correct format.
|
* Finds the class name and maps it to the correct format.
|
||||||
* @param name the fully qualified name of the class to convert
|
* @param name the fully qualified name of the class to convert
|
||||||
* @param mapper the {@link ObfuscationMapper} to use, may be null
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @return the fully qualified class name
|
* @return the fully qualified class name
|
||||||
* @since 0.3.0
|
* @since 0.3.0
|
||||||
*/
|
*/
|
||||||
public static String findClassName(String name, ObfuscationMapper mapper) {
|
public static String findClassName(String name, ProcessorOptions options) {
|
||||||
try {
|
try {
|
||||||
return mapper == null ? name : mapper.obfuscateClass(name).replace('/', '.');
|
return options.mapper == null ? name : options.mapper.obfuscateClass(name).replace('/', '.');
|
||||||
} catch(MappingNotFoundException e) {
|
} catch(MappingNotFoundException e) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import ftbsc.lll.processor.tools.containers.ClassContainer;
|
||||||
import ftbsc.lll.processor.tools.containers.FieldContainer;
|
import ftbsc.lll.processor.tools.containers.FieldContainer;
|
||||||
import ftbsc.lll.processor.tools.containers.InjectorInfo;
|
import ftbsc.lll.processor.tools.containers.InjectorInfo;
|
||||||
import ftbsc.lll.processor.tools.containers.MethodContainer;
|
import ftbsc.lll.processor.tools.containers.MethodContainer;
|
||||||
import ftbsc.lll.processor.tools.obfuscation.ObfuscationMapper;
|
|
||||||
import ftbsc.lll.proxies.ProxyType;
|
import ftbsc.lll.proxies.ProxyType;
|
||||||
import ftbsc.lll.proxies.impl.FieldProxy;
|
import ftbsc.lll.proxies.impl.FieldProxy;
|
||||||
import ftbsc.lll.proxies.impl.MethodProxy;
|
import ftbsc.lll.proxies.impl.MethodProxy;
|
||||||
|
@ -44,13 +43,12 @@ public class JavaPoetUtils {
|
||||||
* @param stub the stub {@link ExecutableElement} if present or relevant, null otherwise
|
* @param stub the stub {@link ExecutableElement} if present or relevant, null otherwise
|
||||||
* @param t the {@link Target} relevant to this finder if present or relevant, null otherwise
|
* @param t the {@link Target} relevant to this finder if present or relevant, null otherwise
|
||||||
* @param con the {@link MethodSpec.Builder} to append to
|
* @param con the {@link MethodSpec.Builder} to append to
|
||||||
* @param env the {@link ProcessingEnvironment} to perform the operation in
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to use, may be null
|
|
||||||
* @since 0.5.0
|
* @since 0.5.0
|
||||||
*/
|
*/
|
||||||
public static void appendMemberFinderDefinition(
|
public static void appendMemberFinderDefinition(
|
||||||
VariableElement var, ExecutableElement stub, Target t,
|
VariableElement var, ExecutableElement stub, Target t,
|
||||||
MethodSpec.Builder con, ProcessingEnvironment env, ObfuscationMapper mapper) {
|
MethodSpec.Builder con, ProcessorOptions options) {
|
||||||
ProxyType type = getProxyType(var);
|
ProxyType type = getProxyType(var);
|
||||||
if(type != ProxyType.METHOD && type != ProxyType.FIELD)
|
if(type != ProxyType.METHOD && type != ProxyType.FIELD)
|
||||||
return; //this method is irrelevant to everyone else
|
return; //this method is irrelevant to everyone else
|
||||||
|
@ -65,13 +63,13 @@ public class JavaPoetUtils {
|
||||||
Element target;
|
Element target;
|
||||||
|
|
||||||
if(isMethod) {
|
if(isMethod) {
|
||||||
MethodContainer mc = MethodContainer.from(stub, t, f, env, mapper);
|
MethodContainer mc = MethodContainer.from(stub, t, f, options);
|
||||||
descriptorObf = mc.descriptorObf;
|
descriptorObf = mc.descriptorObf;
|
||||||
nameObf = mc.nameObf;
|
nameObf = mc.nameObf;
|
||||||
parent = mc.parent;
|
parent = mc.parent;
|
||||||
target = mc.elem;
|
target = mc.elem;
|
||||||
} else {
|
} else {
|
||||||
FieldContainer fc = FieldContainer.from(var, env, mapper);
|
FieldContainer fc = FieldContainer.from(var, options);
|
||||||
descriptorObf = fc.descriptorObf;
|
descriptorObf = fc.descriptorObf;
|
||||||
nameObf = fc.nameObf;
|
nameObf = fc.nameObf;
|
||||||
parent = fc.parent;
|
parent = fc.parent;
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
package ftbsc.lll.processor.tools;
|
||||||
|
|
||||||
|
import ftbsc.lll.IInjector;
|
||||||
|
import ftbsc.lll.exceptions.InvalidResourceException;
|
||||||
|
import ftbsc.lll.processor.tools.obfuscation.ObfuscationMapper;
|
||||||
|
|
||||||
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class in charge of containing, parsing and processing all processor options,
|
||||||
|
* from the simpler booleans to the more complicated mapper.
|
||||||
|
*/
|
||||||
|
public class ProcessorOptions {
|
||||||
|
/**
|
||||||
|
* The environment the processor is acting in.
|
||||||
|
*/
|
||||||
|
public final ProcessingEnvironment env;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ObfuscationMapper} used to convert classes and variables
|
||||||
|
* to their obfuscated equivalent. Will be null when no mapper is in use.
|
||||||
|
*/
|
||||||
|
public final ObfuscationMapper mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the processor should issue warnings when compiling code anonymous
|
||||||
|
* classes which can't be checked for validity.
|
||||||
|
*/
|
||||||
|
public final boolean anonymousClassWarning;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether injector metadata (what is returned by the functions of {@link IInjector})
|
||||||
|
* is to use obfuscated names instead of its normal names.
|
||||||
|
*/
|
||||||
|
public final boolean obfuscateInjectorMetadata;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public constructor, parses and stores all given arguments.
|
||||||
|
* @param env the environment the processor is working in
|
||||||
|
*/
|
||||||
|
public ProcessorOptions(ProcessingEnvironment env) {
|
||||||
|
this.env = env;
|
||||||
|
String location = env.getOptions().get("mappingsFile");
|
||||||
|
if(location == null)
|
||||||
|
this.mapper = null;
|
||||||
|
else {
|
||||||
|
InputStream targetStream;
|
||||||
|
try {
|
||||||
|
URI target = new URI(location);
|
||||||
|
targetStream = target.toURL().openStream();
|
||||||
|
} catch(URISyntaxException | IOException e) {
|
||||||
|
//may be a local file path
|
||||||
|
File f = new File(location);
|
||||||
|
if(!f.exists())
|
||||||
|
throw new InvalidResourceException(location);
|
||||||
|
try {
|
||||||
|
targetStream = new FileInputStream(f);
|
||||||
|
} catch(FileNotFoundException ex) {
|
||||||
|
throw new InvalidResourceException(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//assuming its tsrg file
|
||||||
|
//todo: replace crappy homebaked parser with actual library
|
||||||
|
this.mapper = new ObfuscationMapper(new BufferedReader(new InputStreamReader(targetStream,
|
||||||
|
StandardCharsets.UTF_8)).lines());
|
||||||
|
}
|
||||||
|
this.anonymousClassWarning = parseBooleanArg(env.getOptions().get("anonymousClassWarning"), true);
|
||||||
|
this.obfuscateInjectorMetadata = parseBooleanArg(env.getOptions().get("obfuscateInjectorMetadata"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a boolean arg from a String.
|
||||||
|
* @param arg the arg to parse
|
||||||
|
* @return the parsed boolean
|
||||||
|
*/
|
||||||
|
private static boolean parseBooleanArg(String arg, boolean defaultValue) {
|
||||||
|
if(arg == null) return defaultValue;
|
||||||
|
try { // 0 = false, any other integer = true
|
||||||
|
int i = Integer.parseInt(arg);
|
||||||
|
return i != 0;
|
||||||
|
} catch(NumberFormatException ignored) {
|
||||||
|
return Boolean.parseBoolean(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,10 @@
|
||||||
package ftbsc.lll.processor.tools.containers;
|
package ftbsc.lll.processor.tools.containers;
|
||||||
|
|
||||||
import ftbsc.lll.exceptions.TargetNotFoundException;
|
import ftbsc.lll.exceptions.TargetNotFoundException;
|
||||||
import ftbsc.lll.processor.LilleroProcessor;
|
|
||||||
import ftbsc.lll.processor.annotations.Find;
|
import ftbsc.lll.processor.annotations.Find;
|
||||||
import ftbsc.lll.processor.annotations.Patch;
|
import ftbsc.lll.processor.annotations.Patch;
|
||||||
import ftbsc.lll.processor.tools.obfuscation.ObfuscationMapper;
|
import ftbsc.lll.processor.tools.ProcessorOptions;
|
||||||
|
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
|
||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
@ -40,21 +38,20 @@ public class ClassContainer {
|
||||||
public final Element elem;
|
public final Element elem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor, called from {@link #from(Annotation, Function, String, ProcessingEnvironment, ObfuscationMapper)}.
|
* Private constructor, called from {@link #from(Annotation, Function, String, ProcessorOptions)}.
|
||||||
* @param fqn the fully-qualified name of the target class
|
* @param fqn the fully-qualified name of the target class
|
||||||
* @param innerNames an array of Strings containing the path to the inner class, may be null
|
* @param innerNames an array of Strings containing the path to the inner class, may be null
|
||||||
* @param env the {@link ProcessingEnvironment} to be used to locate the class
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to be used, may be null
|
|
||||||
*/
|
*/
|
||||||
private ClassContainer(String fqn, String[] innerNames, ProcessingEnvironment env, ObfuscationMapper mapper) {
|
private ClassContainer(String fqn, String[] innerNames, ProcessorOptions options) {
|
||||||
//find and validate
|
//find and validate
|
||||||
Element elem = env.getElementUtils().getTypeElement(fqn);
|
Element elem = options.env.getElementUtils().getTypeElement(fqn);
|
||||||
|
|
||||||
if(elem == null)
|
if(elem == null)
|
||||||
throw new TargetNotFoundException("class", fqn);
|
throw new TargetNotFoundException("class", fqn);
|
||||||
|
|
||||||
StringBuilder fqnBuilder = new StringBuilder(
|
StringBuilder fqnBuilder = new StringBuilder(
|
||||||
internalNameFromType(elem.asType(), env).replace('/', '.')
|
internalNameFromType(elem.asType(), options.env).replace('/', '.')
|
||||||
);
|
);
|
||||||
|
|
||||||
if(innerNames != null) {
|
if(innerNames != null) {
|
||||||
|
@ -64,8 +61,8 @@ public class ClassContainer {
|
||||||
try {
|
try {
|
||||||
int anonClassCounter = Integer.parseInt(inner);
|
int anonClassCounter = Integer.parseInt(inner);
|
||||||
//anonymous classes cannot be validated!
|
//anonymous classes cannot be validated!
|
||||||
if(LilleroProcessor.anonymousClassWarning)
|
if(options.anonymousClassWarning)
|
||||||
env.getMessager().printMessage(
|
options.env.getMessager().printMessage(
|
||||||
Diagnostic.Kind.WARNING,
|
Diagnostic.Kind.WARNING,
|
||||||
String.format(
|
String.format(
|
||||||
"Anonymous classes cannot be verified by the processor. The existence of %s$%s is not guaranteed!",
|
"Anonymous classes cannot be verified by the processor. The existence of %s$%s is not guaranteed!",
|
||||||
|
@ -88,7 +85,7 @@ public class ClassContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.fqn = fqnBuilder.toString();
|
this.fqn = fqnBuilder.toString();
|
||||||
this.fqnObf = findClassName(this.fqn, mapper);
|
this.fqnObf = findClassName(this.fqn, options);
|
||||||
this.elem = elem;
|
this.elem = elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,33 +94,28 @@ public class ClassContainer {
|
||||||
* @param ann the annotation containing the class
|
* @param ann the annotation containing the class
|
||||||
* @param classFunction the annotation function returning the class
|
* @param classFunction the annotation function returning the class
|
||||||
* @param innerName a string containing the inner class name or nothing
|
* @param innerName a string containing the inner class name or nothing
|
||||||
* @param env the {@link ProcessingEnvironment} to be used to locate the class
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to be used, may be null
|
|
||||||
* @param <T> the type of the annotation carrying the information
|
* @param <T> the type of the annotation carrying the information
|
||||||
* @return the fully qualified name of the given class
|
* @return the fully qualified name of the given class
|
||||||
* @since 0.5.0
|
* @since 0.5.0
|
||||||
*/
|
*/
|
||||||
public static <T extends Annotation> ClassContainer from(T ann, Function<T, Class<?>> classFunction, String innerName,
|
public static <T extends Annotation> ClassContainer from(T ann, Function<T, Class<?>> classFunction, String innerName, ProcessorOptions options) {
|
||||||
ProcessingEnvironment env, ObfuscationMapper mapper) {
|
|
||||||
String fqn;
|
String fqn;
|
||||||
String[] inner;
|
String[] inner;
|
||||||
fqn = getTypeFromAnnotation(ann, classFunction, env).toString();
|
fqn = getTypeFromAnnotation(ann, classFunction, options.env).toString();
|
||||||
inner = innerName.equals("") ? null : innerName.split("//$");
|
inner = innerName.equals("") ? null : innerName.split("//$");
|
||||||
return new ClassContainer(fqn, inner, env, mapper);
|
return new ClassContainer(fqn, inner, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely extracts a {@link Class} from an annotation and gets its fully qualified name.
|
* Safely extracts a {@link Class} from an annotation and gets its fully qualified name.
|
||||||
* @param cl the {@link TypeElement} representing the class
|
* @param cl the {@link TypeElement} representing the class
|
||||||
* @param env the {@link ProcessingEnvironment} to be used to locate the class
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to be used, may be null
|
|
||||||
* @param <T> the type of the annotation carrying the information
|
|
||||||
* @return the fully qualified name of the given class
|
* @return the fully qualified name of the given class
|
||||||
* @since 0.6.0
|
* @since 0.6.0
|
||||||
*/
|
*/
|
||||||
public static <T extends Annotation> ClassContainer from(
|
public static ClassContainer from(TypeElement cl, ProcessorOptions options) {
|
||||||
TypeElement cl, ProcessingEnvironment env, ObfuscationMapper mapper) {
|
return new ClassContainer(cl.getQualifiedName().toString(), null, options);
|
||||||
return new ClassContainer(cl.getQualifiedName().toString(), null, env, mapper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,16 +124,13 @@ public class ClassContainer {
|
||||||
* @param fallback the {@link ClassContainer} it falls back on
|
* @param fallback the {@link ClassContainer} it falls back on
|
||||||
* @param p the {@link Patch} annotation to get info from
|
* @param p the {@link Patch} annotation to get info from
|
||||||
* @param f the {@link Find} annotation to get info from
|
* @param f the {@link Find} annotation to get info from
|
||||||
* @param env the {@link ProcessingEnvironment} to perform the operation in
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to use, may be null
|
|
||||||
* @return the built {@link ClassContainer} or the fallback if not enough information was present
|
* @return the built {@link ClassContainer} or the fallback if not enough information was present
|
||||||
* @since 0.5.0
|
* @since 0.5.0
|
||||||
*/
|
*/
|
||||||
public static ClassContainer findOrFallback(ClassContainer fallback, Patch p, Find f, ProcessingEnvironment env, ObfuscationMapper mapper) {
|
public static ClassContainer findOrFallback(ClassContainer fallback, Patch p, Find f, ProcessorOptions options) {
|
||||||
if(f == null) return ClassContainer.from(p, Patch::value, p.innerName(), env, mapper);
|
if(f == null) return ClassContainer.from(p, Patch::value, p.innerName(), options);
|
||||||
ClassContainer cl = ClassContainer.from(f, Find::value, f.innerName(), env, mapper);
|
ClassContainer cl = ClassContainer.from(f, Find::value, f.innerName(), options);
|
||||||
return cl.fqn.equals("java.lang.Object")
|
return cl.fqn.equals("java.lang.Object") ? fallback : cl;
|
||||||
? fallback
|
|
||||||
: cl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,15 @@ package ftbsc.lll.processor.tools.containers;
|
||||||
import ftbsc.lll.exceptions.AmbiguousDefinitionException;
|
import ftbsc.lll.exceptions.AmbiguousDefinitionException;
|
||||||
import ftbsc.lll.processor.annotations.Find;
|
import ftbsc.lll.processor.annotations.Find;
|
||||||
import ftbsc.lll.processor.annotations.Patch;
|
import ftbsc.lll.processor.annotations.Patch;
|
||||||
import ftbsc.lll.processor.tools.obfuscation.ObfuscationMapper;
|
import ftbsc.lll.processor.tools.ProcessorOptions;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.element.VariableElement;
|
import javax.lang.model.element.VariableElement;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
|
||||||
import static ftbsc.lll.processor.tools.ASTUtils.*;
|
import static ftbsc.lll.processor.tools.ASTUtils.*;
|
||||||
import static ftbsc.lll.processor.tools.ASTUtils.descriptorFromType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for information about a field.
|
* Container for information about a field.
|
||||||
|
@ -56,16 +54,13 @@ public class FieldContainer {
|
||||||
public final VariableElement elem;
|
public final VariableElement elem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor, called from {@link #from(VariableElement, ProcessingEnvironment, ObfuscationMapper)}.
|
* Private constructor, called from {@link #from(VariableElement, ProcessorOptions)}.
|
||||||
* @param parent the {@link ClassContainer} representing the parent
|
* @param parent the {@link ClassContainer} representing the parent
|
||||||
* @param name the fully-qualified name of the target field
|
* @param name the fully-qualified name of the target field
|
||||||
* @param descriptor the descriptor of the target field, may be null for verifiable fields
|
* @param descriptor the descriptor of the target field, may be null for verifiable fields
|
||||||
* @param env the {@link ProcessingEnvironment} to perform the operation in
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to be used, may be null
|
|
||||||
*/
|
*/
|
||||||
private FieldContainer(
|
private FieldContainer(ClassContainer parent, String name, String descriptor, ProcessorOptions options) {
|
||||||
ClassContainer parent, String name, String descriptor,
|
|
||||||
ProcessingEnvironment env, ObfuscationMapper mapper) {
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
if(parent.elem == null) { //unverified
|
if(parent.elem == null) { //unverified
|
||||||
if(descriptor == null)
|
if(descriptor == null)
|
||||||
|
@ -74,47 +69,45 @@ public class FieldContainer {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
} else {
|
} else {
|
||||||
this.elem = (VariableElement) findMember(parent, name, descriptor, descriptor != null, true, env);
|
this.elem = (VariableElement) findMember(parent, name, descriptor, descriptor != null, true, options.env);
|
||||||
this.name = this.elem.getSimpleName().toString();
|
this.name = this.elem.getSimpleName().toString();
|
||||||
this.descriptor = descriptorFromType(this.elem.asType(), env);
|
this.descriptor = descriptorFromType(this.elem.asType(), options.env);
|
||||||
}
|
}
|
||||||
this.descriptorObf = mapper == null ? this.descriptor : mapper.obfuscateType(Type.getType(this.descriptor)).getDescriptor();
|
this.descriptorObf = options.mapper == null ? this.descriptor : options.mapper.obfuscateType(Type.getType(this.descriptor)).getDescriptor();
|
||||||
this.nameObf = findMemberName(parent.fqn, this.name, null, mapper);
|
this.nameObf = findMemberName(parent.fqn, this.name, null, options.mapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a {@link FieldContainer} from a finder.
|
* Finds a {@link FieldContainer} from a finder.
|
||||||
* @param finder the {@link VariableElement} annotated with {@link Find} for this field
|
* @param finder the {@link VariableElement} annotated with {@link Find} for this field
|
||||||
* @param env the {@link ProcessingEnvironment} to perform the operation in
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to be used, may be null
|
|
||||||
* @return the built {@link FieldContainer}
|
* @return the built {@link FieldContainer}
|
||||||
* @since 0.5.0
|
* @since 0.5.0
|
||||||
*/
|
*/
|
||||||
public static FieldContainer from(VariableElement finder, ProcessingEnvironment env, ObfuscationMapper mapper) {
|
public static FieldContainer from(VariableElement finder, ProcessorOptions options) {
|
||||||
//the parent always has a @Patch annotation
|
//the parent always has a @Patch annotation
|
||||||
Patch patchAnn = finder.getEnclosingElement().getAnnotation(Patch.class);
|
Patch patchAnn = finder.getEnclosingElement().getAnnotation(Patch.class);
|
||||||
//the finder always has a @Find annotation
|
//the finder always has a @Find annotation
|
||||||
Find f = finder.getAnnotation(Find.class);
|
Find f = finder.getAnnotation(Find.class);
|
||||||
|
|
||||||
ClassContainer parent = ClassContainer.findOrFallback(
|
ClassContainer parent = ClassContainer.findOrFallback(
|
||||||
ClassContainer.from((TypeElement) finder.getEnclosingElement(), env, mapper),
|
ClassContainer.from((TypeElement) finder.getEnclosingElement(), options), patchAnn, f, options
|
||||||
patchAnn, f, env, mapper
|
|
||||||
);
|
);
|
||||||
|
|
||||||
String name = f.name().equals("") ? finder.getSimpleName().toString() : f.name();
|
String name = f.name().equals("") ? finder.getSimpleName().toString() : f.name();
|
||||||
String descriptor;
|
String descriptor;
|
||||||
TypeMirror fieldType = getTypeFromAnnotation(f, Find::type, env);
|
TypeMirror fieldType = getTypeFromAnnotation(f, Find::type, options.env);
|
||||||
if(fieldType.toString().equals("java.lang.Object")) {
|
if(fieldType.toString().equals("java.lang.Object")) {
|
||||||
descriptor = null;
|
descriptor = null;
|
||||||
} else {
|
} else {
|
||||||
if(fieldType.getKind() != TypeKind.VOID && !fieldType.getKind().isPrimitive())
|
if(fieldType.getKind() != TypeKind.VOID && !fieldType.getKind().isPrimitive())
|
||||||
descriptor = //jank af but this is temporary anyway
|
descriptor = //jank af but this is temporary anyway
|
||||||
"L" + ClassContainer.from(
|
"L" + ClassContainer.from(
|
||||||
f, Find::type, f.typeInner(), env, mapper
|
f, Find::type, f.typeInner(), options
|
||||||
).fqnObf.replace('.', '/') + ";";
|
).fqnObf.replace('.', '/') + ";";
|
||||||
else descriptor = descriptorFromType(fieldType, env);
|
else descriptor = descriptorFromType(fieldType, options.env);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FieldContainer(parent, name, descriptor, env, mapper);
|
return new FieldContainer(parent, name, descriptor, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,8 @@ package ftbsc.lll.processor.tools.containers;
|
||||||
|
|
||||||
import ftbsc.lll.processor.annotations.Injector;
|
import ftbsc.lll.processor.annotations.Injector;
|
||||||
import ftbsc.lll.processor.annotations.Target;
|
import ftbsc.lll.processor.annotations.Target;
|
||||||
import ftbsc.lll.processor.tools.obfuscation.ObfuscationMapper;
|
import ftbsc.lll.processor.tools.ProcessorOptions;
|
||||||
|
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,13 +35,12 @@ public class InjectorInfo {
|
||||||
* @param injector the injector {@link ExecutableElement}
|
* @param injector the injector {@link ExecutableElement}
|
||||||
* @param targetStub the target {@link ExecutableElement}
|
* @param targetStub the target {@link ExecutableElement}
|
||||||
* @param targetAnn the relevant {@link Target} annotation
|
* @param targetAnn the relevant {@link Target} annotation
|
||||||
* @param env the {@link ProcessingEnvironment} to be used to locate the class
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to be used, may be null
|
|
||||||
*/
|
*/
|
||||||
public InjectorInfo(ExecutableElement injector, ExecutableElement targetStub, Target targetAnn, ProcessingEnvironment env, ObfuscationMapper mapper) {
|
public InjectorInfo(ExecutableElement injector, ExecutableElement targetStub, Target targetAnn, ProcessorOptions options) {
|
||||||
this.injector = injector;
|
this.injector = injector;
|
||||||
this.targetStub = targetStub;
|
this.targetStub = targetStub;
|
||||||
this.reason = injector.getAnnotation(Injector.class).reason();
|
this.reason = injector.getAnnotation(Injector.class).reason();
|
||||||
this.target = MethodContainer.from(targetStub, targetAnn, null, env, mapper);
|
this.target = MethodContainer.from(targetStub, targetAnn, null, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,9 +5,8 @@ import ftbsc.lll.exceptions.TargetNotFoundException;
|
||||||
import ftbsc.lll.processor.annotations.Find;
|
import ftbsc.lll.processor.annotations.Find;
|
||||||
import ftbsc.lll.processor.annotations.Patch;
|
import ftbsc.lll.processor.annotations.Patch;
|
||||||
import ftbsc.lll.processor.annotations.Target;
|
import ftbsc.lll.processor.annotations.Target;
|
||||||
import ftbsc.lll.processor.tools.obfuscation.ObfuscationMapper;
|
import ftbsc.lll.processor.tools.ProcessorOptions;
|
||||||
|
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
@ -55,18 +54,15 @@ public class MethodContainer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor, called from
|
* Private constructor, called from
|
||||||
* {@link #from(ExecutableElement, Target, Find, ProcessingEnvironment, ObfuscationMapper)}.
|
* {@link #from(ExecutableElement, Target, Find, ProcessorOptions)}.
|
||||||
* @param parent the {@link ClassContainer} representing the parent
|
* @param parent the {@link ClassContainer} representing the parent
|
||||||
* @param name the fully-qualified name of the target method
|
* @param name the fully-qualified name of the target method
|
||||||
* @param descriptor the descriptor of the target method
|
* @param descriptor the descriptor of the target method
|
||||||
* @param strict whether the matching should be strict (see {@link Target#strict()} for more info)
|
* @param strict whether the matching should be strict (see {@link Target#strict()} for more info)
|
||||||
* @param bridge whether the "bridge" should be matched isntead (see {@link Target#bridge()} for more info)
|
* @param bridge whether the "bridge" should be matched instead (see {@link Target#bridge()} for more info)
|
||||||
* @param env the {@link ProcessingEnvironment} to perform the operation in
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to be used, may be null
|
|
||||||
*/
|
*/
|
||||||
private MethodContainer(
|
private MethodContainer(ClassContainer parent, String name, String descriptor, boolean strict, boolean bridge, ProcessorOptions options) {
|
||||||
ClassContainer parent, String name, String descriptor, boolean strict,
|
|
||||||
boolean bridge, ProcessingEnvironment env, ObfuscationMapper mapper) {
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
if(parent.elem == null) { //unverified
|
if(parent.elem == null) { //unverified
|
||||||
if(descriptor == null)
|
if(descriptor == null)
|
||||||
|
@ -76,14 +72,14 @@ public class MethodContainer {
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
} else {
|
} else {
|
||||||
ExecutableElement tmp = (ExecutableElement) findMember(
|
ExecutableElement tmp = (ExecutableElement) findMember(
|
||||||
parent, name, descriptor, descriptor != null && strict,false, env
|
parent, name, descriptor, descriptor != null && strict,false, options.env
|
||||||
);
|
);
|
||||||
this.elem = bridge ? findSyntheticBridge((TypeElement) this.parent.elem, tmp, env) : tmp;
|
this.elem = bridge ? findSyntheticBridge((TypeElement) this.parent.elem, tmp, options.env) : tmp;
|
||||||
this.name = this.elem.getSimpleName().toString();
|
this.name = this.elem.getSimpleName().toString();
|
||||||
this.descriptor = descriptorFromExecutableElement(this.elem, env);
|
this.descriptor = descriptorFromExecutableElement(this.elem, options.env);
|
||||||
}
|
}
|
||||||
this.descriptorObf = mapper == null ? this.descriptor : mapper.obfuscateMethodDescriptor(this.descriptor);
|
this.descriptorObf = options.mapper == null ? this.descriptor : options.mapper.obfuscateMethodDescriptor(this.descriptor);
|
||||||
this.nameObf = findMemberName(parent.fqn, this.name, this.descriptor, mapper);
|
this.nameObf = findMemberName(parent.fqn, this.name, this.descriptor, options.mapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,27 +87,25 @@ public class MethodContainer {
|
||||||
* @param stub the {@link ExecutableElement} for the stub
|
* @param stub the {@link ExecutableElement} for the stub
|
||||||
* @param t the {@link Target} annotation relevant to this case
|
* @param t the {@link Target} annotation relevant to this case
|
||||||
* @param f the {@link Find} annotation containing fallback data, may be null
|
* @param f the {@link Find} annotation containing fallback data, may be null
|
||||||
* @param env the {@link ProcessingEnvironment} to perform the operation in
|
* @param options the {@link ProcessorOptions} to be used
|
||||||
* @param mapper the {@link ObfuscationMapper} to be used, may be null
|
|
||||||
* @return the {@link MethodContainer} corresponding to the method
|
* @return the {@link MethodContainer} corresponding to the method
|
||||||
* @throws AmbiguousDefinitionException if it finds more than one candidate
|
* @throws AmbiguousDefinitionException if it finds more than one candidate
|
||||||
* @throws TargetNotFoundException if it finds no valid candidate
|
* @throws TargetNotFoundException if it finds no valid candidate
|
||||||
* @since 0.3.0
|
* @since 0.3.0
|
||||||
*/
|
*/
|
||||||
public static MethodContainer from(ExecutableElement stub, Target t, Find f, ProcessingEnvironment env, ObfuscationMapper mapper) {
|
public static MethodContainer from(ExecutableElement stub, Target t, Find f, ProcessorOptions options) {
|
||||||
//the parent always has a @Patch annotation
|
//the parent always has a @Patch annotation
|
||||||
Patch patchAnn = stub.getEnclosingElement().getAnnotation(Patch.class);
|
Patch patchAnn = stub.getEnclosingElement().getAnnotation(Patch.class);
|
||||||
ClassContainer parent = ClassContainer.findOrFallback(
|
ClassContainer parent = ClassContainer.findOrFallback(
|
||||||
ClassContainer.from((TypeElement) stub.getEnclosingElement(), env, mapper),
|
ClassContainer.from((TypeElement) stub.getEnclosingElement(), options), patchAnn, f, options
|
||||||
patchAnn, f, env, mapper
|
|
||||||
);
|
);
|
||||||
String name = !t.methodName().equals("")
|
String name = !t.methodName().equals("")
|
||||||
? t.methodName() //name was specified in target
|
? t.methodName() //name was specified in target
|
||||||
: stub.getSimpleName().toString();
|
: stub.getSimpleName().toString();
|
||||||
String descriptor = t.strict()
|
String descriptor = t.strict()
|
||||||
? descriptorFromExecutableElement(stub, env)
|
? descriptorFromExecutableElement(stub, options.env)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return new MethodContainer(parent, name, descriptor, t.strict(), t.bridge(), env, mapper);
|
return new MethodContainer(parent, name, descriptor, t.strict(), t.bridge(), options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue