#2347 Do not generate mapper implementation for private mappers

Provide a compiler error message instead of generating code that will not compile
This commit is contained in:
Filip Hrisafov 2021-02-06 10:26:08 +01:00
parent f4b62ded89
commit 07f5189a72
4 changed files with 113 additions and 0 deletions

View File

@ -15,6 +15,7 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
@ -210,6 +211,17 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
mappingContext.getForgedMethodsUnderCreation().keySet() );
}
if ( element.getModifiers().contains( Modifier.PRIVATE ) ) {
// If the mapper element is private then we should report an error
// we can't generate an implementation for a private mapper
mappingContext.getMessager()
.printMessage( element,
Message.GENERAL_CANNOT_IMPLEMENT_PRIVATE_MAPPER,
element.getSimpleName().toString(),
element.getKind() == ElementKind.INTERFACE ? "interface" : "class"
);
}
return mapper;
}

View File

@ -115,6 +115,7 @@ public enum Message {
DECORATOR_NO_SUBTYPE( "Specified decorator type is no subtype of the annotated mapper type." ),
DECORATOR_CONSTRUCTOR( "Specified decorator type has no default constructor nor a constructor with a single parameter accepting the decorated mapper type." ),
GENERAL_CANNOT_IMPLEMENT_PRIVATE_MAPPER("Cannot create an implementation for mapper %s, because it is a private %s."),
GENERAL_NO_IMPLEMENTATION( "No implementation type is registered for return type %s." ),
GENERAL_ABSTRACT_RETURN_TYPE( "The return type %s is an abstract class or interface. Provide a non abstract / non interface result type or a factory method." ),
GENERAL_AMBIGUOUS_MAPPING_METHOD( "Ambiguous mapping methods found for mapping %s to %s: %s. See " + FAQ_AMBIGUOUS_URL + " for more info." ),

View File

@ -0,0 +1,51 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._2347;
import org.mapstruct.Mapper;
/**
* @author Filip Hrisafov
*/
public class ErroneousClassWithPrivateMapper {
public static class Target {
private final String id;
public Target(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
public static class Source {
private final String id;
public Source(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
@Mapper
private interface PrivateInterfaceMapper {
Target map(Source source);
}
@Mapper
private abstract class PrivateClassMapper {
public abstract Target map(Source source);
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._2347;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
/**
* @author Filip Hrisafov
*/
@IssueKey("2347")
@RunWith(AnnotationProcessorTestRunner.class)
@WithClasses({
ErroneousClassWithPrivateMapper.class
})
public class Issue2347Test {
@ExpectedCompilationOutcome(value = CompilationResult.FAILED,
diagnostics = {
@Diagnostic(
type = ErroneousClassWithPrivateMapper.class,
kind = javax.tools.Diagnostic.Kind.ERROR,
line = 41,
message = "Cannot create an implementation for mapper PrivateInterfaceMapper," +
" because it is a private interface."
),
@Diagnostic(
type = ErroneousClassWithPrivateMapper.class,
kind = javax.tools.Diagnostic.Kind.ERROR,
line = 47,
message = "Cannot create an implementation for mapper PrivateClassMapper," +
" because it is a private class."
)
}
)
@Test
public void shouldGenerateCompileErrorWhenMapperIsPrivate() {
}
}