#2863 Add validation of String type to @TargetPropertyName

This commit is contained in:
paparadva 2022-10-30 13:11:26 +03:00 committed by Filip Hrisafov
parent efaa67aadf
commit 7c90592d05
4 changed files with 58 additions and 2 deletions

View File

@ -28,6 +28,7 @@ import org.mapstruct.ap.internal.gem.MappingsGem;
import org.mapstruct.ap.internal.gem.ObjectFactoryGem;
import org.mapstruct.ap.internal.gem.SubclassMappingGem;
import org.mapstruct.ap.internal.gem.SubclassMappingsGem;
import org.mapstruct.ap.internal.gem.TargetPropertyNameGem;
import org.mapstruct.ap.internal.gem.ValueMappingGem;
import org.mapstruct.ap.internal.gem.ValueMappingsGem;
import org.mapstruct.ap.internal.model.common.Parameter;
@ -230,7 +231,7 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
// otherwise add reference to existing mapper method
else if ( isValidReferencedMethod( parameters ) || isValidFactoryMethod( method, parameters, returnType )
|| isValidLifecycleCallbackMethod( method )
|| isValidPresenceCheckMethod( method, returnType ) ) {
|| isValidPresenceCheckMethod( method, parameters, returnType ) ) {
return getReferencedMethod( usedMapper, methodType, method, mapperToImplement, parameters );
}
else {
@ -407,7 +408,17 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
return ObjectFactoryGem.instanceOn( method ) != null;
}
private boolean isValidPresenceCheckMethod(ExecutableElement method, Type returnType) {
private boolean isValidPresenceCheckMethod(ExecutableElement method, List<Parameter> parameters, Type returnType) {
for ( Parameter param : parameters ) {
if ( param.isTargetPropertyName() && !param.getType().isString() ) {
messager.printMessage(
param.getElement(),
TargetPropertyNameGem.instanceOn( param.getElement() ).mirror(),
Message.RETRIEVAL_TARGET_PROPERTY_NAME_WRONG_TYPE
);
return false;
}
}
return isBoolean( returnType ) && hasConditionAnnotation( method );
}

View File

@ -176,6 +176,7 @@ public enum Message {
RETRIEVAL_MAPPER_USES_CYCLE( "The mapper %s is referenced itself in Mapper#uses.", Diagnostic.Kind.WARNING ),
RETRIEVAL_AFTER_METHOD_NOT_IMPLEMENTED( "@AfterMapping can only be applied to an implemented method." ),
RETRIEVAL_BEFORE_METHOD_NOT_IMPLEMENTED( "@BeforeMapping can only be applied to an implemented method." ),
RETRIEVAL_TARGET_PROPERTY_NAME_WRONG_TYPE( "@TargetPropertyName can only by applied to a String parameter." ),
INHERITINVERSECONFIGURATION_DUPLICATES( "Several matching inverse methods exist: %s(). Specify a name explicitly." ),
INHERITINVERSECONFIGURATION_INVALID_NAME( "None of the candidates %s() matches given name: \"%s\"." ),

View File

@ -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.conditional.targetpropertyname;
import org.mapstruct.Condition;
import org.mapstruct.Mapper;
import org.mapstruct.TargetPropertyName;
@Mapper
public interface ErroneousNonStringTargetPropertyNameParameter {
Employee map(EmployeeDto employee);
@Condition
default boolean isNotBlank(String value, @TargetPropertyName int propName) {
return value != null && !value.trim().isEmpty();
}
}

View File

@ -9,6 +9,9 @@ import org.junit.jupiter.api.extension.RegisterExtension;
import org.mapstruct.ap.testutil.IssueKey;
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.ap.testutil.runner.GeneratedSource;
import java.util.Collections;
@ -278,4 +281,24 @@ public class TargetPropertyNameTest {
"addresses.street"
);
}
@IssueKey("2863")
@ProcessorTest
@WithClasses({
ErroneousNonStringTargetPropertyNameParameter.class
})
@ExpectedCompilationOutcome(
value = CompilationResult.FAILED,
diagnostics = {
@Diagnostic(
kind = javax.tools.Diagnostic.Kind.ERROR,
type = ErroneousNonStringTargetPropertyNameParameter.class,
line = 18,
message = "@TargetPropertyName can only by applied to a String parameter."
)
}
)
public void nonStringTargetPropertyNameParameter() {
}
}