From 5217e67f8dc905a96fb35cf110affc02a5893c77 Mon Sep 17 00:00:00 2001 From: Andreas Gudian Date: Thu, 2 Jul 2015 20:51:45 +0200 Subject: [PATCH] #590 Update methods are not supported for "method-and-conversion" methods (can currently cause NullPointerExceptions) --- .../creation/MappingResolverImpl.java | 6 +- .../ap/test/bugs/_590/Issue590Test.java | 47 ++++++++++++++ .../ap/test/bugs/_590/SourceTargetMapper.java | 63 +++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_590/Issue590Test.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_590/SourceTargetMapper.java diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java index 41db41690..8566fbc09 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java @@ -31,9 +31,9 @@ import org.mapstruct.ap.internal.conversion.ConversionProvider; import org.mapstruct.ap.internal.conversion.Conversions; import org.mapstruct.ap.internal.model.AssignmentFactory; import org.mapstruct.ap.internal.model.MapperReference; +import org.mapstruct.ap.internal.model.MappingBuilderContext.MappingResolver; import org.mapstruct.ap.internal.model.MethodReference; import org.mapstruct.ap.internal.model.VirtualMappingMethod; -import org.mapstruct.ap.internal.model.MappingBuilderContext.MappingResolver; import org.mapstruct.ap.internal.model.assignment.Assignment; import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.DefaultConversionContext; @@ -391,6 +391,10 @@ public class MappingResolverImpl implements MappingResolver { // search the other way around for ( Method methodXCandidate : methodXCandidates ) { + if ( methodXCandidate.getMappingTargetParameter() != null ) { + continue; + } + Assignment methodRefX = resolveViaMethod( sourceType, methodXCandidate.getReturnType(), diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/Issue590Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/Issue590Test.java new file mode 100644 index 000000000..2ca636358 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/Issue590Test.java @@ -0,0 +1,47 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.bugs._590; + +import javax.tools.Diagnostic.Kind; + +import org.junit.Test; +import org.junit.runner.RunWith; +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 Andreas Gudian + */ +@RunWith(AnnotationProcessorTestRunner.class) +@WithClasses(SourceTargetMapper.class) +public class Issue590Test { + + @Test + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { @Diagnostic(type = SourceTargetMapper.class, + kind = Kind.ERROR, + line = 34, + messageRegExp = "Can't map property \"[^ ]+ [^\"]+\" to \"[^ ]+ [^\"]+\"") }) + public void showsCantMapPropertyError() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/SourceTargetMapper.java new file mode 100644 index 000000000..73ca00d93 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/SourceTargetMapper.java @@ -0,0 +1,63 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.bugs._590; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.TargetType; +import org.mapstruct.factory.Mappers; + +/** + * @author Andreas Gudian + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN) +public abstract class SourceTargetMapper { + public static final SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + public abstract void sourceToTarget(@MappingTarget Target target, Source source); + + public T unused(String string, @TargetType Class clazz) { + throw new RuntimeException( "should never be called" ); + } + + public static class Source { + private String prop; + + public String getProp() { + return prop; + } + + public void setProp(String prop) { + this.prop = prop; + } + } + + public static class Target { + private StringBuilder prop; + + public StringBuilder getProp() { + return prop; + } + + public void setProp(StringBuilder prop) { + this.prop = prop; + } + } +}