Making processor a bit more robust against source files missing in compilation

This commit is contained in:
Gunnar Morling 2014-01-04 18:14:06 +01:00
parent 4f3ef4f66c
commit 8426b1af34
4 changed files with 28 additions and 6 deletions

View File

@ -18,12 +18,15 @@
*/ */
package org.mapstruct.ap; package org.mapstruct.ap;
import javax.annotation.processing.Messager;
import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
/** /**
* Indicates an error during annotation processing. * Indicates an error during annotation processing. Should only be thrown in non-recoverable situations such as errors
* due to incomplete compilations etc. Expected errors to be propagated to the user of the annotation processor should
* be raised using the {@link Messager} API instead.
* *
* @author Gunnar Morling * @author Gunnar Morling
*/ */
@ -34,6 +37,10 @@ public class AnnotationProcessingException extends RuntimeException {
private final AnnotationMirror annotationMirror; private final AnnotationMirror annotationMirror;
private final AnnotationValue annotationValue; private final AnnotationValue annotationValue;
public AnnotationProcessingException(String message) {
this( message, null, null, null );
}
public AnnotationProcessingException(String message, Element element) { public AnnotationProcessingException(String message, Element element) {
this( message, element, null, null ); this( message, element, null, null );
} }

View File

@ -18,10 +18,13 @@
*/ */
package org.mapstruct.ap.processor; package org.mapstruct.ap.processor;
import static javax.lang.model.util.ElementFilter.methodsIn;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.annotation.processing.Messager; import javax.annotation.processing.Messager;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
@ -31,6 +34,7 @@ import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic.Kind; import javax.tools.Diagnostic.Kind;
import org.mapstruct.ap.AnnotationProcessingException;
import org.mapstruct.ap.IterableMappingPrism; import org.mapstruct.ap.IterableMappingPrism;
import org.mapstruct.ap.MapMappingPrism; import org.mapstruct.ap.MapMappingPrism;
import org.mapstruct.ap.MapperPrism; import org.mapstruct.ap.MapperPrism;
@ -45,8 +49,6 @@ import org.mapstruct.ap.model.source.Method;
import org.mapstruct.ap.util.Executables; import org.mapstruct.ap.util.Executables;
import org.mapstruct.ap.util.TypeFactory; import org.mapstruct.ap.util.TypeFactory;
import static javax.lang.model.util.ElementFilter.methodsIn;
/** /**
* A {@link ModelElementProcessor} which retrieves a list of {@link Method}s * A {@link ModelElementProcessor} which retrieves a list of {@link Method}s
* representing all the mapping methods of the given bean mapper type as well as * representing all the mapping methods of the given bean mapper type as well as
@ -88,8 +90,6 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
private List<Method> retrieveMethods(TypeElement element, boolean mapperRequiresImplementation) { private List<Method> retrieveMethods(TypeElement element, boolean mapperRequiresImplementation) {
List<Method> methods = new ArrayList<Method>(); List<Method> methods = new ArrayList<Method>();
MapperPrism mapperPrism = mapperRequiresImplementation ? MapperPrism.getInstanceOn( element ) : null;
for ( ExecutableElement executable : methodsIn( element.getEnclosedElements() ) ) { for ( ExecutableElement executable : methodsIn( element.getEnclosedElements() ) ) {
Method method = getMethod( element, executable, mapperRequiresImplementation ); Method method = getMethod( element, executable, mapperRequiresImplementation );
if ( method != null ) { if ( method != null ) {
@ -99,6 +99,13 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
//Add all methods of used mappers in order to reference them in the aggregated model //Add all methods of used mappers in order to reference them in the aggregated model
if ( mapperRequiresImplementation ) { if ( mapperRequiresImplementation ) {
MapperPrism mapperPrism = MapperPrism.getInstanceOn( element );
if ( !mapperPrism.isValid ) {
throw new AnnotationProcessingException(
"Couldn't retrieve @Mapper annotation", element, mapperPrism.mirror
);
}
for ( TypeMirror usedMapper : mapperPrism.uses() ) { for ( TypeMirror usedMapper : mapperPrism.uses() ) {
methods.addAll( methods.addAll(
retrieveMethods( retrieveMethods(

View File

@ -42,6 +42,7 @@ import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
import org.mapstruct.ap.AnnotationProcessingException;
import org.mapstruct.ap.model.Type; import org.mapstruct.ap.model.Type;
/** /**
@ -100,6 +101,10 @@ public class TypeFactory {
} }
public Type getType(TypeMirror mirror) { public Type getType(TypeMirror mirror) {
if ( mirror.getKind() == TypeKind.ERROR ) {
throw new AnnotationProcessingException( "Encountered erroneous type " + mirror );
}
Type implementationType = getImplementationType( mirror ); Type implementationType = getImplementationType( mirror );
boolean isIterableType = typeUtils.isSubtype( boolean isIterableType = typeUtils.isSubtype(

View File

@ -305,7 +305,10 @@ public abstract class MapperTestBase {
@Override @Override
public int compare(DiagnosticDescriptor o1, DiagnosticDescriptor o2) { public int compare(DiagnosticDescriptor o1, DiagnosticDescriptor o2) {
int result = o1.getSourceFileName().compareTo( o2.getSourceFileName() ); String sourceFileName1 = o1.getSourceFileName() != null ? o1.getSourceFileName() : "";
String sourceFileName2 = o2.getSourceFileName() != null ? o2.getSourceFileName() : "";
int result = sourceFileName1.compareTo( sourceFileName2 );
if ( result != 0 ) { if ( result != 0 ) {
return result; return result;