From 7c62aec28195950ac6feafd4b2345a8c06ecf6c8 Mon Sep 17 00:00:00 2001 From: Sjaak Derksen Date: Sat, 25 Apr 2020 17:01:22 +0200 Subject: [PATCH] #2077 nullpointer due to no-getter source (#2078) --- .../ap/internal/model/BeanMappingMethod.java | 49 ++++++++++--------- .../bugs/_2077/Issue2077ErroneousMapper.java | 37 ++++++++++++++ .../ap/test/bugs/_2077/Issue2077Test.java | 39 +++++++++++++++ 3 files changed, 102 insertions(+), 23 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077ErroneousMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077Test.java diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java index 5cb2192aa..53a271858 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java @@ -721,30 +721,33 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { sourceRef = getSourceRef( method.getSourceParameters().get( 0 ), targetPropertyName ); } - if ( sourceRef.isValid() ) { + if ( sourceRef != null ) { + // sourceRef == null is not considered an error here + if ( sourceRef.isValid() ) { - // targetProperty == null can occur: we arrived here because we want as many errors - // as possible before we stop analysing - propertyMapping = new PropertyMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) - .sourcePropertyName( mapping.getSourceName() ) - .sourceReference( sourceRef ) - .selectionParameters( mapping.getSelectionParameters() ) - .formattingParameters( mapping.getFormattingParameters() ) - .existingVariableNames( existingVariableNames ) - .dependsOn( mapping.getDependsOn() ) - .defaultValue( mapping.getDefaultValue() ) - .defaultJavaExpression( mapping.getDefaultJavaExpression() ) - .mirror( mapping.getMirror() ) - .options( mapping ) - .build(); - handledTargets.add( targetPropertyName ); - unprocessedSourceParameters.remove( sourceRef.getParameter() ); - } - else { - errorOccured = true; + // targetProperty == null can occur: we arrived here because we want as many errors + // as possible before we stop analysing + propertyMapping = new PropertyMappingBuilder() + .mappingContext( ctx ) + .sourceMethod( method ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .sourcePropertyName( mapping.getSourceName() ) + .sourceReference( sourceRef ) + .selectionParameters( mapping.getSelectionParameters() ) + .formattingParameters( mapping.getFormattingParameters() ) + .existingVariableNames( existingVariableNames ) + .dependsOn( mapping.getDependsOn() ) + .defaultValue( mapping.getDefaultValue() ) + .defaultJavaExpression( mapping.getDefaultJavaExpression() ) + .mirror( mapping.getMirror() ) + .options( mapping ) + .build(); + handledTargets.add( targetPropertyName ); + unprocessedSourceParameters.remove( sourceRef.getParameter() ); + } + else { + errorOccured = true; + } } } // remaining are the mappings without a 'source' so, 'only' a date format or qualifiers diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077ErroneousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077ErroneousMapper.java new file mode 100644 index 000000000..ecbff6380 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077ErroneousMapper.java @@ -0,0 +1,37 @@ +/* + * 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._2077; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( unmappedTargetPolicy = ReportingPolicy.ERROR ) +public interface Issue2077ErroneousMapper { + + Issue2077ErroneousMapper INSTANCE = Mappers.getMapper( Issue2077ErroneousMapper.class ); + + @Mapping(target = "s1", defaultValue = "xyz" ) + Target map(String source); + + class Target { + + private String s1; + + public String getS1() { + return s1; + } + + public void setS1(String s1) { + this.s1 = s1; + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077Test.java new file mode 100644 index 000000000..d8c3a1e5d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077Test.java @@ -0,0 +1,39 @@ +/* + * 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._2077; + +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; + +import static javax.tools.Diagnostic.Kind.ERROR; + +/** + * @author Sjaak Derksen + */ +@IssueKey("2077") +@RunWith(AnnotationProcessorTestRunner.class) +public class Issue2077Test { + + @Test + @WithClasses(Issue2077ErroneousMapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = Issue2077ErroneousMapper.class, + kind = ERROR, + line = 22, + message = "Unmapped target property: \"s1\".") + } + ) + public void shouldNotCompile() { + } +}