mirror of
https://github.com/zaaarf/lillero-processor.git
synced 2024-11-22 10:54:50 +01:00
chore: implemented matching by name for finders, added OrphanExceptions to prevent ungraceful crashes in generated code
This commit is contained in:
parent
c688b55fc3
commit
d2fe55db7a
7 changed files with 55 additions and 22 deletions
|
@ -1,17 +1,16 @@
|
||||||
package ftbsc.lll.exceptions;
|
package ftbsc.lll.exceptions;
|
||||||
|
|
||||||
import ftbsc.lll.processor.annotations.Find;
|
import ftbsc.lll.processor.annotations.Find;
|
||||||
import ftbsc.lll.proxies.impl.FieldProxy;
|
|
||||||
import ftbsc.lll.proxies.impl.MethodProxy;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when a method is annotated with {@link Find} but does not
|
* Thrown when a method is annotated with {@link Find} but does not
|
||||||
* return a {@link MethodProxy} or a {@link FieldProxy}
|
* return a known instance of {@link ftbsc.lll.proxies.AbstractProxy}.
|
||||||
|
* @since 0.5.0
|
||||||
*/
|
*/
|
||||||
public class NotAProxyException extends RuntimeException {
|
public class NotAProxyException extends RuntimeException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a exception for the specified method.
|
* Constructs an exception for the specified method.
|
||||||
* @param parent the FQN of the class containing the method
|
* @param parent the FQN of the class containing the method
|
||||||
* @param method the name of the method wrongly annotated
|
* @param method the name of the method wrongly annotated
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ftbsc.lll.exceptions;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Element;
|
||||||
|
import javax.lang.model.element.QualifiedNameable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when an annotated element that needs to be paired with
|
||||||
|
* another does not match with any.
|
||||||
|
* @since 0.5.0
|
||||||
|
*/
|
||||||
|
public class OrphanElementException extends RuntimeException {
|
||||||
|
/**
|
||||||
|
* Constructs an exception for the specified method.
|
||||||
|
* @param element the orphan element
|
||||||
|
*/
|
||||||
|
public OrphanElementException(Element element) {
|
||||||
|
super(
|
||||||
|
String.format(
|
||||||
|
"Could not find a valid target for element %s.%s!",
|
||||||
|
((QualifiedNameable) element.getEnclosingElement()).getQualifiedName().toString(),
|
||||||
|
element.getSimpleName().toString()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import com.squareup.javapoet.*;
|
||||||
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.InvalidResourceException;
|
||||||
|
import ftbsc.lll.exceptions.OrphanElementException;
|
||||||
import ftbsc.lll.processor.annotations.Find;
|
import ftbsc.lll.processor.annotations.Find;
|
||||||
import ftbsc.lll.processor.annotations.Injector;
|
import ftbsc.lll.processor.annotations.Injector;
|
||||||
import ftbsc.lll.processor.annotations.Patch;
|
import ftbsc.lll.processor.annotations.Patch;
|
||||||
|
@ -159,7 +160,7 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
&& processingEnv.getTypeUtils().isSameType(params.get(1), methodNodeType);
|
&& processingEnv.getTypeUtils().isSameType(params.get(1), methodNodeType);
|
||||||
})) return true;
|
})) return true;
|
||||||
else {
|
else {
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, //TODO orphan targets
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
|
||||||
String.format("Missing valid @Injector method in @Patch class %s, skipping.", elem));
|
String.format("Missing valid @Injector method in @Patch class %s, skipping.", elem));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -224,6 +225,10 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
//this will contain the classes to generate: the key is the class name
|
//this will contain the classes to generate: the key is the class name
|
||||||
HashMap<String, InjectorInfo> toGenerate = new HashMap<>();
|
HashMap<String, InjectorInfo> toGenerate = new HashMap<>();
|
||||||
|
|
||||||
|
//these are needed for orphan checks
|
||||||
|
HashSet<ExecutableElement> matchedInjectors = new HashSet<>();
|
||||||
|
HashSet<VariableElement> matchedMethodFinders = new HashSet<>();
|
||||||
|
|
||||||
for(ExecutableElement tg : targets) {
|
for(ExecutableElement tg : targets) {
|
||||||
Target[] mtgAnn = tg.getAnnotationsByType(Target.class);
|
Target[] mtgAnn = tg.getAnnotationsByType(Target.class);
|
||||||
int iterationNumber = 1;
|
int iterationNumber = 1;
|
||||||
|
@ -248,15 +253,19 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
finderCandidates = new ArrayList<>(); //no candidates
|
finderCandidates = new ArrayList<>(); //no candidates
|
||||||
injectorCandidates = new ArrayList<>();
|
injectorCandidates = new ArrayList<>();
|
||||||
injectorCandidates.add(injectors.get(0));
|
injectorCandidates.add(injectors.get(0));
|
||||||
} else { //todo match finders based on same name
|
} else {
|
||||||
//case 3: try to match by injectTargetName
|
//case 3: try to match by injectTargetName or same name for finers
|
||||||
finderCandidates = new ArrayList<>(); //no candidates
|
|
||||||
String inferredName = "inject" + tg.getSimpleName();
|
String inferredName = "inject" + tg.getSimpleName();
|
||||||
injectorCandidates =
|
injectorCandidates =
|
||||||
injectorCandidates
|
injectorCandidates
|
||||||
.stream()
|
.stream()
|
||||||
.filter(t -> t.getSimpleName().toString().equalsIgnoreCase(inferredName))
|
.filter(t -> t.getSimpleName().toString().equalsIgnoreCase(inferredName))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
finderCandidates =
|
||||||
|
finderCandidates
|
||||||
|
.stream()
|
||||||
|
.filter(t -> t.getSimpleName().contentEquals(tg.getSimpleName()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
//throw exception if user is a moron and defined a finder and an injector with the same name
|
//throw exception if user is a moron and defined a finder and an injector with the same name
|
||||||
|
@ -278,16 +287,20 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
else {
|
else {
|
||||||
if(injectorCandidates.size() == 1) {
|
if(injectorCandidates.size() == 1) {
|
||||||
//matched an injector!
|
//matched an injector!
|
||||||
|
ExecutableElement injector = injectorCandidates.get(0);
|
||||||
|
matchedInjectors.add(injector);
|
||||||
toGenerate.put(
|
toGenerate.put(
|
||||||
String.format("%sInjector%d", cl.getSimpleName(), iterationNumber),
|
String.format("%sInjector%d", cl.getSimpleName(), iterationNumber),
|
||||||
new InjectorInfo(injectorCandidates.get(0), tg)
|
new InjectorInfo(injector, tg)
|
||||||
);
|
);
|
||||||
iterationNumber++; //increment is only used by injectors
|
iterationNumber++; //increment is only used by injectors
|
||||||
} else {
|
} else {
|
||||||
//matched a finder!
|
//matched a finder!
|
||||||
|
VariableElement finder = finderCandidates.get(0);
|
||||||
|
matchedMethodFinders.add(finder);
|
||||||
appendMemberFinderDefinition(
|
appendMemberFinderDefinition(
|
||||||
targetClass,
|
targetClass,
|
||||||
finderCandidates.get(0),
|
finder,
|
||||||
tg,
|
tg,
|
||||||
constructorBuilder,
|
constructorBuilder,
|
||||||
this.processingEnv,
|
this.processingEnv,
|
||||||
|
@ -298,6 +311,14 @@ public class LilleroProcessor extends AbstractProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//find orphans, throw exception if any are found
|
||||||
|
for(ExecutableElement e : injectors)
|
||||||
|
if(!matchedInjectors.contains(e))
|
||||||
|
throw new OrphanElementException(e);
|
||||||
|
for(VariableElement e : methodFinders)
|
||||||
|
if(!matchedMethodFinders.contains(e))
|
||||||
|
throw new OrphanElementException(e);
|
||||||
|
|
||||||
//iterate over the map and generate the classes
|
//iterate over the map and generate the classes
|
||||||
for(String injName : toGenerate.keySet()) {
|
for(String injName : toGenerate.keySet()) {
|
||||||
String targetMethodDescriptor = descriptorFromExecutableElement(toGenerate.get(injName).target);
|
String targetMethodDescriptor = descriptorFromExecutableElement(toGenerate.get(injName).target);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ftbsc.lll.processor.annotations;
|
package ftbsc.lll.processor.annotations;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Repeatable;
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package ftbsc.lll.processor.annotations;
|
package ftbsc.lll.processor.annotations;
|
||||||
|
|
||||||
import ftbsc.lll.proxies.impl.TypeProxy;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
|
@ -14,12 +14,7 @@ import ftbsc.lll.proxies.ProxyType;
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import javax.lang.model.type.MirroredTypeException;
|
import javax.lang.model.type.MirroredTypeException;
|
||||||
import javax.lang.model.type.MirroredTypesException;
|
|
||||||
import javax.lang.model.type.TypeMirror;
|
|
||||||
import javax.lang.model.util.Elements;
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
|
@ -19,12 +19,8 @@ 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 javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static ftbsc.lll.processor.tools.ASTUtils.*;
|
import static ftbsc.lll.processor.tools.ASTUtils.*;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue