mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#2773 Copy @Deprecated
annotation from method or mapper to implementation
This commit is contained in:
parent
73e8fd6152
commit
e979f506fa
@ -31,6 +31,7 @@ public final class FullFeatureCompilationExclusionCliEnhancer implements Process
|
|||||||
case JAVA_8:
|
case JAVA_8:
|
||||||
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/cdi/**/*.java" );
|
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/cdi/**/*.java" );
|
||||||
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/**/*.java" );
|
additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/**/*.java" );
|
||||||
|
additionalExcludes.add( "org/mapstruct/ap/test/annotatewith/deprecated/jdk11/*.java" );
|
||||||
break;
|
break;
|
||||||
case JAVA_9:
|
case JAVA_9:
|
||||||
// TODO find out why this fails:
|
// TODO find out why this fails:
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
<additionalExclude2>x</additionalExclude2>
|
<additionalExclude2>x</additionalExclude2>
|
||||||
<additionalExclude3>x</additionalExclude3>
|
<additionalExclude3>x</additionalExclude3>
|
||||||
<additionalExclude4>x</additionalExclude4>
|
<additionalExclude4>x</additionalExclude4>
|
||||||
|
<additionalExclude5>x</additionalExclude5>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -45,6 +46,7 @@
|
|||||||
<exclude>${additionalExclude2}</exclude>
|
<exclude>${additionalExclude2}</exclude>
|
||||||
<exclude>${additionalExclude3}</exclude>
|
<exclude>${additionalExclude3}</exclude>
|
||||||
<exclude>${additionalExclude4}</exclude>
|
<exclude>${additionalExclude4}</exclude>
|
||||||
|
<exclude>${additionalExclude5}</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
@ -45,6 +45,7 @@ import org.mapstruct.tools.gem.GemDefinition;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
|
@GemDefinition(Deprecated.class)
|
||||||
@GemDefinition(AnnotateWith.class)
|
@GemDefinition(AnnotateWith.class)
|
||||||
@GemDefinition(AnnotateWith.Element.class)
|
@GemDefinition(AnnotateWith.Element.class)
|
||||||
@GemDefinition(AnnotateWiths.class)
|
@GemDefinition(AnnotateWiths.class)
|
||||||
|
@ -10,6 +10,7 @@ import java.lang.annotation.Repeatable;
|
|||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -31,6 +32,7 @@ import javax.lang.model.type.TypeMirror;
|
|||||||
|
|
||||||
import org.mapstruct.ap.internal.gem.AnnotateWithGem;
|
import org.mapstruct.ap.internal.gem.AnnotateWithGem;
|
||||||
import org.mapstruct.ap.internal.gem.AnnotateWithsGem;
|
import org.mapstruct.ap.internal.gem.AnnotateWithsGem;
|
||||||
|
import org.mapstruct.ap.internal.gem.DeprecatedGem;
|
||||||
import org.mapstruct.ap.internal.gem.ElementGem;
|
import org.mapstruct.ap.internal.gem.ElementGem;
|
||||||
import org.mapstruct.ap.internal.model.annotation.AnnotationElement;
|
import org.mapstruct.ap.internal.model.annotation.AnnotationElement;
|
||||||
import org.mapstruct.ap.internal.model.annotation.AnnotationElement.AnnotationElementType;
|
import org.mapstruct.ap.internal.model.annotation.AnnotationElement.AnnotationElementType;
|
||||||
@ -55,7 +57,6 @@ public class AdditionalAnnotationsBuilder
|
|||||||
extends RepeatableAnnotations<AnnotateWithGem, AnnotateWithsGem, Annotation> {
|
extends RepeatableAnnotations<AnnotateWithGem, AnnotateWithsGem, Annotation> {
|
||||||
private static final String ANNOTATE_WITH_FQN = "org.mapstruct.AnnotateWith";
|
private static final String ANNOTATE_WITH_FQN = "org.mapstruct.AnnotateWith";
|
||||||
private static final String ANNOTATE_WITHS_FQN = "org.mapstruct.AnnotateWiths";
|
private static final String ANNOTATE_WITHS_FQN = "org.mapstruct.AnnotateWiths";
|
||||||
|
|
||||||
private TypeFactory typeFactory;
|
private TypeFactory typeFactory;
|
||||||
private FormattingMessager messager;
|
private FormattingMessager messager;
|
||||||
|
|
||||||
@ -90,6 +91,45 @@ public class AdditionalAnnotationsBuilder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Annotation> getProcessedAnnotations(Element source) {
|
||||||
|
Set<Annotation> processedAnnotations = super.getProcessedAnnotations( source );
|
||||||
|
return addDeprecatedAnnotation( source, processedAnnotations );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Annotation> addDeprecatedAnnotation(Element source, Set<Annotation> annotations) {
|
||||||
|
DeprecatedGem deprecatedGem = DeprecatedGem.instanceOn( source );
|
||||||
|
if ( deprecatedGem == null ) {
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
Type deprecatedType = typeFactory.getType( Deprecated.class );
|
||||||
|
if ( annotations.stream().anyMatch( annotation -> annotation.getType().equals( deprecatedType ) ) ) {
|
||||||
|
messager.printMessage(
|
||||||
|
source,
|
||||||
|
deprecatedGem.mirror(),
|
||||||
|
Message.ANNOTATE_WITH_DUPLICATE,
|
||||||
|
deprecatedType.describe() );
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
List<AnnotationElement> annotationElements = new ArrayList<>();
|
||||||
|
if ( deprecatedGem.since() != null && deprecatedGem.since().hasValue() ) {
|
||||||
|
annotationElements.add( new AnnotationElement(
|
||||||
|
AnnotationElementType.STRING,
|
||||||
|
"since",
|
||||||
|
Collections.singletonList( deprecatedGem.since().getValue() )
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
if ( deprecatedGem.forRemoval() != null && deprecatedGem.forRemoval().hasValue() ) {
|
||||||
|
annotationElements.add( new AnnotationElement(
|
||||||
|
AnnotationElementType.BOOLEAN,
|
||||||
|
"forRemoval",
|
||||||
|
Collections.singletonList( deprecatedGem.forRemoval().getValue() )
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
annotations.add( new Annotation(deprecatedType, annotationElements ) );
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
|
||||||
private void addAndValidateMapping(Set<Annotation> mappings, Element source, AnnotateWithGem gem, Annotation anno) {
|
private void addAndValidateMapping(Set<Annotation> mappings, Element source, AnnotateWithGem gem, Annotation anno) {
|
||||||
if ( anno.getType().getTypeElement().getAnnotation( Repeatable.class ) == null ) {
|
if ( anno.getType().getTypeElement().getAnnotation( Repeatable.class ) == null ) {
|
||||||
if ( mappings.stream().anyMatch( existing -> existing.getType().equals( anno.getType() ) ) ) {
|
if ( mappings.stream().anyMatch( existing -> existing.getType().equals( anno.getType() ) ) ) {
|
||||||
|
@ -593,5 +593,4 @@ public class AnnotateWithTest {
|
|||||||
Method method = mapper.getClass().getMethod( "map", String.class );
|
Method method = mapper.getClass().getMethod( "map", String.class );
|
||||||
assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull();
|
assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotatewith.deprecated;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
@Deprecated
|
||||||
|
public class DeprecatedMapperWithClass {
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotatewith.deprecated;
|
||||||
|
|
||||||
|
import org.mapstruct.AnnotateWith;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface DeprecatedMapperWithMethod {
|
||||||
|
|
||||||
|
@AnnotateWith(CustomMethodOnlyAnnotation.class)
|
||||||
|
@Deprecated
|
||||||
|
Target map(Source source);
|
||||||
|
|
||||||
|
class Source {
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Target {
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotatewith.deprecated;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation;
|
||||||
|
import org.mapstruct.ap.testutil.ProcessorTest;
|
||||||
|
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.factory.Mappers;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author orange add
|
||||||
|
*/
|
||||||
|
public class DeprecatedTest {
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
@WithClasses( { DeprecatedMapperWithMethod.class, CustomMethodOnlyAnnotation.class} )
|
||||||
|
public void deprecatedWithMethodCorrectCopy() throws NoSuchMethodException {
|
||||||
|
DeprecatedMapperWithMethod mapper = Mappers.getMapper( DeprecatedMapperWithMethod.class );
|
||||||
|
Method method = mapper.getClass().getMethod( "map", DeprecatedMapperWithMethod.Source.class );
|
||||||
|
Deprecated annotation = method.getAnnotation( Deprecated.class );
|
||||||
|
assertThat( annotation ).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
@WithClasses(DeprecatedMapperWithClass.class)
|
||||||
|
public void deprecatedWithClassCorrectCopy() {
|
||||||
|
DeprecatedMapperWithClass mapper = Mappers.getMapper( DeprecatedMapperWithClass.class );
|
||||||
|
Deprecated annotation = mapper.getClass().getAnnotation( Deprecated.class );
|
||||||
|
assertThat( annotation ).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
@WithClasses(RepeatDeprecatedMapper.class)
|
||||||
|
@ExpectedCompilationOutcome(
|
||||||
|
value = CompilationResult.SUCCEEDED,
|
||||||
|
diagnostics = {
|
||||||
|
@Diagnostic(
|
||||||
|
kind = javax.tools.Diagnostic.Kind.WARNING,
|
||||||
|
type = RepeatDeprecatedMapper.class,
|
||||||
|
message = "Annotation \"Deprecated\" is already present with the " +
|
||||||
|
"same elements configuration."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public void deprecatedWithRepeat() {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotatewith.deprecated;
|
||||||
|
|
||||||
|
import org.mapstruct.AnnotateWith;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
@Deprecated
|
||||||
|
@AnnotateWith(Deprecated.class)
|
||||||
|
public class RepeatDeprecatedMapper {
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotatewith.deprecated.jdk11;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
@Deprecated(since = "11")
|
||||||
|
public class DeprecatedMapperWithClass {
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotatewith.deprecated.jdk11;
|
||||||
|
|
||||||
|
import org.mapstruct.AnnotateWith;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface DeprecatedMapperWithMethod {
|
||||||
|
|
||||||
|
@AnnotateWith(CustomMethodOnlyAnnotation.class)
|
||||||
|
@Deprecated(since = "18", forRemoval = false)
|
||||||
|
Target map(Source source);
|
||||||
|
|
||||||
|
class Source {
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Target {
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotatewith.deprecated.jdk11;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation;
|
||||||
|
import org.mapstruct.ap.testutil.ProcessorTest;
|
||||||
|
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.factory.Mappers;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author orange add
|
||||||
|
*/
|
||||||
|
public class DeprecatedTest {
|
||||||
|
@ProcessorTest
|
||||||
|
@WithClasses({ DeprecatedMapperWithMethod.class, CustomMethodOnlyAnnotation.class})
|
||||||
|
public void deprecatedWithMethodCorrectCopyForJdk11() throws NoSuchMethodException {
|
||||||
|
DeprecatedMapperWithMethod mapper = Mappers.getMapper( DeprecatedMapperWithMethod.class );
|
||||||
|
Method method = mapper.getClass().getMethod( "map", DeprecatedMapperWithMethod.Source.class );
|
||||||
|
Deprecated annotation = method.getAnnotation( Deprecated.class );
|
||||||
|
assertThat( annotation ).isNotNull();
|
||||||
|
assertThat( annotation.since() ).isEqualTo( "18" );
|
||||||
|
assertThat( annotation.forRemoval() ).isEqualTo( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
@WithClasses(DeprecatedMapperWithClass.class)
|
||||||
|
public void deprecatedWithClassCorrectCopyForJdk11() {
|
||||||
|
DeprecatedMapperWithClass mapper = Mappers.getMapper( DeprecatedMapperWithClass.class );
|
||||||
|
Deprecated annotation = mapper.getClass().getAnnotation( Deprecated.class );
|
||||||
|
assertThat( annotation ).isNotNull();
|
||||||
|
assertThat( annotation.since() ).isEqualTo( "11" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
@WithClasses( { RepeatDeprecatedMapperWithParams.class})
|
||||||
|
@ExpectedCompilationOutcome(
|
||||||
|
value = CompilationResult.SUCCEEDED,
|
||||||
|
diagnostics = {
|
||||||
|
@Diagnostic(
|
||||||
|
kind = javax.tools.Diagnostic.Kind.WARNING,
|
||||||
|
type = RepeatDeprecatedMapperWithParams.class,
|
||||||
|
message = "Annotation \"Deprecated\" is already present with the " +
|
||||||
|
"same elements configuration."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public void bothExistPriorityAnnotateWithForJdk11() {
|
||||||
|
RepeatDeprecatedMapperWithParams mapper = Mappers.getMapper( RepeatDeprecatedMapperWithParams.class );
|
||||||
|
Deprecated deprecated = mapper.getClass().getAnnotation( Deprecated.class );
|
||||||
|
assertThat( deprecated ).isNotNull();
|
||||||
|
assertThat( deprecated.since() ).isEqualTo( "1.5" );
|
||||||
|
assertThat( deprecated.forRemoval() ).isEqualTo( false );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotatewith.deprecated.jdk11;
|
||||||
|
|
||||||
|
import org.mapstruct.AnnotateWith;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
@Deprecated( since = "1.8" )
|
||||||
|
@AnnotateWith(
|
||||||
|
value = Deprecated.class,
|
||||||
|
elements = {
|
||||||
|
@AnnotateWith.Element( name = "forRemoval", booleans = false),
|
||||||
|
@AnnotateWith.Element( name = "since", strings = "1.5")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class RepeatDeprecatedMapperWithParams {
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user