#3296: Skip default and static methods when determining prototype methods

This commit is contained in:
Zegveld 2023-07-08 18:03:56 +02:00 committed by GitHub
parent 1b1325da6d
commit 04434af17a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 158 additions and 0 deletions

View File

@ -124,6 +124,11 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
List<SourceMethod> methods = new ArrayList<>(); List<SourceMethod> methods = new ArrayList<>();
for ( ExecutableElement executable : elementUtils.getAllEnclosedExecutableElements( typeElement ) ) { for ( ExecutableElement executable : elementUtils.getAllEnclosedExecutableElements( typeElement ) ) {
if ( executable.isDefault() || executable.getModifiers().contains( Modifier.STATIC ) ) {
// skip the default and static methods because these are not prototypes.
continue;
}
ExecutableType methodType = typeFactory.getMethodType( mapperAnnotation.mapperConfigType(), executable ); ExecutableType methodType = typeFactory.getMethodType( mapperAnnotation.mapperConfigType(), executable );
List<Parameter> parameters = typeFactory.getParameters( methodType, executable ); List<Parameter> parameters = typeFactory.getParameters( methodType, executable );
boolean containsTargetTypeParameter = SourceMethod.containsTargetTypeParameter( parameters ); boolean containsTargetTypeParameter = SourceMethod.containsTargetTypeParameter( parameters );

View File

@ -0,0 +1,18 @@
/*
* 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._3296;
public class Entity {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,43 @@
/*
* 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._3296;
import static org.assertj.core.api.Assertions.assertThat;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.factory.Mappers;
/**
* @author Ben Zegveld
*/
@IssueKey( "3296" )
@WithClasses( { Entity.class, Payload.class } )
public class Issue3296Test {
@ProcessorTest
@WithClasses( { MapperExtendingConfig.class, MapperConfigWithPayloadArgument.class } )
public void shouldNotRaiseErrorForDefaultAfterMappingMethodImplementation() {
Payload payload = new Payload();
payload.setName( "original" );
Entity entity = Mappers.getMapper( MapperExtendingConfig.class ).toEntity( payload );
assertThat( entity.getName() ).isEqualTo( "AfterMapping called" );
}
@ProcessorTest
@WithClasses( { MapperNotExtendingConfig.class, MapperConfigWithoutPayloadArgument.class } )
public void shouldNotRaiseErrorRequiringArgumentsForDefaultMethods() {
Payload payload = new Payload();
payload.setName( "original" );
Entity entity = Mappers.getMapper( MapperNotExtendingConfig.class ).toEntity( payload );
assertThat( entity.getName() ).isEqualTo( "original" );
}
}

View File

@ -0,0 +1,24 @@
/*
* 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._3296;
import org.mapstruct.AfterMapping;
import org.mapstruct.MapperConfig;
import org.mapstruct.MappingTarget;
@MapperConfig
public interface MapperConfigWithPayloadArgument {
@AfterMapping
default void afterMapping(@MappingTarget Entity entity, Payload unused) {
staticMethod( entity );
}
static void staticMethod(Entity entity) {
entity.setName( "AfterMapping called" );
}
}

View File

@ -0,0 +1,23 @@
/*
* 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._3296;
import org.mapstruct.AfterMapping;
import org.mapstruct.MapperConfig;
import org.mapstruct.MappingTarget;
@MapperConfig
public interface MapperConfigWithoutPayloadArgument {
@AfterMapping
default void afterMapping(@MappingTarget Entity entity) {
staticMethod( entity );
}
static void staticMethod(Entity entity) {
entity.setName( "AfterMapping called" );
}
}

View File

@ -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.bugs._3296;
import org.mapstruct.Mapper;
@Mapper( config = MapperConfigWithPayloadArgument.class )
public interface MapperExtendingConfig extends MapperConfigWithPayloadArgument {
Entity toEntity(Payload payload);
}

View File

@ -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.bugs._3296;
import org.mapstruct.Mapper;
@Mapper( config = MapperConfigWithoutPayloadArgument.class )
public interface MapperNotExtendingConfig {
Entity toEntity(Payload payload);
}

View File

@ -0,0 +1,19 @@
/*
* 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._3296;
public class Payload {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}