From ffa2993aeb4f503c7e29c7fbba22ff65476c8195 Mon Sep 17 00:00:00 2001 From: orange add <771240658@qq.com> Date: Tue, 16 Aug 2022 15:24:05 +0800 Subject: [PATCH 01/15] feat: Copy the method annotation to the implementation method --- .../ap/internal/model/BeanMappingMethod.java | 59 ++++++++++++++-- .../ap/internal/model/BeanMappingMethod.ftl | 3 + .../ap/test/bugs/_2773/ChartEntry.java | 67 +++++++++++++++++++ .../ap/test/bugs/_2773/Issue2773Mapper.java | 26 +++++++ .../ap/test/bugs/_2773/Issue2773Test.java | 36 ++++++++++ .../mapstruct/ap/test/bugs/_2773/Studio.java | 31 +++++++++ .../ap/test/bugs/_2773/TestAnnotation.java | 17 +++++ 7 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.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 0b299067f5..42fbbeccc2 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 @@ -95,6 +95,8 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { private final MappingReferences mappingReferences; + private final List methodAnnotations; + public static class Builder extends AbstractMappingMethodBuilder { private Type userDefinedReturnType; @@ -357,6 +359,8 @@ else if ( !method.isUpdateMethod() ) { finalizeMethod = getFinalizerMethod(); } + List methodAnnotations = getSourceMethodAnnotations(); + return new BeanMappingMethod( method, existingVariableNames, @@ -369,7 +373,8 @@ else if ( !method.isUpdateMethod() ) { afterMappingMethods, finalizeMethod, mappingReferences, - subclasses + subclasses, + methodAnnotations ); } @@ -1684,6 +1689,44 @@ private void reportErrorForUnusedSourceParameters() { } } } + + /** + * Get annotations for non-mapstruct frameworks in methods + * + * @return annotations + */ + private List getSourceMethodAnnotations(){ + List annotationTypes = new ArrayList<>(); + if (method instanceof SourceMethod) { + SourceMethod sourceMethod = (SourceMethod) method; + List annotationMirrors = sourceMethod.getExecutable().getAnnotationMirrors(); + TypeFactory typeFactory = this.ctx.getTypeFactory(); + for (AnnotationMirror annotationMirror : annotationMirrors) { + Type type = typeFactory.getType(annotationMirror.getAnnotationType()); + if (isInternalAnnotation(type)){ + continue; + } + Map elementValues = annotationMirror.getElementValues(); + if (elementValues.isEmpty()){ + annotationTypes.add(new Annotation(type)); + continue; + } + List properties = new ArrayList<>(); + for (Entry entry : elementValues.entrySet()) { + ExecutableElement key = entry.getKey(); + AnnotationValue value = entry.getValue(); + properties.add(key.getSimpleName().toString()+" = "+value.toString()); + } + annotationTypes.add(new Annotation(type,properties)); + } + } + return annotationTypes; + } + + private boolean isInternalAnnotation(Type type){ + return type.getPackageName().equalsIgnoreCase("org.mapstruct"); + } + } private static class ConstructorAccessor { @@ -1710,7 +1753,9 @@ private BeanMappingMethod(Method method, List afterMappingReferences, MethodReference finalizerMethod, MappingReferences mappingReferences, - List subclassMappings) { + List subclassMappings, + List methodAnnotations + ) { super( method, existingVariableNames, @@ -1725,7 +1770,7 @@ private BeanMappingMethod(Method method, this.returnTypeBuilder = returnTypeBuilder; this.finalizerMethod = finalizerMethod; this.mappingReferences = mappingReferences; - + this.methodAnnotations = methodAnnotations; // intialize constant mappings as all mappings, but take out the ones that can be contributed to a // parameter mapping. this.mappingsByParameter = new HashMap<>(); @@ -1817,16 +1862,22 @@ public Set getImportTypes() { types.addAll( subclassMapping.getImportTypes() ); } + for (Annotation methodAnnotation : methodAnnotations) { + types.addAll(methodAnnotation.getImportTypes()); + } if ( returnTypeToConstruct != null ) { types.addAll( returnTypeToConstruct.getImportTypes() ); } if ( returnTypeBuilder != null ) { types.add( returnTypeBuilder.getOwningType() ); } - return types; } + public List getMethodAnnotations() { + return methodAnnotations; + } + public List getSourceParametersExcludingPrimitives() { return getSourceParameters().stream() .filter( parameter -> !parameter.getType().isPrimitive() ) diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl index 12a03c06ca..aeab2df193 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl @@ -7,6 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.BeanMappingMethod" --> <#if overridden>@Override +<#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#assign targetType = resultType /> <#if !existingInstanceMapping> diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java new file mode 100644 index 0000000000..a1bd368022 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java @@ -0,0 +1,67 @@ +/* + * 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._2773; + +/** + * @author Sjaak Derksen + */ +public class ChartEntry { + + private String chartName; + private String songTitle; + private String artistName; + private String recordedAt; + private String city; + private int position; + + public String getChartName() { + return chartName; + } + + public void setChartName(String chartName) { + this.chartName = chartName; + } + + public String getSongTitle() { + return songTitle; + } + + public void setSongTitle(String songTitle) { + this.songTitle = songTitle; + } + + public String getArtistName() { + return artistName; + } + + public void setArtistName(String artistName) { + this.artistName = artistName; + } + + public String getRecordedAt() { + return recordedAt; + } + + public void setRecordedAt(String recordedAt) { + this.recordedAt = recordedAt; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public int getPosition() { + return position; + } + + public void setPosition(int position) { + this.position = position; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java new file mode 100644 index 0000000000..1a4fc1a6d2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java @@ -0,0 +1,26 @@ +package org.mapstruct.ap.test.bugs._2773; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2773Mapper { + + Issue2773Mapper INSTANCE = Mappers.getMapper(Issue2773Mapper.class); + + @Deprecated + @TestAnnotation(name = "hello", id = 1, address = {"shenzhen", "guangzhou"}) + @Mapping(target = "name", source = "chartEntry1.recordedAt") + @Mapping(target = "city", source = "chartEntry2.city") + Studio toStudio(ChartEntry chartEntry1, ChartEntry chartEntry2); + + + + @Mappings({ + @Mapping(target = "city",source = "city"), + @Mapping(target = "name",source = "recordedAt")} + ) + Studio map(ChartEntry chartEntry); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java new file mode 100644 index 0000000000..df5716c27a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -0,0 +1,36 @@ +package org.mapstruct.ap.test.bugs._2773; + + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import java.lang.reflect.Method; +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2773") +@WithClasses({ChartEntry.class,Issue2773Mapper.class,Studio.class,TestAnnotation.class}) +public class Issue2773Test { + + @ProcessorTest + public void shouldContainMethodAnnotations() throws NoSuchMethodException { + Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; + Class mapperClass = issue2773Mapper.getClass(); + Method toStudio = mapperClass.getMethod("toStudio", ChartEntry.class, ChartEntry.class); + assertThat(toStudio.getAnnotation(Deprecated.class)).isNotNull(); + assertThat(toStudio.getAnnotation(TestAnnotation.class)).isNotNull(); + } + + @ProcessorTest + public void shouldNotContainMethodAnnotations() throws NoSuchMethodException { + Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; + Class mapperClass = issue2773Mapper.getClass(); + Method toStudio = mapperClass.getMethod("toStudio", ChartEntry.class, ChartEntry.class); + Method map = mapperClass.getMethod("map", ChartEntry.class); + assertThat(toStudio.getAnnotation(Mapping.class)).isNull(); + assertThat(map.getAnnotation(Mappings.class)).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java new file mode 100644 index 0000000000..3cff59a213 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java @@ -0,0 +1,31 @@ +/* + * 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._2773; + +/** + * @author Sjaak Derksen + */ +public class Studio { + + private String city; + private String name; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java new file mode 100644 index 0000000000..22ff4879f6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java @@ -0,0 +1,17 @@ +package org.mapstruct.ap.test.bugs._2773; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface TestAnnotation { + + int id(); + + String name(); + + String[] address(); +} From 6eeaff8c8c9e41b496eb577f1d3d7dd25bfd3e38 Mon Sep 17 00:00:00 2001 From: orange add <771240658@qq.com> Date: Wed, 17 Aug 2022 14:27:42 +0800 Subject: [PATCH 02/15] feat: Add method annotation copy supporting IterableMapping,MapMapping, StreamMapping --- .../ap/internal/model/BeanMappingMethod.java | 53 ++------------- .../ap/internal/model/MappingMethod.java | 68 ++++++++++++++++--- .../internal/model/source/SourceMethod.java | 4 ++ .../internal/model/IterableMappingMethod.ftl | 3 + .../ap/internal/model/MapMappingMethod.ftl | 3 + .../ap/internal/model/StreamMappingMethod.ftl | 3 + .../ap/test/bugs/_2773/Issue2773Mapper.java | 22 +++++- .../ap/test/bugs/_2773/Issue2773Test.java | 10 +++ 8 files changed, 103 insertions(+), 63 deletions(-) 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 42fbbeccc2..d02b6abf48 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 @@ -95,7 +95,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { private final MappingReferences mappingReferences; - private final List methodAnnotations; + public static class Builder extends AbstractMappingMethodBuilder { @@ -359,7 +359,7 @@ else if ( !method.isUpdateMethod() ) { finalizeMethod = getFinalizerMethod(); } - List methodAnnotations = getSourceMethodAnnotations(); + return new BeanMappingMethod( method, @@ -373,8 +373,7 @@ else if ( !method.isUpdateMethod() ) { afterMappingMethods, finalizeMethod, mappingReferences, - subclasses, - methodAnnotations + subclasses ); } @@ -1690,42 +1689,7 @@ private void reportErrorForUnusedSourceParameters() { } } - /** - * Get annotations for non-mapstruct frameworks in methods - * - * @return annotations - */ - private List getSourceMethodAnnotations(){ - List annotationTypes = new ArrayList<>(); - if (method instanceof SourceMethod) { - SourceMethod sourceMethod = (SourceMethod) method; - List annotationMirrors = sourceMethod.getExecutable().getAnnotationMirrors(); - TypeFactory typeFactory = this.ctx.getTypeFactory(); - for (AnnotationMirror annotationMirror : annotationMirrors) { - Type type = typeFactory.getType(annotationMirror.getAnnotationType()); - if (isInternalAnnotation(type)){ - continue; - } - Map elementValues = annotationMirror.getElementValues(); - if (elementValues.isEmpty()){ - annotationTypes.add(new Annotation(type)); - continue; - } - List properties = new ArrayList<>(); - for (Entry entry : elementValues.entrySet()) { - ExecutableElement key = entry.getKey(); - AnnotationValue value = entry.getValue(); - properties.add(key.getSimpleName().toString()+" = "+value.toString()); - } - annotationTypes.add(new Annotation(type,properties)); - } - } - return annotationTypes; - } - private boolean isInternalAnnotation(Type type){ - return type.getPackageName().equalsIgnoreCase("org.mapstruct"); - } } @@ -1753,9 +1717,7 @@ private BeanMappingMethod(Method method, List afterMappingReferences, MethodReference finalizerMethod, MappingReferences mappingReferences, - List subclassMappings, - List methodAnnotations - ) { + List subclassMappings) { super( method, existingVariableNames, @@ -1770,7 +1732,6 @@ private BeanMappingMethod(Method method, this.returnTypeBuilder = returnTypeBuilder; this.finalizerMethod = finalizerMethod; this.mappingReferences = mappingReferences; - this.methodAnnotations = methodAnnotations; // intialize constant mappings as all mappings, but take out the ones that can be contributed to a // parameter mapping. this.mappingsByParameter = new HashMap<>(); @@ -1862,9 +1823,6 @@ public Set getImportTypes() { types.addAll( subclassMapping.getImportTypes() ); } - for (Annotation methodAnnotation : methodAnnotations) { - types.addAll(methodAnnotation.getImportTypes()); - } if ( returnTypeToConstruct != null ) { types.addAll( returnTypeToConstruct.getImportTypes() ); } @@ -1874,9 +1832,6 @@ public Set getImportTypes() { return types; } - public List getMethodAnnotations() { - return methodAnnotations; - } public List getSourceParametersExcludingPrimitives() { return getSourceParameters().stream() diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java index c7d329916f..0ccadd1665 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java @@ -8,18 +8,15 @@ import static org.mapstruct.ap.internal.util.Strings.getSafeVariableName; import static org.mapstruct.ap.internal.util.Strings.join; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import org.mapstruct.ap.internal.model.common.Accessibility; -import org.mapstruct.ap.internal.model.common.ModelElement; -import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.common.Type; +import java.util.*; + +import org.mapstruct.ap.internal.model.common.*; import org.mapstruct.ap.internal.model.source.Method; +import org.mapstruct.ap.internal.model.source.SourceMethod; + +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.ExecutableElement; /** * A method implemented or referenced by a {@link Mapper} class. @@ -41,6 +38,8 @@ public abstract class MappingMethod extends ModelElement { private final List beforeMappingReferencesWithoutMappingTarget; private final List afterMappingReferences; + private final List methodAnnotations; + /** * constructor to be overloaded when local variable names are required prior to calling this constructor. (e.g. for * property mappings). It is supposed to be initialized with at least the parameter names. @@ -71,6 +70,7 @@ protected MappingMethod(Method method, List parameters, Collection parameters) { @@ -153,6 +153,10 @@ public Set getImportTypes() { types.addAll( type.getImportTypes() ); } + for (Annotation methodAnnotation : methodAnnotations) { + types.addAll(methodAnnotation.getImportTypes()); + } + return types; } @@ -205,6 +209,48 @@ public List getBeforeMappingReferencesWithoutM return beforeMappingReferencesWithoutMappingTarget; } + public List getMethodAnnotations() { + return methodAnnotations; + } + + /** + * Get annotations for non-mapstruct frameworks in methods + * + * @return annotations + */ + private List getSourceMethodAnnotations(Method method){ + List annotationTypes = new ArrayList<>(); + if (method instanceof SourceMethod) { + SourceMethod sourceMethod = (SourceMethod) method; + List annotationMirrors = sourceMethod.getExecutable().getAnnotationMirrors(); + TypeFactory typeFactory = sourceMethod.getTypeFactory(); + for (AnnotationMirror annotationMirror : annotationMirrors) { + Type type = typeFactory.getType(annotationMirror.getAnnotationType()); + if (isInternalAnnotation(type)){ + continue; + } + Map elementValues = annotationMirror.getElementValues(); + if (elementValues.isEmpty()){ + annotationTypes.add(new Annotation(type)); + continue; + } + List properties = new ArrayList<>(); + for (Map.Entry entry : elementValues.entrySet()) { + ExecutableElement key = entry.getKey(); + AnnotationValue value = entry.getValue(); + properties.add(key.getSimpleName().toString()+" = "+value.toString()); + } + annotationTypes.add(new Annotation(type,properties)); + } + } + return annotationTypes; + } + + private boolean isInternalAnnotation(Type type){ + return type.getPackageName().equalsIgnoreCase("org.mapstruct"); + } + + @Override public int hashCode() { int hash = 7; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java index 5895ecba2a..852f4c3cc3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java @@ -340,6 +340,10 @@ public Accessibility getAccessibility() { return accessibility; } + public TypeFactory getTypeFactory() { + return typeFactory; + } + public boolean inverses(SourceMethod method) { return method.getDeclaringMapper() == null && method.isAbstract() diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl index 3af75079b9..82b5b8ae00 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl @@ -7,6 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableMappingMethod" --> <#if overridden>@Override +<#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl index 1c6e6bad35..a4e43dfe36 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl @@ -7,6 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MapMappingMethod" --> <#if overridden>@Override +<#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl index ae48a3477a..b3a40c45e5 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl @@ -7,6 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.StreamMappingMethod" --> <#if overridden>@Override +<#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#--TODO does it even make sense to do a callback if the result is a Stream, as they are immutable--> <#list beforeMappingReferencesWithoutMappingTarget as callback> diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java index 1a4fc1a6d2..ad32b613f1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java @@ -1,10 +1,14 @@ package org.mapstruct.ap.test.bugs._2773; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; +import org.mapstruct.*; import org.mapstruct.factory.Mappers; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + @Mapper public interface Issue2773Mapper { @@ -23,4 +27,16 @@ public interface Issue2773Mapper { @Mapping(target = "name",source = "recordedAt")} ) Studio map(ChartEntry chartEntry); + + @Deprecated + @IterableMapping(numberFormat = "$#.00") + List prices(List prices); + + @Deprecated + Set integerStreamToStringSet(Stream integers); + + @Deprecated + @MapMapping(valueDateFormat = "dd.MM.yyyy") + Map longDateMapToStringStringMap(Map source); + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java index df5716c27a..4cfb84be5f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -9,6 +9,10 @@ import org.mapstruct.ap.testutil.WithClasses; import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + import static org.assertj.core.api.Assertions.assertThat; @IssueKey("2773") @@ -20,8 +24,14 @@ public void shouldContainMethodAnnotations() throws NoSuchMethodException { Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; Class mapperClass = issue2773Mapper.getClass(); Method toStudio = mapperClass.getMethod("toStudio", ChartEntry.class, ChartEntry.class); + Method prices = mapperClass.getMethod("prices", List.class); + Method integerStreamToStringSet = mapperClass.getMethod("integerStreamToStringSet", Stream.class); + Method longDateMapToStringStringMap = mapperClass.getMethod("longDateMapToStringStringMap", Map.class); assertThat(toStudio.getAnnotation(Deprecated.class)).isNotNull(); assertThat(toStudio.getAnnotation(TestAnnotation.class)).isNotNull(); + assertThat(prices.getAnnotation(Deprecated.class)).isNotNull(); + assertThat(integerStreamToStringSet.getAnnotation(Deprecated.class)).isNotNull(); + assertThat(longDateMapToStringStringMap.getAnnotation(Deprecated.class)).isNotNull(); } @ProcessorTest From 0fb88568eb74fd8a5a86beb5c704717e61d283c7 Mon Sep 17 00:00:00 2001 From: orange add <771240658@qq.com> Date: Tue, 16 Aug 2022 15:24:05 +0800 Subject: [PATCH 03/15] feat: Copy the method annotation to the implementation method --- .../ap/internal/model/BeanMappingMethod.java | 59 ++++++++++++++-- .../ap/internal/model/BeanMappingMethod.ftl | 3 + .../ap/test/bugs/_2773/ChartEntry.java | 67 +++++++++++++++++++ .../ap/test/bugs/_2773/Issue2773Mapper.java | 26 +++++++ .../ap/test/bugs/_2773/Issue2773Test.java | 36 ++++++++++ .../mapstruct/ap/test/bugs/_2773/Studio.java | 31 +++++++++ .../ap/test/bugs/_2773/TestAnnotation.java | 17 +++++ 7 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.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 e748c173af..1f28ae53cc 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 @@ -98,6 +98,8 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { private final MappingReferences mappingReferences; + private final List methodAnnotations; + public static class Builder extends AbstractMappingMethodBuilder { private Type userDefinedReturnType; @@ -368,6 +370,8 @@ else if ( !method.isUpdateMethod() ) { finalizeMethod = getFinalizerMethod(); } + List methodAnnotations = getSourceMethodAnnotations(); + return new BeanMappingMethod( method, annotations, @@ -381,7 +385,8 @@ else if ( !method.isUpdateMethod() ) { afterMappingMethods, finalizeMethod, mappingReferences, - subclasses + subclasses, + methodAnnotations ); } @@ -1694,6 +1699,44 @@ private void reportErrorForUnusedSourceParameters() { } } } + + /** + * Get annotations for non-mapstruct frameworks in methods + * + * @return annotations + */ + private List getSourceMethodAnnotations(){ + List annotationTypes = new ArrayList<>(); + if (method instanceof SourceMethod) { + SourceMethod sourceMethod = (SourceMethod) method; + List annotationMirrors = sourceMethod.getExecutable().getAnnotationMirrors(); + TypeFactory typeFactory = this.ctx.getTypeFactory(); + for (AnnotationMirror annotationMirror : annotationMirrors) { + Type type = typeFactory.getType(annotationMirror.getAnnotationType()); + if (isInternalAnnotation(type)){ + continue; + } + Map elementValues = annotationMirror.getElementValues(); + if (elementValues.isEmpty()){ + annotationTypes.add(new Annotation(type)); + continue; + } + List properties = new ArrayList<>(); + for (Entry entry : elementValues.entrySet()) { + ExecutableElement key = entry.getKey(); + AnnotationValue value = entry.getValue(); + properties.add(key.getSimpleName().toString()+" = "+value.toString()); + } + annotationTypes.add(new Annotation(type,properties)); + } + } + return annotationTypes; + } + + private boolean isInternalAnnotation(Type type){ + return type.getPackageName().equalsIgnoreCase("org.mapstruct"); + } + } private static class ConstructorAccessor { @@ -1721,7 +1764,9 @@ private BeanMappingMethod(Method method, List afterMappingReferences, MethodReference finalizerMethod, MappingReferences mappingReferences, - List subclassMappings) { + List subclassMappings, + List methodAnnotations + ) { super( method, existingVariableNames, @@ -1737,7 +1782,7 @@ private BeanMappingMethod(Method method, this.returnTypeBuilder = returnTypeBuilder; this.finalizerMethod = finalizerMethod; this.mappingReferences = mappingReferences; - + this.methodAnnotations = methodAnnotations; // intialize constant mappings as all mappings, but take out the ones that can be contributed to a // parameter mapping. this.mappingsByParameter = new HashMap<>(); @@ -1833,16 +1878,22 @@ public Set getImportTypes() { types.addAll( subclassMapping.getImportTypes() ); } + for (Annotation methodAnnotation : methodAnnotations) { + types.addAll(methodAnnotation.getImportTypes()); + } if ( returnTypeToConstruct != null ) { types.addAll( returnTypeToConstruct.getImportTypes() ); } if ( returnTypeBuilder != null ) { types.add( returnTypeBuilder.getOwningType() ); } - return types; } + public List getMethodAnnotations() { + return methodAnnotations; + } + public List getSourceParametersExcludingPrimitives() { return getSourceParameters().stream() .filter( parameter -> !parameter.getType().isPrimitive() ) diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl index 1b402a57f0..dcf8711eda 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl @@ -10,6 +10,9 @@ <#nt><@includeModel object=annotation/> <#if overridden>@Override +<#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#assign targetType = resultType /> <#if !existingInstanceMapping> diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java new file mode 100644 index 0000000000..a1bd368022 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java @@ -0,0 +1,67 @@ +/* + * 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._2773; + +/** + * @author Sjaak Derksen + */ +public class ChartEntry { + + private String chartName; + private String songTitle; + private String artistName; + private String recordedAt; + private String city; + private int position; + + public String getChartName() { + return chartName; + } + + public void setChartName(String chartName) { + this.chartName = chartName; + } + + public String getSongTitle() { + return songTitle; + } + + public void setSongTitle(String songTitle) { + this.songTitle = songTitle; + } + + public String getArtistName() { + return artistName; + } + + public void setArtistName(String artistName) { + this.artistName = artistName; + } + + public String getRecordedAt() { + return recordedAt; + } + + public void setRecordedAt(String recordedAt) { + this.recordedAt = recordedAt; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public int getPosition() { + return position; + } + + public void setPosition(int position) { + this.position = position; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java new file mode 100644 index 0000000000..1a4fc1a6d2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java @@ -0,0 +1,26 @@ +package org.mapstruct.ap.test.bugs._2773; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2773Mapper { + + Issue2773Mapper INSTANCE = Mappers.getMapper(Issue2773Mapper.class); + + @Deprecated + @TestAnnotation(name = "hello", id = 1, address = {"shenzhen", "guangzhou"}) + @Mapping(target = "name", source = "chartEntry1.recordedAt") + @Mapping(target = "city", source = "chartEntry2.city") + Studio toStudio(ChartEntry chartEntry1, ChartEntry chartEntry2); + + + + @Mappings({ + @Mapping(target = "city",source = "city"), + @Mapping(target = "name",source = "recordedAt")} + ) + Studio map(ChartEntry chartEntry); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java new file mode 100644 index 0000000000..df5716c27a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -0,0 +1,36 @@ +package org.mapstruct.ap.test.bugs._2773; + + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import java.lang.reflect.Method; +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2773") +@WithClasses({ChartEntry.class,Issue2773Mapper.class,Studio.class,TestAnnotation.class}) +public class Issue2773Test { + + @ProcessorTest + public void shouldContainMethodAnnotations() throws NoSuchMethodException { + Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; + Class mapperClass = issue2773Mapper.getClass(); + Method toStudio = mapperClass.getMethod("toStudio", ChartEntry.class, ChartEntry.class); + assertThat(toStudio.getAnnotation(Deprecated.class)).isNotNull(); + assertThat(toStudio.getAnnotation(TestAnnotation.class)).isNotNull(); + } + + @ProcessorTest + public void shouldNotContainMethodAnnotations() throws NoSuchMethodException { + Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; + Class mapperClass = issue2773Mapper.getClass(); + Method toStudio = mapperClass.getMethod("toStudio", ChartEntry.class, ChartEntry.class); + Method map = mapperClass.getMethod("map", ChartEntry.class); + assertThat(toStudio.getAnnotation(Mapping.class)).isNull(); + assertThat(map.getAnnotation(Mappings.class)).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java new file mode 100644 index 0000000000..3cff59a213 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java @@ -0,0 +1,31 @@ +/* + * 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._2773; + +/** + * @author Sjaak Derksen + */ +public class Studio { + + private String city; + private String name; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java new file mode 100644 index 0000000000..22ff4879f6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java @@ -0,0 +1,17 @@ +package org.mapstruct.ap.test.bugs._2773; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface TestAnnotation { + + int id(); + + String name(); + + String[] address(); +} From e1d19a5b17c86396f23a8e08211e18699151a37a Mon Sep 17 00:00:00 2001 From: orange add <771240658@qq.com> Date: Wed, 17 Aug 2022 14:27:42 +0800 Subject: [PATCH 04/15] feat: Add method annotation copy supporting IterableMapping,MapMapping, StreamMapping --- .../ap/internal/model/BeanMappingMethod.java | 53 ++----------------- .../internal/model/source/SourceMethod.java | 4 ++ .../internal/model/IterableMappingMethod.ftl | 3 ++ .../ap/internal/model/MapMappingMethod.ftl | 3 ++ .../ap/internal/model/StreamMappingMethod.ftl | 3 ++ .../ap/test/bugs/_2773/Issue2773Mapper.java | 22 ++++++-- .../ap/test/bugs/_2773/Issue2773Test.java | 10 ++++ 7 files changed, 46 insertions(+), 52 deletions(-) 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 1f28ae53cc..b88bcd0519 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 @@ -98,7 +98,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { private final MappingReferences mappingReferences; - private final List methodAnnotations; + public static class Builder extends AbstractMappingMethodBuilder { @@ -370,7 +370,7 @@ else if ( !method.isUpdateMethod() ) { finalizeMethod = getFinalizerMethod(); } - List methodAnnotations = getSourceMethodAnnotations(); + return new BeanMappingMethod( method, @@ -385,8 +385,7 @@ else if ( !method.isUpdateMethod() ) { afterMappingMethods, finalizeMethod, mappingReferences, - subclasses, - methodAnnotations + subclasses ); } @@ -1700,42 +1699,7 @@ private void reportErrorForUnusedSourceParameters() { } } - /** - * Get annotations for non-mapstruct frameworks in methods - * - * @return annotations - */ - private List getSourceMethodAnnotations(){ - List annotationTypes = new ArrayList<>(); - if (method instanceof SourceMethod) { - SourceMethod sourceMethod = (SourceMethod) method; - List annotationMirrors = sourceMethod.getExecutable().getAnnotationMirrors(); - TypeFactory typeFactory = this.ctx.getTypeFactory(); - for (AnnotationMirror annotationMirror : annotationMirrors) { - Type type = typeFactory.getType(annotationMirror.getAnnotationType()); - if (isInternalAnnotation(type)){ - continue; - } - Map elementValues = annotationMirror.getElementValues(); - if (elementValues.isEmpty()){ - annotationTypes.add(new Annotation(type)); - continue; - } - List properties = new ArrayList<>(); - for (Entry entry : elementValues.entrySet()) { - ExecutableElement key = entry.getKey(); - AnnotationValue value = entry.getValue(); - properties.add(key.getSimpleName().toString()+" = "+value.toString()); - } - annotationTypes.add(new Annotation(type,properties)); - } - } - return annotationTypes; - } - private boolean isInternalAnnotation(Type type){ - return type.getPackageName().equalsIgnoreCase("org.mapstruct"); - } } @@ -1764,9 +1728,7 @@ private BeanMappingMethod(Method method, List afterMappingReferences, MethodReference finalizerMethod, MappingReferences mappingReferences, - List subclassMappings, - List methodAnnotations - ) { + List subclassMappings) { super( method, existingVariableNames, @@ -1782,7 +1744,6 @@ private BeanMappingMethod(Method method, this.returnTypeBuilder = returnTypeBuilder; this.finalizerMethod = finalizerMethod; this.mappingReferences = mappingReferences; - this.methodAnnotations = methodAnnotations; // intialize constant mappings as all mappings, but take out the ones that can be contributed to a // parameter mapping. this.mappingsByParameter = new HashMap<>(); @@ -1878,9 +1839,6 @@ public Set getImportTypes() { types.addAll( subclassMapping.getImportTypes() ); } - for (Annotation methodAnnotation : methodAnnotations) { - types.addAll(methodAnnotation.getImportTypes()); - } if ( returnTypeToConstruct != null ) { types.addAll( returnTypeToConstruct.getImportTypes() ); } @@ -1890,9 +1848,6 @@ public Set getImportTypes() { return types; } - public List getMethodAnnotations() { - return methodAnnotations; - } public List getSourceParametersExcludingPrimitives() { return getSourceParameters().stream() diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java index 37b57d9025..82f7acc695 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java @@ -349,6 +349,10 @@ public Accessibility getAccessibility() { return accessibility; } + public TypeFactory getTypeFactory() { + return typeFactory; + } + public boolean inverses(SourceMethod method) { return method.getDeclaringMapper() == null && method.isAbstract() diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl index 495111b7a1..6d2f1861f2 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl @@ -7,6 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableMappingMethod" --> <#if overridden>@Override +<#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl index 443d87cba7..c8a4c811f1 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl @@ -7,6 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MapMappingMethod" --> <#if overridden>@Override +<#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl index 860859fc3a..29e47a74a5 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl @@ -7,6 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.StreamMappingMethod" --> <#if overridden>@Override +<#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#--TODO does it even make sense to do a callback if the result is a Stream, as they are immutable--> <#list beforeMappingReferencesWithoutMappingTarget as callback> diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java index 1a4fc1a6d2..ad32b613f1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java @@ -1,10 +1,14 @@ package org.mapstruct.ap.test.bugs._2773; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; +import org.mapstruct.*; import org.mapstruct.factory.Mappers; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + @Mapper public interface Issue2773Mapper { @@ -23,4 +27,16 @@ public interface Issue2773Mapper { @Mapping(target = "name",source = "recordedAt")} ) Studio map(ChartEntry chartEntry); + + @Deprecated + @IterableMapping(numberFormat = "$#.00") + List prices(List prices); + + @Deprecated + Set integerStreamToStringSet(Stream integers); + + @Deprecated + @MapMapping(valueDateFormat = "dd.MM.yyyy") + Map longDateMapToStringStringMap(Map source); + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java index df5716c27a..4cfb84be5f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -9,6 +9,10 @@ import org.mapstruct.ap.testutil.WithClasses; import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + import static org.assertj.core.api.Assertions.assertThat; @IssueKey("2773") @@ -20,8 +24,14 @@ public void shouldContainMethodAnnotations() throws NoSuchMethodException { Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; Class mapperClass = issue2773Mapper.getClass(); Method toStudio = mapperClass.getMethod("toStudio", ChartEntry.class, ChartEntry.class); + Method prices = mapperClass.getMethod("prices", List.class); + Method integerStreamToStringSet = mapperClass.getMethod("integerStreamToStringSet", Stream.class); + Method longDateMapToStringStringMap = mapperClass.getMethod("longDateMapToStringStringMap", Map.class); assertThat(toStudio.getAnnotation(Deprecated.class)).isNotNull(); assertThat(toStudio.getAnnotation(TestAnnotation.class)).isNotNull(); + assertThat(prices.getAnnotation(Deprecated.class)).isNotNull(); + assertThat(integerStreamToStringSet.getAnnotation(Deprecated.class)).isNotNull(); + assertThat(longDateMapToStringStringMap.getAnnotation(Deprecated.class)).isNotNull(); } @ProcessorTest From 9dc0f168187310a8bd3240862ea9c3f500f6ae52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=A2=93=E4=BD=B3?= <771240658@qq.com> Date: Sat, 20 Aug 2022 23:11:03 +0800 Subject: [PATCH 05/15] feat: Reimplement #2733 --- .../mapstruct/ap/internal/model/ForgedMethod.java | 5 +++++ .../mapstruct/ap/internal/model/HelperMethod.java | 5 +++++ .../ap/internal/model/NormalTypeMappingMethod.java | 8 ++++++++ .../mapstruct/ap/internal/model/source/Method.java | 7 +++++++ .../ap/internal/model/source/SourceMethod.java | 11 +++++++++++ .../internal/model/source/builtin/BuiltInMethod.java | 5 +++++ .../ap/internal/model/BeanMappingMethod.ftl | 4 +--- .../ap/internal/model/IterableMappingMethod.ftl | 4 +--- .../mapstruct/ap/internal/model/MapMappingMethod.ftl | 4 +--- .../ap/internal/model/StreamMappingMethod.ftl | 4 +--- .../ap/internal/model/ValueMappingMethod.ftl | 1 + .../mapstruct/ap/test/bugs/_2773/Issue2773Test.java | 12 +----------- 12 files changed, 47 insertions(+), 23 deletions(-) diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethod.java index a33bc7520e..b8bf827648 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethod.java @@ -328,6 +328,11 @@ public boolean overridesMethod() { return false; } + @Override + public boolean deprecatedMethod() { + return false; + } + @Override public ExecutableElement getExecutable() { return basedOn.getExecutable(); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/HelperMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/HelperMethod.java index 35b35aee73..410d412583 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/HelperMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/HelperMethod.java @@ -219,6 +219,11 @@ public boolean overridesMethod() { return false; } + @Override + public boolean deprecatedMethod() { + return false; + } + @Override public ExecutableElement getExecutable() { return null; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java index fcd8d70d52..7d17e5ef77 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java @@ -22,6 +22,9 @@ public abstract class NormalTypeMappingMethod extends MappingMethod { private final MethodReference factoryMethod; private final boolean overridden; + + private final boolean deprecated; + private final boolean mapNullToDefault; NormalTypeMappingMethod(Method method, Collection existingVariableNames, MethodReference factoryMethod, @@ -31,6 +34,7 @@ public abstract class NormalTypeMappingMethod extends MappingMethod { super( method, existingVariableNames, beforeMappingReferences, afterMappingReferences ); this.factoryMethod = factoryMethod; this.overridden = method.overridesMethod(); + this.deprecated = method.deprecatedMethod(); this.mapNullToDefault = mapNullToDefault; } @@ -56,6 +60,10 @@ public boolean isOverridden() { return overridden; } + public boolean isDeprecated() { + return deprecated; + } + public MethodReference getFactoryMethod() { return this.factoryMethod; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Method.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Method.java index 0c60f41364..c3a3441904 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Method.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Method.java @@ -148,6 +148,13 @@ default boolean isPresenceCheck() { */ boolean overridesMethod(); + + /** + * + * @return Returns true when the method is modified by @Deprecated + */ + boolean deprecatedMethod(); + ExecutableElement getExecutable(); /** diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java index 82f7acc695..dbaf890f7c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; @@ -519,6 +520,16 @@ public boolean overridesMethod() { return declaringMapper == null && executable.getModifiers().contains( Modifier.ABSTRACT ); } + @Override + public boolean deprecatedMethod() { + Type deprecatedType = typeFactory.getType(Deprecated.class); + return executable!=null && executable.getAnnotationMirrors() + .stream() + .map(annotationMirror -> getTypeFactory().getType(annotationMirror.getAnnotationType())) + .anyMatch(annotationType->deprecatedType.equals(annotationType)); + + } + @Override public boolean matches(List sourceTypes, Type targetType) { MethodMatcher matcher = new MethodMatcher( typeUtils, typeFactory, this ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMethod.java index f46b201576..a9eb84d4ac 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMethod.java @@ -233,6 +233,11 @@ public boolean overridesMethod() { return false; } + @Override + public boolean deprecatedMethod() { + return false; + } + @Override public ExecutableElement getExecutable() { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl index dcf8711eda..567b799720 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl @@ -10,9 +10,7 @@ <#nt><@includeModel object=annotation/> <#if overridden>@Override -<#list methodAnnotations as annotation> - <#nt><@includeModel object=annotation/> - +<#if deprecated>@Deprecated <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#assign targetType = resultType /> <#if !existingInstanceMapping> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl index 6d2f1861f2..7e6d556372 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl @@ -7,9 +7,7 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableMappingMethod" --> <#if overridden>@Override -<#list methodAnnotations as annotation> - <#nt><@includeModel object=annotation/> - +<#if deprecated>@Deprecated <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl index c8a4c811f1..13e8a9a687 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl @@ -7,9 +7,7 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MapMappingMethod" --> <#if overridden>@Override -<#list methodAnnotations as annotation> - <#nt><@includeModel object=annotation/> - +<#if deprecated>@Deprecated <#lt>${accessibility.keyword} <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl index 29e47a74a5..e153d8e3cf 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl @@ -7,9 +7,7 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.StreamMappingMethod" --> <#if overridden>@Override -<#list methodAnnotations as annotation> - <#nt><@includeModel object=annotation/> - +<#if deprecated>@Deprecated <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#--TODO does it even make sense to do a callback if the result is a Stream, as they are immutable--> <#list beforeMappingReferencesWithoutMappingTarget as callback> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl index 4d961c40af..86ce418508 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl @@ -7,6 +7,7 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.ValueMappingMethod" --> <#if overridden>@Override +<#if deprecated>@Deprecated <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, ) { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java index 4cfb84be5f..26c02681e6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -16,10 +16,10 @@ import static org.assertj.core.api.Assertions.assertThat; @IssueKey("2773") -@WithClasses({ChartEntry.class,Issue2773Mapper.class,Studio.class,TestAnnotation.class}) public class Issue2773Test { @ProcessorTest + @WithClasses({ChartEntry.class,Issue2773Mapper.class,Studio.class,TestAnnotation.class}) public void shouldContainMethodAnnotations() throws NoSuchMethodException { Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; Class mapperClass = issue2773Mapper.getClass(); @@ -28,19 +28,9 @@ public void shouldContainMethodAnnotations() throws NoSuchMethodException { Method integerStreamToStringSet = mapperClass.getMethod("integerStreamToStringSet", Stream.class); Method longDateMapToStringStringMap = mapperClass.getMethod("longDateMapToStringStringMap", Map.class); assertThat(toStudio.getAnnotation(Deprecated.class)).isNotNull(); - assertThat(toStudio.getAnnotation(TestAnnotation.class)).isNotNull(); assertThat(prices.getAnnotation(Deprecated.class)).isNotNull(); assertThat(integerStreamToStringSet.getAnnotation(Deprecated.class)).isNotNull(); assertThat(longDateMapToStringStringMap.getAnnotation(Deprecated.class)).isNotNull(); } - @ProcessorTest - public void shouldNotContainMethodAnnotations() throws NoSuchMethodException { - Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; - Class mapperClass = issue2773Mapper.getClass(); - Method toStudio = mapperClass.getMethod("toStudio", ChartEntry.class, ChartEntry.class); - Method map = mapperClass.getMethod("map", ChartEntry.class); - assertThat(toStudio.getAnnotation(Mapping.class)).isNull(); - assertThat(map.getAnnotation(Mappings.class)).isNull(); - } } From 042a034fa66545681631b7f342ae63ca9f64c4bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=A2=93=E4=BD=B3?= <771240658@qq.com> Date: Sat, 20 Aug 2022 23:46:11 +0800 Subject: [PATCH 06/15] fix bug --- .../org/mapstruct/ap/internal/model/ValueMappingMethod.ftl | 1 - 1 file changed, 1 deletion(-) diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl index 86ce418508..4d961c40af 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl @@ -7,7 +7,6 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.ValueMappingMethod" --> <#if overridden>@Override -<#if deprecated>@Deprecated <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, ) { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> From e4d7125ea790b114fdd3f08d50fe99089b21d6ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=A2=93=E4=BD=B3?= <771240658@qq.com> Date: Sun, 21 Aug 2022 10:02:20 +0800 Subject: [PATCH 07/15] fix: Adjust if statements to avoid printing useless newlines --- .../org/mapstruct/ap/internal/model/BeanMappingMethod.ftl | 4 +++- .../org/mapstruct/ap/internal/model/IterableMappingMethod.ftl | 4 +++- .../org/mapstruct/ap/internal/model/MapMappingMethod.ftl | 4 +++- .../org/mapstruct/ap/internal/model/StreamMappingMethod.ftl | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl index 567b799720..0533529d92 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl @@ -10,7 +10,9 @@ <#nt><@includeModel object=annotation/> <#if overridden>@Override -<#if deprecated>@Deprecated +<#if deprecated> + @Deprecated + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#assign targetType = resultType /> <#if !existingInstanceMapping> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl index 7e6d556372..b2db945363 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl @@ -7,7 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableMappingMethod" --> <#if overridden>@Override -<#if deprecated>@Deprecated +<#if deprecated> + @Deprecated + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl index 13e8a9a687..d3b1e6fd4d 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl @@ -7,7 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MapMappingMethod" --> <#if overridden>@Override -<#if deprecated>@Deprecated +<#if deprecated> + @Deprecated + <#lt>${accessibility.keyword} <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl index e153d8e3cf..d40b0f35a8 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl @@ -7,7 +7,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.StreamMappingMethod" --> <#if overridden>@Override -<#if deprecated>@Deprecated +<#if deprecated> + @Deprecated + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#--TODO does it even make sense to do a callback if the result is a Stream, as they are immutable--> <#list beforeMappingReferencesWithoutMappingTarget as callback> From fc5495a0cdcfcb280d8ddafb6d8e3f3144a85366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=A2=93=E4=BD=B3?= <771240658@qq.com> Date: Sun, 21 Aug 2022 10:40:49 +0800 Subject: [PATCH 08/15] adjust unit test --- .../annotationnotfound/AnnotationNotFoundTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java index 8a5ffefe6d..268efbd383 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java @@ -30,7 +30,11 @@ public class AnnotationNotFoundTest { @Diagnostic( type = ErroneousMapper.class, kind = Kind.ERROR, line = 17, - messageRegExp = "NotFoundAnnotation") + messageRegExp = "NotFoundAnnotation"), + @Diagnostic(type = ErroneousMapper.class, + kind = Kind.ERROR, + line = 15 + ) } ) public void shouldFailToGenerateMappings() { From 92288c4ee578830f278ecc3e9e054fa24576828b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=A2=93=E4=BD=B3?= <771240658@qq.com> Date: Sun, 21 Aug 2022 10:55:55 +0800 Subject: [PATCH 09/15] docs: add license --- .../java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java | 2 +- .../org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java | 4 +++- .../java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java | 3 +++ .../test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java | 2 +- .../java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java | 4 +++- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java index a1bd368022..27fd59a6f7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/ChartEntry.java @@ -6,7 +6,7 @@ package org.mapstruct.ap.test.bugs._2773; /** - * @author Sjaak Derksen + * @author orange add */ public class ChartEntry { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java index ad32b613f1..1bff9f68ca 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java @@ -8,7 +8,9 @@ import java.util.Map; import java.util.Set; import java.util.stream.Stream; - +/** + * @author orange add + */ @Mapper public interface Issue2773Mapper { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java index 26c02681e6..63f677df1a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -15,6 +15,9 @@ import static org.assertj.core.api.Assertions.assertThat; +/** + * @author orange add + */ @IssueKey("2773") public class Issue2773Test { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java index 3cff59a213..9ade71f47d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Studio.java @@ -6,7 +6,7 @@ package org.mapstruct.ap.test.bugs._2773; /** - * @author Sjaak Derksen + * @author orange add */ public class Studio { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java index 22ff4879f6..9d428c3263 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java @@ -4,7 +4,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - +/** + * @author orange add + */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { From 2db350d0c287c8a3f881b273003b9b2fc82fec37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=A2=93=E4=BD=B3?= <771240658@qq.com> Date: Sun, 21 Aug 2022 11:15:31 +0800 Subject: [PATCH 10/15] docs: add header license --- processor/pom.xml | 2 ++ .../org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java | 5 +++++ .../java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java | 5 +++++ .../org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java | 5 +++++ 4 files changed, 17 insertions(+) diff --git a/processor/pom.xml b/processor/pom.xml index 6f2bb6495c..a4aa6ad1ab 100644 --- a/processor/pom.xml +++ b/processor/pom.xml @@ -282,6 +282,8 @@ + 9 + 9 diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java index 1bff9f68ca..8f0091d689 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java @@ -1,3 +1,8 @@ +/* + * 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._2773; import org.mapstruct.*; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java index 63f677df1a..f8435b8824 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -1,3 +1,8 @@ +/* + * 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._2773; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java index 9d428c3263..bacb960c03 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java @@ -1,3 +1,8 @@ +/* + * 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._2773; import java.lang.annotation.ElementType; From 73d6e0cdb312c45cbf3477789bd299fcff148212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=A2=93=E4=BD=B3?= <771240658@qq.com> Date: Sun, 21 Aug 2022 11:58:03 +0800 Subject: [PATCH 11/15] docs: checkstyle --- .../ap/internal/model/BeanMappingMethod.java | 10 --------- .../internal/model/source/SourceMethod.java | 9 ++++---- .../ap/test/bugs/_2773/Issue2773Mapper.java | 17 +++++++------- .../ap/test/bugs/_2773/Issue2773Test.java | 22 ++++++++----------- .../ap/test/bugs/_2773/TestAnnotation.java | 1 + 5 files changed, 23 insertions(+), 36 deletions(-) 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 b88bcd0519..e1b39ae7b0 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 @@ -95,15 +95,10 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { private final Type returnTypeToConstruct; private final BuilderType returnTypeBuilder; private final MethodReference finalizerMethod; - private final MappingReferences mappingReferences; - - public static class Builder extends AbstractMappingMethodBuilder { - private Type userDefinedReturnType; - /* returnType to construct can have a builder */ private BuilderType returnTypeBuilder; private Map unprocessedConstructorProperties; @@ -116,7 +111,6 @@ public static class Builder extends AbstractMappingMethodBuilder existingVariableNames = new HashSet<>(); private final Map> unprocessedDefinedTargets = new LinkedHashMap<>(); private final List annotations = new ArrayList<>(); - private MappingReferences mappingReferences; private MethodReference factoryMethod; private boolean hasFactoryMethod; @@ -1698,9 +1692,6 @@ private void reportErrorForUnusedSourceParameters() { } } } - - - } private static class ConstructorAccessor { @@ -1848,7 +1839,6 @@ public Set getImportTypes() { return types; } - public List getSourceParametersExcludingPrimitives() { return getSourceParameters().stream() .filter( parameter -> !parameter.getType().isPrimitive() ) diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java index dbaf890f7c..34da8d7f98 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java @@ -11,7 +11,6 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; @@ -522,11 +521,11 @@ public boolean overridesMethod() { @Override public boolean deprecatedMethod() { - Type deprecatedType = typeFactory.getType(Deprecated.class); - return executable!=null && executable.getAnnotationMirrors() + Type deprecatedType = typeFactory.getType( Deprecated.class ); + return executable != null && executable.getAnnotationMirrors() .stream() - .map(annotationMirror -> getTypeFactory().getType(annotationMirror.getAnnotationType())) - .anyMatch(annotationType->deprecatedType.equals(annotationType)); + .map( annotationMirror -> getTypeFactory().getType( annotationMirror.getAnnotationType() ) ) + .anyMatch( annotationType -> deprecatedType.equals( annotationType ) ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java index 8f0091d689..5dc19c81a0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java @@ -5,7 +5,11 @@ */ package org.mapstruct.ap.test.bugs._2773; -import org.mapstruct.*; +import org.mapstruct.IterableMapping; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; import java.util.Date; @@ -13,13 +17,15 @@ import java.util.Map; import java.util.Set; import java.util.stream.Stream; + /** * @author orange add */ + @Mapper public interface Issue2773Mapper { - Issue2773Mapper INSTANCE = Mappers.getMapper(Issue2773Mapper.class); + Issue2773Mapper INSTANCE = Mappers.getMapper( Issue2773Mapper.class ); @Deprecated @TestAnnotation(name = "hello", id = 1, address = {"shenzhen", "guangzhou"}) @@ -27,12 +33,7 @@ public interface Issue2773Mapper { @Mapping(target = "city", source = "chartEntry2.city") Studio toStudio(ChartEntry chartEntry1, ChartEntry chartEntry2); - - - @Mappings({ - @Mapping(target = "city",source = "city"), - @Mapping(target = "name",source = "recordedAt")} - ) + @Mappings({@Mapping(target = "city", source = "city"), @Mapping(target = "name", source = "recordedAt")}) Studio map(ChartEntry chartEntry); @Deprecated diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java index f8435b8824..14504cca42 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -5,10 +5,6 @@ */ package org.mapstruct.ap.test.bugs._2773; - -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; @@ -27,18 +23,18 @@ public class Issue2773Test { @ProcessorTest - @WithClasses({ChartEntry.class,Issue2773Mapper.class,Studio.class,TestAnnotation.class}) + @WithClasses({ChartEntry.class, Issue2773Mapper.class, Studio.class, TestAnnotation.class}) public void shouldContainMethodAnnotations() throws NoSuchMethodException { Issue2773Mapper issue2773Mapper = Issue2773Mapper.INSTANCE; Class mapperClass = issue2773Mapper.getClass(); - Method toStudio = mapperClass.getMethod("toStudio", ChartEntry.class, ChartEntry.class); - Method prices = mapperClass.getMethod("prices", List.class); - Method integerStreamToStringSet = mapperClass.getMethod("integerStreamToStringSet", Stream.class); - Method longDateMapToStringStringMap = mapperClass.getMethod("longDateMapToStringStringMap", Map.class); - assertThat(toStudio.getAnnotation(Deprecated.class)).isNotNull(); - assertThat(prices.getAnnotation(Deprecated.class)).isNotNull(); - assertThat(integerStreamToStringSet.getAnnotation(Deprecated.class)).isNotNull(); - assertThat(longDateMapToStringStringMap.getAnnotation(Deprecated.class)).isNotNull(); + Method toStudio = mapperClass.getMethod( "toStudio", ChartEntry.class, ChartEntry.class ); + Method prices = mapperClass.getMethod( "prices", List.class ); + Method integerStreamToStringSet = mapperClass.getMethod( "integerStreamToStringSet", Stream.class ); + Method longDateMapToStringStringMap = mapperClass.getMethod( "longDateMapToStringStringMap", Map.class ); + assertThat( toStudio.getAnnotation( Deprecated.class ) ).isNotNull(); + assertThat( prices.getAnnotation( Deprecated.class ) ).isNotNull(); + assertThat( integerStreamToStringSet.getAnnotation( Deprecated.class ) ).isNotNull(); + assertThat( longDateMapToStringStringMap.getAnnotation( Deprecated.class ) ).isNotNull(); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java index bacb960c03..bf6d8cc833 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/TestAnnotation.java @@ -12,6 +12,7 @@ /** * @author orange add */ + @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { From 13e95c720503fd58969d5befd0be7a5f508655cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=A2=93=E4=BD=B3?= <771240658@qq.com> Date: Sun, 21 Aug 2022 15:26:08 +0800 Subject: [PATCH 12/15] fix bug --- processor/pom.xml | 2 -- .../mapstruct/ap/internal/model/source/SourceMethod.java | 6 +++++- .../annotationnotfound/AnnotationNotFoundTest.java | 6 +----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/processor/pom.xml b/processor/pom.xml index a4aa6ad1ab..6f2bb6495c 100644 --- a/processor/pom.xml +++ b/processor/pom.xml @@ -282,8 +282,6 @@ - 9 - 9 diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java index 34da8d7f98..4233933bf1 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java @@ -11,9 +11,11 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; +import javax.lang.model.type.TypeKind; import org.mapstruct.ap.internal.gem.ConditionGem; import org.mapstruct.ap.internal.gem.ObjectFactoryGem; @@ -524,7 +526,9 @@ public boolean deprecatedMethod() { Type deprecatedType = typeFactory.getType( Deprecated.class ); return executable != null && executable.getAnnotationMirrors() .stream() - .map( annotationMirror -> getTypeFactory().getType( annotationMirror.getAnnotationType() ) ) + .map( AnnotationMirror::getAnnotationType ) + .filter( annotationType -> TypeKind.DECLARED == annotationType.getKind() ) + .map( typeFactory::getType ) .anyMatch( annotationType -> deprecatedType.equals( annotationType ) ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java index 268efbd383..8a5ffefe6d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java @@ -30,11 +30,7 @@ public class AnnotationNotFoundTest { @Diagnostic( type = ErroneousMapper.class, kind = Kind.ERROR, line = 17, - messageRegExp = "NotFoundAnnotation"), - @Diagnostic(type = ErroneousMapper.class, - kind = Kind.ERROR, - line = 15 - ) + messageRegExp = "NotFoundAnnotation") } ) public void shouldFailToGenerateMappings() { From 138ee37cec876134737a81aba8e7100e5146d550 Mon Sep 17 00:00:00 2001 From: orange add <771240658@qq.com> Date: Mon, 22 Aug 2022 16:09:49 +0800 Subject: [PATCH 13/15] feat: Support for implementing classes carrying the @Deprecated annotation --- .../main/java/org/mapstruct/ap/internal/model/Mapper.java | 6 +++++- .../org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java | 1 + .../org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java index 9b7729e8fa..62f2478985 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java @@ -155,7 +155,11 @@ private Mapper(TypeFactory typeFactory, String packageName, String name, this.customPackage = customPackage; this.customImplName = customImplName; customAnnotations.forEach( this::addAnnotation ); - + TypeElement typeElement = this.getMapperDefinitionType().getTypeElement(); + if ( typeElement.getAnnotation( Deprecated.class ) != null + && typeFactory.isTypeAvailable( Deprecated.class.getCanonicalName() )) { + addAnnotation( new Annotation(typeFactory.getType( Deprecated.class )) ); + } this.decorator = decorator; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java index 5dc19c81a0..ad470fa0ee 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Mapper.java @@ -23,6 +23,7 @@ */ @Mapper +@Deprecated public interface Issue2773Mapper { Issue2773Mapper INSTANCE = Mappers.getMapper( Issue2773Mapper.class ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java index 14504cca42..0b19447c55 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2773/Issue2773Test.java @@ -31,6 +31,7 @@ public void shouldContainMethodAnnotations() throws NoSuchMethodException { Method prices = mapperClass.getMethod( "prices", List.class ); Method integerStreamToStringSet = mapperClass.getMethod( "integerStreamToStringSet", Stream.class ); Method longDateMapToStringStringMap = mapperClass.getMethod( "longDateMapToStringStringMap", Map.class ); + assertThat( mapperClass.getAnnotation( Deprecated.class ) ).isNotNull(); assertThat( toStudio.getAnnotation( Deprecated.class ) ).isNotNull(); assertThat( prices.getAnnotation( Deprecated.class ) ).isNotNull(); assertThat( integerStreamToStringSet.getAnnotation( Deprecated.class ) ).isNotNull(); From 54d04444c80ee1b0bee0779a880b715ba8660722 Mon Sep 17 00:00:00 2001 From: orange add <771240658@qq.com> Date: Thu, 25 Aug 2022 14:12:45 +0800 Subject: [PATCH 14/15] feat: Remove redundant judgments and revert BeanMappingMethod change --- .../ap/internal/model/BeanMappingMethod.java | 880 +++++++++--------- .../mapstruct/ap/internal/model/Mapper.java | 3 +- 2 files changed, 443 insertions(+), 440 deletions(-) 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 e1b39ae7b0..bb61e44514 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 @@ -95,10 +95,13 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { private final Type returnTypeToConstruct; private final BuilderType returnTypeBuilder; private final MethodReference finalizerMethod; + private final MappingReferences mappingReferences; public static class Builder extends AbstractMappingMethodBuilder { + private Type userDefinedReturnType; + /* returnType to construct can have a builder */ private BuilderType returnTypeBuilder; private Map unprocessedConstructorProperties; @@ -111,6 +114,7 @@ public static class Builder extends AbstractMappingMethodBuilder existingVariableNames = new HashSet<>(); private final Map> unprocessedDefinedTargets = new LinkedHashMap<>(); private final List annotations = new ArrayList<>(); + private MappingReferences mappingReferences; private MethodReference factoryMethod; private boolean hasFactoryMethod; @@ -147,9 +151,9 @@ public Builder forgedMethod(ForgedMethod forgedMethod) { SourceReference sourceReference = mappingReference.getSourceReference(); if ( sourceReference != null ) { mappingReference.setSourceReference( new SourceReference.BuilderFromSourceReference() - .sourceParameter( sourceParameter ) - .sourceReference( sourceReference ) - .build() ); + .sourceParameter( sourceParameter ) + .sourceReference( sourceReference ) + .build() ); } } return this; @@ -176,8 +180,8 @@ public BeanMappingMethod build() { returnTypeImpl = returnTypeBuilder.getBuilder(); initializeFactoryMethod( returnTypeImpl, selectionParameters ); if ( factoryMethod != null - || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) - || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { + || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) + || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { returnTypeToConstruct = returnTypeImpl; } else { @@ -198,8 +202,8 @@ else if ( !method.isUpdateMethod() ) { returnTypeImpl = method.getReturnType(); initializeFactoryMethod( returnTypeImpl, selectionParameters ); if ( factoryMethod != null - || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) - || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { + || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) + || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { returnTypeToConstruct = returnTypeImpl; } else { @@ -213,10 +217,10 @@ else if ( !method.isUpdateMethod() ) { return null; } AdditionalAnnotationsBuilder additionalAnnotationsBuilder = - new AdditionalAnnotationsBuilder( - ctx.getElementUtils(), - ctx.getTypeFactory(), - ctx.getMessager() ); + new AdditionalAnnotationsBuilder( + ctx.getElementUtils(), + ctx.getTypeFactory(), + ctx.getMessager() ); annotations.addAll( additionalAnnotationsBuilder.getProcessedAnnotations( method.getExecutable() ) ); /* the type that needs to be used in the mapping process as target */ @@ -239,8 +243,8 @@ else if ( !method.isUpdateMethod() ) { this.unprocessedConstructorProperties = constructorAccessor.constructorAccessors; factoryMethod = MethodReference.forConstructorInvocation( - resultTypeToMap, - constructorAccessor.parameterBindings + resultTypeToMap, + constructorAccessor.parameterBindings ); } @@ -260,7 +264,7 @@ else if ( !method.isUpdateMethod() ) { unprocessedSourceParameters.add( sourceParameter ); if ( sourceParameter.getType().isPrimitive() || sourceParameter.getType().isArrayType() || - sourceParameter.getType().isMapType() ) { + sourceParameter.getType().isMapType() ) { continue; } @@ -316,27 +320,27 @@ else if ( !method.isUpdateMethod() ) { // mapNullToDefault boolean mapNullToDefault = method.getOptions() - .getBeanMapping() - .getNullValueMappingStrategy() - .isReturnDefault(); + .getBeanMapping() + .getNullValueMappingStrategy() + .isReturnDefault(); // sort sortPropertyMappingsByDependencies(); // before / after mappings List beforeMappingMethods = LifecycleMethodResolver.beforeMappingMethods( - method, - resultTypeToMap, - selectionParameters, - ctx, - existingVariableNames + method, + resultTypeToMap, + selectionParameters, + ctx, + existingVariableNames ); List afterMappingMethods = LifecycleMethodResolver.afterMappingMethods( - method, - resultTypeToMap, - selectionParameters, - ctx, - existingVariableNames + method, + resultTypeToMap, + selectionParameters, + ctx, + existingVariableNames ); if ( method instanceof ForgedMethod ) { @@ -364,33 +368,31 @@ else if ( !method.isUpdateMethod() ) { finalizeMethod = getFinalizerMethod(); } - - return new BeanMappingMethod( - method, - annotations, - existingVariableNames, - propertyMappings, - factoryMethod, - mapNullToDefault, - returnTypeToConstruct, - returnTypeBuilder, - beforeMappingMethods, - afterMappingMethods, - finalizeMethod, - mappingReferences, - subclasses + method, + annotations, + existingVariableNames, + propertyMappings, + factoryMethod, + mapNullToDefault, + returnTypeToConstruct, + returnTypeBuilder, + beforeMappingMethods, + afterMappingMethods, + finalizeMethod, + mappingReferences, + subclasses ); } private boolean doesNotAllowAbstractReturnTypeAndCanBeConstructed(Type returnTypeImpl) { return !isAbstractReturnTypeAllowed() - && canReturnTypeBeConstructed( returnTypeImpl ); + && canReturnTypeBeConstructed( returnTypeImpl ); } private boolean allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed(Type returnTypeImpl) { return isAbstractReturnTypeAllowed() - && isReturnTypeAbstractOrCanBeConstructed( returnTypeImpl ); + && isReturnTypeAbstractOrCanBeConstructed( returnTypeImpl ); } private SubclassMapping createSubclassMapping(SubclassMappingOptions subclassMappingOptions) { @@ -399,36 +401,36 @@ private SubclassMapping createSubclassMapping(SubclassMappingOptions subclassMap Type targetType = typeFactory.getType( subclassMappingOptions.getTarget() ); SourceRHS rightHandSide = new SourceRHS( - "subclassMapping", - sourceType, - Collections.emptySet(), - "SubclassMapping for " + sourceType.getFullyQualifiedName() ); + "subclassMapping", + sourceType, + Collections.emptySet(), + "SubclassMapping for " + sourceType.getFullyQualifiedName() ); SelectionCriteria criteria = - SelectionCriteria - .forMappingMethods( - new SelectionParameters( - Collections.emptyList(), - Collections.emptyList(), - subclassMappingOptions.getTarget(), - ctx.getTypeUtils() ).withSourceRHS( rightHandSide ), - null, - null, - false ); + SelectionCriteria + .forMappingMethods( + new SelectionParameters( + Collections.emptyList(), + Collections.emptyList(), + subclassMappingOptions.getTarget(), + ctx.getTypeUtils() ).withSourceRHS( rightHandSide ), + null, + null, + false ); Assignment assignment = ctx - .getMappingResolver() - .getTargetAssignment( - method, - null, - targetType, - FormattingParameters.EMPTY, - criteria, - rightHandSide, - null, - () -> forgeSubclassMapping( - rightHandSide, - sourceType, - targetType, - mappingReferences ) ); + .getMappingResolver() + .getTargetAssignment( + method, + null, + targetType, + FormattingParameters.EMPTY, + criteria, + rightHandSide, + null, + () -> forgeSubclassMapping( + rightHandSide, + sourceType, + targetType, + mappingReferences ) ); String sourceArgument = null; for ( Parameter parameter : method.getSourceParameters() ) { if ( ctx @@ -443,7 +445,7 @@ private SubclassMapping createSubclassMapping(SubclassMappingOptions subclassMap private boolean isAbstractReturnTypeAllowed() { return method.getOptions().getBeanMapping().getSubclassExhaustiveStrategy().isAbstractReturnTypeAllowed() - && !method.getOptions().getSubclassMappings().isEmpty(); + && !method.getOptions().getSubclassMappings().isEmpty(); } private void initializeMappingReferencesIfNeeded(Type resultTypeToMap) { @@ -451,11 +453,11 @@ private void initializeMappingReferencesIfNeeded(Type resultTypeToMap) { Set readAndWriteTargetProperties = new HashSet<>( unprocessedTargetProperties.keySet() ); readAndWriteTargetProperties.addAll( resultTypeToMap.getPropertyReadAccessors().keySet() ); mappingReferences = forSourceMethod( - (SourceMethod) method, - resultTypeToMap, - readAndWriteTargetProperties, - ctx.getMessager(), - ctx.getTypeFactory() + (SourceMethod) method, + resultTypeToMap, + readAndWriteTargetProperties, + ctx.getMessager(), + ctx.getTypeFactory() ); } } @@ -485,9 +487,9 @@ else if ( returnTypeToConstruct.isAssignableTo( method.getReturnType() ) ) { private MethodReference getFinalizerMethod() { return BuilderFinisherMethodResolver.getBuilderFinisherMethod( - method, - returnTypeBuilder, - ctx + method, + returnTypeBuilder, + ctx ); } @@ -509,28 +511,28 @@ private void handleUnprocessedDefinedTargets() { boolean forceUpdateMethod = sourceParameters.size() > 1; for ( Parameter sourceParameter : sourceParameters ) { SourceReference reference = new SourceReference.BuilderFromProperty() - .sourceParameter( sourceParameter ) - .name( propertyName ) - .build(); + .sourceParameter( sourceParameter ) + .name( propertyName ) + .build(); ReadAccessor targetPropertyReadAccessor = - method.getResultType().getReadAccessor( propertyName ); + method.getResultType().getReadAccessor( propertyName ); MappingReferences mappingRefs = extractMappingReferences( propertyName, true ); PropertyMapping propertyMapping = new PropertyMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .target( - propertyName, - targetPropertyReadAccessor, - unprocessedTargetProperties.get( propertyName ) - ) - .sourceReference( reference ) - .existingVariableNames( existingVariableNames ) - .dependsOn( mappingRefs.collectNestedDependsOn() ) - .forgeMethodWithMappingReferences( mappingRefs ) - .forceUpdateMethod( forceUpdateMethod ) - .forgedNamedBased( false ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .target( + propertyName, + targetPropertyReadAccessor, + unprocessedTargetProperties.get( propertyName ) + ) + .sourceReference( reference ) + .existingVariableNames( existingVariableNames ) + .dependsOn( mappingRefs.collectNestedDependsOn() ) + .forgeMethodWithMappingReferences( mappingRefs ) + .forceUpdateMethod( forceUpdateMethod ) + .forgedNamedBased( false ) + .build(); if ( propertyMapping != null ) { unprocessedTargetProperties.remove( propertyName ); @@ -549,18 +551,18 @@ private void handleUnmappedConstructorProperties() { for ( Entry entry : unprocessedConstructorProperties.entrySet() ) { Accessor accessor = entry.getValue(); Type accessedType = ctx.getTypeFactory() - .getType( accessor.getAccessedType() ); + .getType( accessor.getAccessedType() ); String targetPropertyName = entry.getKey(); propertyMappings.add( new JavaExpressionMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .javaExpression( accessedType.getNull() ) - .existingVariableNames( existingVariableNames ) - .target( targetPropertyName, null, accessor ) - .dependsOn( Collections.emptySet() ) - .mirror( null ) - .build() + .mappingContext( ctx ) + .sourceMethod( method ) + .javaExpression( accessedType.getNull() ) + .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, null, accessor ) + .dependsOn( Collections.emptySet() ) + .mirror( null ) + .build() ); } @@ -587,13 +589,13 @@ private void sortPropertyMappingsByDependencies() { } ctx.getMessager().printMessage( - method.getExecutable(), - Message.BEANMAPPING_CYCLE_BETWEEN_PROPERTIES, Strings.join( cycles, ", " ) + method.getExecutable(), + Message.BEANMAPPING_CYCLE_BETWEEN_PROPERTIES, Strings.join( cycles, ", " ) ); } else { propertyMappings.sort( Comparator.comparingInt( propertyMapping -> - graphAnalyzer.getTraversalSequence( propertyMapping.getName() ) ) ); + graphAnalyzer.getTraversalSequence( propertyMapping.getName() ) ) ); } } @@ -602,30 +604,30 @@ private boolean canResultTypeFromBeanMappingBeConstructed(Type resultType) { boolean error = true; if ( resultType.isAbstract() ) { ctx.getMessager().printMessage( - method.getExecutable(), - method.getOptions().getBeanMapping().getMirror(), - BEANMAPPING_ABSTRACT, - resultType.describe(), - method.getResultType().describe() + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + BEANMAPPING_ABSTRACT, + resultType.describe(), + method.getResultType().describe() ); error = false; } else if ( !resultType.isAssignableTo( method.getResultType() ) ) { ctx.getMessager().printMessage( - method.getExecutable(), - method.getOptions().getBeanMapping().getMirror(), - BEANMAPPING_NOT_ASSIGNABLE, - resultType.describe(), - method.getResultType().describe() + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + BEANMAPPING_NOT_ASSIGNABLE, + resultType.describe(), + method.getResultType().describe() ); error = false; } else if ( !resultType.hasAccessibleConstructor() ) { ctx.getMessager().printMessage( - method.getExecutable(), - method.getOptions().getBeanMapping().getMirror(), - Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, - resultType.describe() + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + resultType.describe() ); error = false; } @@ -636,17 +638,17 @@ private boolean canReturnTypeBeConstructed(Type returnType) { boolean error = true; if ( returnType.isAbstract() ) { ctx.getMessager().printMessage( - method.getExecutable(), - GENERAL_ABSTRACT_RETURN_TYPE, - returnType.describe() + method.getExecutable(), + GENERAL_ABSTRACT_RETURN_TYPE, + returnType.describe() ); error = false; } else if ( !returnType.hasAccessibleConstructor() ) { ctx.getMessager().printMessage( - method.getExecutable(), - Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, - returnType.describe() + method.getExecutable(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + returnType.describe() ); error = false; } @@ -657,11 +659,11 @@ private boolean isReturnTypeAbstractOrCanBeConstructed(Type returnType) { boolean error = true; if ( !returnType.isAbstract() && !returnType.hasAccessibleConstructor() ) { ctx - .getMessager() - .printMessage( - method.getExecutable(), - Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, - returnType.describe() ); + .getMessager() + .printMessage( + method.getExecutable(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + returnType.describe() ); error = false; } return error; @@ -675,12 +677,12 @@ private boolean isReturnTypeAbstractOrCanBeConstructed(Type returnType) { */ private void initializeFactoryMethod(Type returnTypeImpl, SelectionParameters selectionParameters) { List> matchingFactoryMethods = - ObjectFactoryMethodResolver.getMatchingFactoryMethods( - method, - returnTypeImpl, - selectionParameters, - ctx - ); + ObjectFactoryMethodResolver.getMatchingFactoryMethods( + method, + returnTypeImpl, + selectionParameters, + ctx + ); if ( matchingFactoryMethods.isEmpty() ) { if ( factoryMethod == null && returnTypeBuilder != null ) { @@ -690,21 +692,21 @@ private void initializeFactoryMethod(Type returnTypeImpl, SelectionParameters se } else if ( matchingFactoryMethods.size() == 1 ) { factoryMethod = ObjectFactoryMethodResolver.getFactoryMethodReference( - method, - first( matchingFactoryMethods ), - ctx + method, + first( matchingFactoryMethods ), + ctx ); hasFactoryMethod = true; } else { ctx.getMessager().printMessage( - method.getExecutable(), - Message.GENERAL_AMBIGUOUS_FACTORY_METHOD, - returnTypeImpl.describe(), - matchingFactoryMethods.stream() - .map( SelectedMethod::getMethod ) - .map( Method::describe ) - .collect( Collectors.joining( ", " ) ) + method.getExecutable(), + Message.GENERAL_AMBIGUOUS_FACTORY_METHOD, + returnTypeImpl.describe(), + matchingFactoryMethods.stream() + .map( SelectedMethod::getMethod ) + .map( Method::describe ) + .collect( Collectors.joining( ", " ) ) ); hasFactoryMethod = true; } @@ -727,28 +729,28 @@ private ConstructorAccessor getConstructorAccessor(Type type) { Map constructorAccessors = new LinkedHashMap<>(); for ( Element recordComponent : recordComponents ) { TypeMirror recordComponentMirror = ctx.getTypeUtils() - .asMemberOf( (DeclaredType) type.getTypeMirror(), recordComponent ); + .asMemberOf( (DeclaredType) type.getTypeMirror(), recordComponent ); String parameterName = recordComponent.getSimpleName().toString(); Accessor accessor = createConstructorAccessor( - recordComponent, - recordComponentMirror, - parameterName + recordComponent, + recordComponentMirror, + parameterName ); constructorAccessors.put( - parameterName, - accessor + parameterName, + accessor ); parameterBindings.add( ParameterBinding.fromTypeAndName( - ctx.getTypeFactory().getType( recordComponentMirror ), - accessor.getSimpleName() + ctx.getTypeFactory().getType( recordComponentMirror ), + accessor.getSimpleName() ) ); } return new ConstructorAccessor( parameterBindings, constructorAccessors ); } List constructors = ElementFilter.constructorsIn( type.getTypeElement() - .getEnclosedElements() ); + .getEnclosedElements() ); // The rules for picking a constructor are the following: // 1. Constructor annotated with @Default (from any package) has highest precedence @@ -811,17 +813,17 @@ private ConstructorAccessor getConstructorAccessor(Type type) { if ( accessibleConstructors.size() > 1 ) { ctx.getMessager().printMessage( - method.getExecutable(), - GENERAL_AMBIGUOUS_CONSTRUCTORS, - type, - constructors.stream() - .map( ExecutableElement::getParameters ) - .map( ps -> ps.stream() - .map( VariableElement::asType ) - .map( String::valueOf ) - .collect( Collectors.joining( ", ", type.getName() + "(", ")" ) ) - ) - .collect( Collectors.joining( ", " ) ) + method.getExecutable(), + GENERAL_AMBIGUOUS_CONSTRUCTORS, + type, + constructors.stream() + .map( ExecutableElement::getParameters ) + .map( ps -> ps.stream() + .map( VariableElement::asType ) + .map( String::valueOf ) + .collect( Collectors.joining( ", ", type.getName() + "(", ")" ) ) + ) + .collect( Collectors.joining( ", " ) ) ); return null; } @@ -833,17 +835,17 @@ private ConstructorAccessor getConstructorAccessor(Type type) { private ConstructorAccessor getConstructorAccessor(Type type, ExecutableElement constructor) { List constructorParameters = ctx.getTypeFactory() - .getParameters( (DeclaredType) type.getTypeMirror(), constructor ); + .getParameters( (DeclaredType) type.getTypeMirror(), constructor ); List constructorProperties = null; for ( AnnotationMirror annotationMirror : constructor.getAnnotationMirrors() ) { if ( annotationMirror.getAnnotationType() - .asElement() - .getSimpleName() - .contentEquals( "ConstructorProperties" ) ) { + .asElement() + .getSimpleName() + .contentEquals( "ConstructorProperties" ) ) { for ( Entry entry : annotationMirror - .getElementValues() - .entrySet() ) { + .getElementValues() + .entrySet() ) { if ( entry.getKey().getSimpleName().contentEquals( "value" ) ) { constructorProperties = getArrayValues( entry.getValue() ); break; @@ -860,17 +862,17 @@ private ConstructorAccessor getConstructorAccessor(Type type, ExecutableElement String parameterName = constructorParameter.getName(); Element parameterElement = constructorParameter.getElement(); Accessor constructorAccessor = createConstructorAccessor( - parameterElement, - constructorParameter.getType().getTypeMirror(), - parameterName + parameterElement, + constructorParameter.getType().getTypeMirror(), + parameterName ); constructorAccessors.put( - parameterName, - constructorAccessor + parameterName, + constructorAccessor ); parameterBindings.add( ParameterBinding.fromTypeAndName( - constructorParameter.getType(), - constructorAccessor.getSimpleName() + constructorParameter.getType(), + constructorAccessor.getSimpleName() ) ); } @@ -878,9 +880,9 @@ private ConstructorAccessor getConstructorAccessor(Type type, ExecutableElement } else if ( constructorProperties.size() != constructorParameters.size() ) { ctx.getMessager().printMessage( - method.getExecutable(), - GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS, - type + method.getExecutable(), + GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS, + type ); return null; } @@ -892,17 +894,17 @@ else if ( constructorProperties.size() != constructorParameters.size() ) { Parameter constructorParameter = constructorParameters.get( i ); Element parameterElement = constructorParameter.getElement(); Accessor constructorAccessor = createConstructorAccessor( - parameterElement, - constructorParameter.getType().getTypeMirror(), - parameterName + parameterElement, + constructorParameter.getType().getTypeMirror(), + parameterName ); constructorAccessors.put( - parameterName, - constructorAccessor + parameterName, + constructorAccessor ); parameterBindings.add( ParameterBinding.fromTypeAndName( - constructorParameter.getType(), - constructorAccessor.getSimpleName() + constructorParameter.getType(), + constructorAccessor.getSimpleName() ) ); } @@ -912,8 +914,8 @@ else if ( constructorProperties.size() != constructorParameters.size() ) { private Accessor createConstructorAccessor(Element element, TypeMirror accessedType, String parameterName) { String safeParameterName = Strings.getSafeVariableName( - parameterName, - existingVariableNames + parameterName, + existingVariableNames ); existingVariableNames.add( safeParameterName ); return new ParameterElementAccessor( element, accessedType, safeParameterName ); @@ -922,9 +924,9 @@ private Accessor createConstructorAccessor(Element element, TypeMirror accessedT private boolean hasDefaultAnnotationFromAnyPackage(Element element) { for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) { if ( annotationMirror.getAnnotationType() - .asElement() - .getSimpleName() - .contentEquals( "Default" ) ) { + .asElement() + .getSimpleName() + .contentEquals( "Default" ) ) { return true; } } @@ -1012,20 +1014,20 @@ private boolean handleDefinedMappings(Type resultTypeToMap) { private boolean handleDefinedNestedTargetMapping(Set handledTargets, Type resultTypeToMap) { NestedTargetPropertyMappingHolder holder = new NestedTargetPropertyMappingHolder.Builder() - .mappingContext( ctx ) - .method( method ) - .targetPropertiesWriteAccessors( unprocessedTargetProperties ) - .targetPropertyType( resultTypeToMap ) - .mappingReferences( mappingReferences ) - .existingVariableNames( existingVariableNames ) - .build(); + .mappingContext( ctx ) + .method( method ) + .targetPropertiesWriteAccessors( unprocessedTargetProperties ) + .targetPropertyType( resultTypeToMap ) + .mappingReferences( mappingReferences ) + .existingVariableNames( existingVariableNames ) + .build(); unprocessedSourceParameters.removeAll( holder.getProcessedSourceParameters() ); propertyMappings.addAll( holder.getPropertyMappings() ); handledTargets.addAll( holder.getHandledTargets() ); // Store all the unprocessed defined targets. for ( Entry> entry : holder.getUnprocessedDefinedTarget() - .entrySet() ) { + .entrySet() ) { if ( entry.getValue().isEmpty() ) { continue; } @@ -1035,7 +1037,7 @@ private boolean handleDefinedNestedTargetMapping(Set handledTargets, Typ } private boolean handleDefinedMapping(MappingReference mappingRef, Type resultTypeToMap, - Set handledTargets) { + Set handledTargets) { boolean errorOccured = false; PropertyMapping propertyMapping = null; @@ -1047,11 +1049,11 @@ private boolean handleDefinedMapping(MappingReference mappingRef, Type resultTyp for ( String dependency : mapping.getDependsOn() ) { if ( !targetProperties.contains( dependency ) ) { ctx.getMessager().printMessage( - method.getExecutable(), - mapping.getMirror(), - mapping.getDependsOnAnnotationValue(), - Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_DEPENDS_ON, - dependency + method.getExecutable(), + mapping.getMirror(), + mapping.getDependsOnAnnotationValue(), + Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_DEPENDS_ON, + dependency ); errorOccured = true; } @@ -1072,7 +1074,7 @@ private boolean handleDefinedMapping(MappingReference mappingRef, Type resultTyp MappingOptions.InheritContext inheritContext = mapping.getInheritContext(); if ( inheritContext != null ) { if ( inheritContext.isForwarded() && - inheritContext.getTemplateMethod().isUpdateMethod() != method.isUpdateMethod() ) { + inheritContext.getTemplateMethod().isUpdateMethod() != method.isUpdateMethod() ) { // When a configuration is inherited and the template method is not same type as the current // method then we can safely ignore this mapping. // This means that a property which is inherited might be present for a direct mapping @@ -1097,9 +1099,9 @@ else if ( inheritContext.isReversed() ) { if ( targetRef.getPathProperties().isEmpty() ) { msg = Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE; args = new String[] { - targetPropertyName, - resultTypeToMap.describe(), - mostSimilarProperty + targetPropertyName, + resultTypeToMap.describe(), + mostSimilarProperty }; } else { @@ -1107,21 +1109,21 @@ else if ( inheritContext.isReversed() ) { pathProperties.add( mostSimilarProperty ); msg = Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_TYPE; args = new String[] { - targetPropertyName, - resultTypeToMap.describe(), - mapping.getTargetName(), - Strings.join( pathProperties, "." ) + targetPropertyName, + resultTypeToMap.describe(), + mapping.getTargetName(), + Strings.join( pathProperties, "." ) }; } ctx.getMessager() - .printMessage( - mapping.getElement(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - msg, - args - ); + .printMessage( + mapping.getElement(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + msg, + args + ); return true; } else if ( mapping.getInheritContext() != null && mapping.getInheritContext().isReversed() ) { @@ -1136,26 +1138,26 @@ else if ( !mapping.isIgnored() ) { if ( Objects.equals( targetPropertyName, mapping.getTargetName() ) ) { msg = Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_RESULTTYPE; args = new Object[] { - mapping.getTargetName(), - resultTypeToMap.describe() + mapping.getTargetName(), + resultTypeToMap.describe() }; } else { msg = Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_TYPE; args = new Object[] { - targetPropertyName, - resultTypeToMap.describe(), - mapping.getTargetName() + targetPropertyName, + resultTypeToMap.describe(), + mapping.getTargetName() }; } ctx.getMessager() - .printMessage( - mapping.getElement(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - msg, - args - ); + .printMessage( + mapping.getElement(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + msg, + args + ); return true; } } @@ -1167,17 +1169,17 @@ else if ( !mapping.isIgnored() ) { // Even though the property is ignored this is a constructor parameter. // Therefore we have to initialize it Type accessedType = ctx.getTypeFactory() - .getType( targetWriteAccessor.getAccessedType() ); + .getType( targetWriteAccessor.getAccessedType() ); propertyMapping = new JavaExpressionMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .javaExpression( accessedType.getNull() ) - .existingVariableNames( existingVariableNames ) - .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) - .dependsOn( mapping.getDependsOn() ) - .mirror( mapping.getMirror() ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .javaExpression( accessedType.getNull() ) + .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .dependsOn( mapping.getDependsOn() ) + .mirror( mapping.getMirror() ) + .build(); } handledTargets.add( targetPropertyName ); } @@ -1188,17 +1190,17 @@ else if ( !mapping.isIgnored() ) { else if ( mapping.getConstant() != null ) { propertyMapping = new ConstantMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .constantExpression( mapping.getConstant() ) - .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) - .formattingParameters( mapping.getFormattingParameters() ) - .selectionParameters( mapping.getSelectionParameters() ) - .options( mapping ) - .existingVariableNames( existingVariableNames ) - .dependsOn( mapping.getDependsOn() ) - .mirror( mapping.getMirror() ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .constantExpression( mapping.getConstant() ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .formattingParameters( mapping.getFormattingParameters() ) + .selectionParameters( mapping.getSelectionParameters() ) + .options( mapping ) + .existingVariableNames( existingVariableNames ) + .dependsOn( mapping.getDependsOn() ) + .mirror( mapping.getMirror() ) + .build(); handledTargets.add( targetPropertyName ); } @@ -1208,14 +1210,14 @@ else if ( mapping.getConstant() != null ) { else if ( mapping.getJavaExpression() != null ) { propertyMapping = new JavaExpressionMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .javaExpression( mapping.getJavaExpression() ) - .existingVariableNames( existingVariableNames ) - .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) - .dependsOn( mapping.getDependsOn() ) - .mirror( mapping.getMirror() ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .javaExpression( mapping.getJavaExpression() ) + .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .dependsOn( mapping.getDependsOn() ) + .mirror( mapping.getMirror() ) + .build(); handledTargets.add( targetPropertyName ); } // its a plain-old property mapping @@ -1230,8 +1232,8 @@ else if ( mapping.getJavaExpression() != null ) { // and then do parameter name based mapping for ( Parameter sourceParameter : method.getSourceParameters() ) { SourceReference matchingSourceRef = getSourceRefByTargetName( - sourceParameter, - targetPropertyName + sourceParameter, + targetPropertyName ); if ( matchingSourceRef != null ) { if ( sourceRef != null ) { @@ -1239,12 +1241,12 @@ else if ( mapping.getJavaExpression() != null ) { // This can only happen when the target property matches multiple properties // within the different source parameters ctx.getMessager() - .printMessage( - method.getExecutable(), - mappingRef.getMapping().getMirror(), - Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, - targetPropertyName - ); + .printMessage( + method.getExecutable(), + mappingRef.getMapping().getMirror(), + Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, + targetPropertyName + ); break; } // We can't break here since it is possible that the same property exists in multiple @@ -1258,14 +1260,14 @@ else if ( mapping.getJavaExpression() != null ) { if ( sourceRef == null ) { // still no match. Try if one of the parameters has the same name sourceRef = method.getSourceParameters() - .stream() - .filter( p -> targetPropertyName.equals( p.getName() ) ) - .findAny() - .map( p -> new SourceReference.BuilderFromProperty() - .sourceParameter( p ) - .name( targetPropertyName ) - .build() ) - .orElse( null ); + .stream() + .filter( p -> targetPropertyName.equals( p.getName() ) ) + .findAny() + .map( p -> new SourceReference.BuilderFromProperty() + .sourceParameter( p ) + .name( targetPropertyName ) + .build() ) + .orElse( null ); } if ( sourceRef != null ) { @@ -1275,21 +1277,21 @@ else if ( mapping.getJavaExpression() != null ) { // 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() ) - .conditionJavaExpression( mapping.getConditionJavaExpression() ) - .mirror( mapping.getMirror() ) - .options( mapping ) - .build(); + .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() ) + .conditionJavaExpression( mapping.getConditionJavaExpression() ) + .mirror( mapping.getMirror() ) + .options( mapping ) + .build(); handledTargets.add( targetPropertyName ); unprocessedSourceParameters.remove( sourceRef.getParameter() ); unprocessedSourceProperties.remove( sourceRef.getShallowestPropertyName() ); @@ -1303,24 +1305,24 @@ else if ( mapping.getJavaExpression() != null ) { if ( method.getSourceParameters().size() == 1 ) { ctx.getMessager() - .printMessage( - method.getExecutable(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PROPERTY_FROM_TARGET, - method.getSourceParameters().get( 0 ).getName(), - targetPropertyName - ); + .printMessage( + method.getExecutable(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PROPERTY_FROM_TARGET, + method.getSourceParameters().get( 0 ).getName(), + targetPropertyName + ); } else { ctx.getMessager() - .printMessage( - method.getExecutable(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET, - targetPropertyName - ); + .printMessage( + method.getExecutable(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET, + targetPropertyName + ); } } } @@ -1346,21 +1348,21 @@ private void applyTargetThisMapping() { // handle all prior unprocessed target properties, but let duplicates fall through List sourceRefs = targetThis - .getSourceReference() - .push( ctx.getTypeFactory(), ctx.getMessager(), method ) - .stream() - .filter( sr -> unprocessedTargetProperties.containsKey( sr.getDeepestPropertyName() ) - || handledTargetProperties.contains( sr.getDeepestPropertyName() ) ) - .collect( Collectors.toList() ); + .getSourceReference() + .push( ctx.getTypeFactory(), ctx.getMessager(), method ) + .stream() + .filter( sr -> unprocessedTargetProperties.containsKey( sr.getDeepestPropertyName() ) + || handledTargetProperties.contains( sr.getDeepestPropertyName() ) ) + .collect( Collectors.toList() ); // apply name based mapping applyPropertyNameBasedMapping( sourceRefs ); // add handled target properties handledTargetProperties.addAll( sourceRefs.stream() - .map( SourceReference::getDeepestPropertyName ) - .collect( - Collectors.toList() ) ); + .map( SourceReference::getDeepestPropertyName ) + .collect( + Collectors.toList() ) ); } } @@ -1399,24 +1401,24 @@ private void applyPropertyNameBasedMapping(List sourceReference if ( targetPropertyWriteAccessor == null ) { // TODO improve error message ctx.getMessager() - .printMessage( method.getExecutable(), - Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, - targetPropertyName - ); + .printMessage( method.getExecutable(), + Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, + targetPropertyName + ); continue; } ReadAccessor targetPropertyReadAccessor = - method.getResultType().getReadAccessor( targetPropertyName ); + method.getResultType().getReadAccessor( targetPropertyName ); MappingReferences mappingRefs = extractMappingReferences( targetPropertyName, false ); PropertyMapping propertyMapping = new PropertyMappingBuilder().mappingContext( ctx ) - .sourceMethod( method ) - .target( targetPropertyName, targetPropertyReadAccessor, targetPropertyWriteAccessor ) - .sourceReference( sourceRef ) - .existingVariableNames( existingVariableNames ) - .forgeMethodWithMappingReferences( mappingRefs ) - .options( method.getOptions().getBeanMapping() ) - .build(); + .sourceMethod( method ) + .target( targetPropertyName, targetPropertyReadAccessor, targetPropertyWriteAccessor ) + .sourceReference( sourceRef ) + .existingVariableNames( existingVariableNames ) + .forgeMethodWithMappingReferences( mappingRefs ) + .options( method.getOptions().getBeanMapping() ) + .build(); unprocessedSourceParameters.remove( sourceRef.getParameter() ); @@ -1431,7 +1433,7 @@ private void applyPropertyNameBasedMapping(List sourceReference private void applyParameterNameBasedMapping() { Iterator> targetPropertyEntriesIterator = - unprocessedTargetProperties.entrySet().iterator(); + unprocessedTargetProperties.entrySet().iterator(); while ( targetPropertyEntriesIterator.hasNext() ) { @@ -1445,22 +1447,22 @@ private void applyParameterNameBasedMapping() { if ( sourceParameter.getName().equals( targetProperty.getKey() ) ) { SourceReference sourceRef = new SourceReference.BuilderFromProperty() - .sourceParameter( sourceParameter ) - .name( targetProperty.getKey() ) - .build(); + .sourceParameter( sourceParameter ) + .name( targetProperty.getKey() ) + .build(); ReadAccessor targetPropertyReadAccessor = - method.getResultType().getReadAccessor( targetProperty.getKey() ); + method.getResultType().getReadAccessor( targetProperty.getKey() ); MappingReferences mappingRefs = extractMappingReferences( targetProperty.getKey(), false ); PropertyMapping propertyMapping = new PropertyMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .target( targetProperty.getKey(), targetPropertyReadAccessor, targetProperty.getValue() ) - .sourceReference( sourceRef ) - .existingVariableNames( existingVariableNames ) - .forgeMethodWithMappingReferences( mappingRefs ) - .options( method.getOptions().getBeanMapping() ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .target( targetProperty.getKey(), targetPropertyReadAccessor, targetProperty.getValue() ) + .sourceReference( sourceRef ) + .existingVariableNames( existingVariableNames ) + .forgeMethodWithMappingReferences( mappingRefs ) + .options( method.getOptions().getBeanMapping() ) + .build(); propertyMappings.add( propertyMapping ); targetPropertyEntriesIterator.remove(); @@ -1472,7 +1474,7 @@ private void applyParameterNameBasedMapping() { if ( !sourceParameter.getType().isPrimitive() && !sourceParameter.getType().isArrayType() ) { // We explicitly ignore source properties from primitives or array types Map readAccessors = sourceParameter.getType() - .getPropertyReadAccessors(); + .getPropertyReadAccessors(); for ( String sourceProperty : readAccessors.keySet() ) { unprocessedSourceProperties.remove( sourceProperty ); } @@ -1496,16 +1498,16 @@ private SourceReference getSourceRefByTargetName(Parameter sourceParameter, Stri if ( sourceReadAccessor != null ) { // property mapping PresenceCheckAccessor sourcePresenceChecker = - sourceParameter.getType().getPresenceChecker( targetPropertyName ); + sourceParameter.getType().getPresenceChecker( targetPropertyName ); DeclaredType declaredSourceType = (DeclaredType) sourceParameter.getType().getTypeMirror(); Type returnType = ctx.getTypeFactory().getReturnType( declaredSourceType, sourceReadAccessor ); sourceRef = new SourceReference.BuilderFromProperty().sourceParameter( sourceParameter ) - .type( returnType ) - .readAccessor( sourceReadAccessor ) - .presenceChecker( sourcePresenceChecker ) - .name( targetPropertyName ) - .build(); + .type( returnType ) + .readAccessor( sourceReadAccessor ) + .presenceChecker( sourcePresenceChecker ) + .name( targetPropertyName ) + .build(); } return sourceRef; } @@ -1540,24 +1542,24 @@ private void reportErrorForUnmappedTargetPropertiesIfRequired() { Type sourceType = this.method.getParameters().get( 0 ).getType(); Type targetType = this.method.getReturnType(); ctx.getMessager().printMessage( - this.method.getExecutable(), - Message.PROPERTYMAPPING_FORGED_MAPPING_NOT_FOUND, - sourceType.describe(), - targetType.describe(), - targetType.describe(), - sourceType.describe() + this.method.getExecutable(), + Message.PROPERTYMAPPING_FORGED_MAPPING_NOT_FOUND, + sourceType.describe(), + targetType.describe(), + targetType.describe(), + sourceType.describe() ); } else { ForgedMethodHistory history = forgedMethod.getHistory(); ctx.getMessager().printMessage( - this.method.getExecutable(), - Message.PROPERTYMAPPING_FORGED_MAPPING_WITH_HISTORY_NOT_FOUND, - history.createSourcePropertyErrorMessage(), - history.getTargetType().describe(), - history.createTargetPropertyName(), - history.getTargetType().describe(), - history.getSourceType().describe() + this.method.getExecutable(), + Message.PROPERTYMAPPING_FORGED_MAPPING_WITH_HISTORY_NOT_FOUND, + history.createSourcePropertyErrorMessage(), + history.getTargetType().describe(), + history.createTargetPropertyName(), + history.getTargetType().describe(), + history.getSourceType().describe() ); } } @@ -1565,49 +1567,49 @@ else if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.require if ( !( method instanceof ForgedMethod ) ) { Message msg = unmappedTargetPolicy.getDiagnosticKind() == Diagnostic.Kind.ERROR ? - Message.BEANMAPPING_UNMAPPED_TARGETS_ERROR : Message.BEANMAPPING_UNMAPPED_TARGETS_WARNING; + Message.BEANMAPPING_UNMAPPED_TARGETS_ERROR : Message.BEANMAPPING_UNMAPPED_TARGETS_WARNING; Object[] args = new Object[] { - MessageFormat.format( - "{0,choice,1#property|1 typeParameters = parameterType.getTypeParameters(); if ( typeParameters.size() != 2 || !typeParameters.get( 0 ).isString() ) { Message message = typeParameters.isEmpty() ? - Message.MAPTOBEANMAPPING_RAW_MAP : - Message.MAPTOBEANMAPPING_WRONG_KEY_TYPE; + Message.MAPTOBEANMAPPING_RAW_MAP : + Message.MAPTOBEANMAPPING_WRONG_KEY_TYPE; ctx.getMessager() - .printMessage( - method.getExecutable(), - message, - sourceParameter.getName(), - String.format( - "Map<%s,%s>", - !typeParameters.isEmpty() ? typeParameters.get( 0 ).describe() : "", - typeParameters.size() > 1 ? typeParameters.get( 1 ).describe() : "" - ) - ); + .printMessage( + method.getExecutable(), + message, + sourceParameter.getName(), + String.format( + "Map<%s,%s>", + !typeParameters.isEmpty() ? typeParameters.get( 0 ).describe() : "", + typeParameters.size() > 1 ? typeParameters.get( 1 ).describe() : "" + ) + ); } } } @@ -1699,8 +1701,8 @@ private static class ConstructorAccessor { private final Map constructorAccessors; private ConstructorAccessor( - List parameterBindings, - Map constructorAccessors) { + List parameterBindings, + Map constructorAccessors) { this.parameterBindings = parameterBindings; this.constructorAccessors = constructorAccessors; } @@ -1721,12 +1723,12 @@ private BeanMappingMethod(Method method, MappingReferences mappingReferences, List subclassMappings) { super( - method, - existingVariableNames, - factoryMethod, - mapNullToDefault, - beforeMappingReferences, - afterMappingReferences + method, + existingVariableNames, + factoryMethod, + mapNullToDefault, + beforeMappingReferences, + afterMappingReferences ); //CHECKSTYLE:ON @@ -1735,6 +1737,7 @@ private BeanMappingMethod(Method method, this.returnTypeBuilder = returnTypeBuilder; this.finalizerMethod = finalizerMethod; this.mappingReferences = mappingReferences; + // intialize constant mappings as all mappings, but take out the ones that can be contributed to a // parameter mapping. this.mappingsByParameter = new HashMap<>(); @@ -1742,14 +1745,14 @@ private BeanMappingMethod(Method method, this.constructorMappingsByParameter = new LinkedHashMap<>(); this.constructorConstantMappings = new ArrayList<>(); Set sourceParameterNames = getSourceParameters().stream() - .map( Parameter::getName ) - .collect( Collectors.toSet() ); + .map( Parameter::getName ) + .collect( Collectors.toSet() ); for ( PropertyMapping mapping : propertyMappings ) { if ( mapping.isConstructorMapping() ) { if ( sourceParameterNames.contains( mapping.getSourceBeanName() ) ) { constructorMappingsByParameter.computeIfAbsent( - mapping.getSourceBeanName(), - key -> new ArrayList<>() + mapping.getSourceBeanName(), + key -> new ArrayList<>() ).add( mapping ); } else { @@ -1758,7 +1761,7 @@ private BeanMappingMethod(Method method, } else if ( sourceParameterNames.contains( mapping.getSourceBeanName() ) ) { mappingsByParameter.computeIfAbsent( mapping.getSourceBeanName(), key -> new ArrayList<>() ) - .add( mapping ); + .add( mapping ); } else { constantMappings.add( mapping ); @@ -1804,7 +1807,7 @@ public boolean hasSubclassMappings() { public boolean isAbstractReturnType() { return getFactoryMethod() == null && returnTypeToConstruct != null - && returnTypeToConstruct.isAbstract(); + && returnTypeToConstruct.isAbstract(); } public boolean hasConstructorMappings() { @@ -1836,25 +1839,26 @@ public Set getImportTypes() { if ( returnTypeBuilder != null ) { types.add( returnTypeBuilder.getOwningType() ); } + return types; } public List getSourceParametersExcludingPrimitives() { return getSourceParameters().stream() - .filter( parameter -> !parameter.getType().isPrimitive() ) - .collect( Collectors.toList() ); + .filter( parameter -> !parameter.getType().isPrimitive() ) + .collect( Collectors.toList() ); } public List getSourceParametersNeedingNullCheck() { return getSourceParameters().stream() - .filter( this::needsNullCheck ) - .collect( Collectors.toList() ); + .filter( this::needsNullCheck ) + .collect( Collectors.toList() ); } public List getSourceParametersNotNeedingNullCheck() { return getSourceParameters().stream() - .filter( parameter -> !needsNullCheck( parameter ) ) - .collect( Collectors.toList() ); + .filter( parameter -> !needsNullCheck( parameter ) ) + .collect( Collectors.toList() ); } private boolean needsNullCheck(Parameter parameter) { @@ -1920,4 +1924,4 @@ public boolean equals(Object obj) { return true; } -} +} \ No newline at end of file diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java index 62f2478985..8b83d0b202 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java @@ -156,8 +156,7 @@ private Mapper(TypeFactory typeFactory, String packageName, String name, this.customImplName = customImplName; customAnnotations.forEach( this::addAnnotation ); TypeElement typeElement = this.getMapperDefinitionType().getTypeElement(); - if ( typeElement.getAnnotation( Deprecated.class ) != null - && typeFactory.isTypeAvailable( Deprecated.class.getCanonicalName() )) { + if ( typeElement.getAnnotation( Deprecated.class ) != null) { addAnnotation( new Annotation(typeFactory.getType( Deprecated.class )) ); } this.decorator = decorator; From 2174db275f795e7c23db6e6d3f49af7540cca04d Mon Sep 17 00:00:00 2001 From: orange add <771240658@qq.com> Date: Thu, 25 Aug 2022 14:30:46 +0800 Subject: [PATCH 15/15] feat: revert BeanMappingMethod change --- .../ap/internal/model/BeanMappingMethod.java | 872 +++++++++--------- 1 file changed, 436 insertions(+), 436 deletions(-) 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 bb61e44514..e748c173af 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 @@ -151,9 +151,9 @@ public Builder forgedMethod(ForgedMethod forgedMethod) { SourceReference sourceReference = mappingReference.getSourceReference(); if ( sourceReference != null ) { mappingReference.setSourceReference( new SourceReference.BuilderFromSourceReference() - .sourceParameter( sourceParameter ) - .sourceReference( sourceReference ) - .build() ); + .sourceParameter( sourceParameter ) + .sourceReference( sourceReference ) + .build() ); } } return this; @@ -180,8 +180,8 @@ public BeanMappingMethod build() { returnTypeImpl = returnTypeBuilder.getBuilder(); initializeFactoryMethod( returnTypeImpl, selectionParameters ); if ( factoryMethod != null - || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) - || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { + || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) + || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { returnTypeToConstruct = returnTypeImpl; } else { @@ -202,8 +202,8 @@ else if ( !method.isUpdateMethod() ) { returnTypeImpl = method.getReturnType(); initializeFactoryMethod( returnTypeImpl, selectionParameters ); if ( factoryMethod != null - || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) - || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { + || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) + || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { returnTypeToConstruct = returnTypeImpl; } else { @@ -217,10 +217,10 @@ else if ( !method.isUpdateMethod() ) { return null; } AdditionalAnnotationsBuilder additionalAnnotationsBuilder = - new AdditionalAnnotationsBuilder( - ctx.getElementUtils(), - ctx.getTypeFactory(), - ctx.getMessager() ); + new AdditionalAnnotationsBuilder( + ctx.getElementUtils(), + ctx.getTypeFactory(), + ctx.getMessager() ); annotations.addAll( additionalAnnotationsBuilder.getProcessedAnnotations( method.getExecutable() ) ); /* the type that needs to be used in the mapping process as target */ @@ -243,8 +243,8 @@ else if ( !method.isUpdateMethod() ) { this.unprocessedConstructorProperties = constructorAccessor.constructorAccessors; factoryMethod = MethodReference.forConstructorInvocation( - resultTypeToMap, - constructorAccessor.parameterBindings + resultTypeToMap, + constructorAccessor.parameterBindings ); } @@ -264,7 +264,7 @@ else if ( !method.isUpdateMethod() ) { unprocessedSourceParameters.add( sourceParameter ); if ( sourceParameter.getType().isPrimitive() || sourceParameter.getType().isArrayType() || - sourceParameter.getType().isMapType() ) { + sourceParameter.getType().isMapType() ) { continue; } @@ -320,27 +320,27 @@ else if ( !method.isUpdateMethod() ) { // mapNullToDefault boolean mapNullToDefault = method.getOptions() - .getBeanMapping() - .getNullValueMappingStrategy() - .isReturnDefault(); + .getBeanMapping() + .getNullValueMappingStrategy() + .isReturnDefault(); // sort sortPropertyMappingsByDependencies(); // before / after mappings List beforeMappingMethods = LifecycleMethodResolver.beforeMappingMethods( - method, - resultTypeToMap, - selectionParameters, - ctx, - existingVariableNames + method, + resultTypeToMap, + selectionParameters, + ctx, + existingVariableNames ); List afterMappingMethods = LifecycleMethodResolver.afterMappingMethods( - method, - resultTypeToMap, - selectionParameters, - ctx, - existingVariableNames + method, + resultTypeToMap, + selectionParameters, + ctx, + existingVariableNames ); if ( method instanceof ForgedMethod ) { @@ -369,30 +369,30 @@ else if ( !method.isUpdateMethod() ) { } return new BeanMappingMethod( - method, - annotations, - existingVariableNames, - propertyMappings, - factoryMethod, - mapNullToDefault, - returnTypeToConstruct, - returnTypeBuilder, - beforeMappingMethods, - afterMappingMethods, - finalizeMethod, - mappingReferences, - subclasses + method, + annotations, + existingVariableNames, + propertyMappings, + factoryMethod, + mapNullToDefault, + returnTypeToConstruct, + returnTypeBuilder, + beforeMappingMethods, + afterMappingMethods, + finalizeMethod, + mappingReferences, + subclasses ); } private boolean doesNotAllowAbstractReturnTypeAndCanBeConstructed(Type returnTypeImpl) { return !isAbstractReturnTypeAllowed() - && canReturnTypeBeConstructed( returnTypeImpl ); + && canReturnTypeBeConstructed( returnTypeImpl ); } private boolean allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed(Type returnTypeImpl) { return isAbstractReturnTypeAllowed() - && isReturnTypeAbstractOrCanBeConstructed( returnTypeImpl ); + && isReturnTypeAbstractOrCanBeConstructed( returnTypeImpl ); } private SubclassMapping createSubclassMapping(SubclassMappingOptions subclassMappingOptions) { @@ -401,36 +401,36 @@ private SubclassMapping createSubclassMapping(SubclassMappingOptions subclassMap Type targetType = typeFactory.getType( subclassMappingOptions.getTarget() ); SourceRHS rightHandSide = new SourceRHS( - "subclassMapping", - sourceType, - Collections.emptySet(), - "SubclassMapping for " + sourceType.getFullyQualifiedName() ); + "subclassMapping", + sourceType, + Collections.emptySet(), + "SubclassMapping for " + sourceType.getFullyQualifiedName() ); SelectionCriteria criteria = - SelectionCriteria - .forMappingMethods( - new SelectionParameters( - Collections.emptyList(), - Collections.emptyList(), - subclassMappingOptions.getTarget(), - ctx.getTypeUtils() ).withSourceRHS( rightHandSide ), - null, - null, - false ); + SelectionCriteria + .forMappingMethods( + new SelectionParameters( + Collections.emptyList(), + Collections.emptyList(), + subclassMappingOptions.getTarget(), + ctx.getTypeUtils() ).withSourceRHS( rightHandSide ), + null, + null, + false ); Assignment assignment = ctx - .getMappingResolver() - .getTargetAssignment( - method, - null, - targetType, - FormattingParameters.EMPTY, - criteria, - rightHandSide, - null, - () -> forgeSubclassMapping( - rightHandSide, - sourceType, - targetType, - mappingReferences ) ); + .getMappingResolver() + .getTargetAssignment( + method, + null, + targetType, + FormattingParameters.EMPTY, + criteria, + rightHandSide, + null, + () -> forgeSubclassMapping( + rightHandSide, + sourceType, + targetType, + mappingReferences ) ); String sourceArgument = null; for ( Parameter parameter : method.getSourceParameters() ) { if ( ctx @@ -445,7 +445,7 @@ private SubclassMapping createSubclassMapping(SubclassMappingOptions subclassMap private boolean isAbstractReturnTypeAllowed() { return method.getOptions().getBeanMapping().getSubclassExhaustiveStrategy().isAbstractReturnTypeAllowed() - && !method.getOptions().getSubclassMappings().isEmpty(); + && !method.getOptions().getSubclassMappings().isEmpty(); } private void initializeMappingReferencesIfNeeded(Type resultTypeToMap) { @@ -453,11 +453,11 @@ private void initializeMappingReferencesIfNeeded(Type resultTypeToMap) { Set readAndWriteTargetProperties = new HashSet<>( unprocessedTargetProperties.keySet() ); readAndWriteTargetProperties.addAll( resultTypeToMap.getPropertyReadAccessors().keySet() ); mappingReferences = forSourceMethod( - (SourceMethod) method, - resultTypeToMap, - readAndWriteTargetProperties, - ctx.getMessager(), - ctx.getTypeFactory() + (SourceMethod) method, + resultTypeToMap, + readAndWriteTargetProperties, + ctx.getMessager(), + ctx.getTypeFactory() ); } } @@ -487,9 +487,9 @@ else if ( returnTypeToConstruct.isAssignableTo( method.getReturnType() ) ) { private MethodReference getFinalizerMethod() { return BuilderFinisherMethodResolver.getBuilderFinisherMethod( - method, - returnTypeBuilder, - ctx + method, + returnTypeBuilder, + ctx ); } @@ -511,28 +511,28 @@ private void handleUnprocessedDefinedTargets() { boolean forceUpdateMethod = sourceParameters.size() > 1; for ( Parameter sourceParameter : sourceParameters ) { SourceReference reference = new SourceReference.BuilderFromProperty() - .sourceParameter( sourceParameter ) - .name( propertyName ) - .build(); + .sourceParameter( sourceParameter ) + .name( propertyName ) + .build(); ReadAccessor targetPropertyReadAccessor = - method.getResultType().getReadAccessor( propertyName ); + method.getResultType().getReadAccessor( propertyName ); MappingReferences mappingRefs = extractMappingReferences( propertyName, true ); PropertyMapping propertyMapping = new PropertyMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .target( - propertyName, - targetPropertyReadAccessor, - unprocessedTargetProperties.get( propertyName ) - ) - .sourceReference( reference ) - .existingVariableNames( existingVariableNames ) - .dependsOn( mappingRefs.collectNestedDependsOn() ) - .forgeMethodWithMappingReferences( mappingRefs ) - .forceUpdateMethod( forceUpdateMethod ) - .forgedNamedBased( false ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .target( + propertyName, + targetPropertyReadAccessor, + unprocessedTargetProperties.get( propertyName ) + ) + .sourceReference( reference ) + .existingVariableNames( existingVariableNames ) + .dependsOn( mappingRefs.collectNestedDependsOn() ) + .forgeMethodWithMappingReferences( mappingRefs ) + .forceUpdateMethod( forceUpdateMethod ) + .forgedNamedBased( false ) + .build(); if ( propertyMapping != null ) { unprocessedTargetProperties.remove( propertyName ); @@ -551,18 +551,18 @@ private void handleUnmappedConstructorProperties() { for ( Entry entry : unprocessedConstructorProperties.entrySet() ) { Accessor accessor = entry.getValue(); Type accessedType = ctx.getTypeFactory() - .getType( accessor.getAccessedType() ); + .getType( accessor.getAccessedType() ); String targetPropertyName = entry.getKey(); propertyMappings.add( new JavaExpressionMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .javaExpression( accessedType.getNull() ) - .existingVariableNames( existingVariableNames ) - .target( targetPropertyName, null, accessor ) - .dependsOn( Collections.emptySet() ) - .mirror( null ) - .build() + .mappingContext( ctx ) + .sourceMethod( method ) + .javaExpression( accessedType.getNull() ) + .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, null, accessor ) + .dependsOn( Collections.emptySet() ) + .mirror( null ) + .build() ); } @@ -589,13 +589,13 @@ private void sortPropertyMappingsByDependencies() { } ctx.getMessager().printMessage( - method.getExecutable(), - Message.BEANMAPPING_CYCLE_BETWEEN_PROPERTIES, Strings.join( cycles, ", " ) + method.getExecutable(), + Message.BEANMAPPING_CYCLE_BETWEEN_PROPERTIES, Strings.join( cycles, ", " ) ); } else { propertyMappings.sort( Comparator.comparingInt( propertyMapping -> - graphAnalyzer.getTraversalSequence( propertyMapping.getName() ) ) ); + graphAnalyzer.getTraversalSequence( propertyMapping.getName() ) ) ); } } @@ -604,30 +604,30 @@ private boolean canResultTypeFromBeanMappingBeConstructed(Type resultType) { boolean error = true; if ( resultType.isAbstract() ) { ctx.getMessager().printMessage( - method.getExecutable(), - method.getOptions().getBeanMapping().getMirror(), - BEANMAPPING_ABSTRACT, - resultType.describe(), - method.getResultType().describe() + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + BEANMAPPING_ABSTRACT, + resultType.describe(), + method.getResultType().describe() ); error = false; } else if ( !resultType.isAssignableTo( method.getResultType() ) ) { ctx.getMessager().printMessage( - method.getExecutable(), - method.getOptions().getBeanMapping().getMirror(), - BEANMAPPING_NOT_ASSIGNABLE, - resultType.describe(), - method.getResultType().describe() + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + BEANMAPPING_NOT_ASSIGNABLE, + resultType.describe(), + method.getResultType().describe() ); error = false; } else if ( !resultType.hasAccessibleConstructor() ) { ctx.getMessager().printMessage( - method.getExecutable(), - method.getOptions().getBeanMapping().getMirror(), - Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, - resultType.describe() + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + resultType.describe() ); error = false; } @@ -638,17 +638,17 @@ private boolean canReturnTypeBeConstructed(Type returnType) { boolean error = true; if ( returnType.isAbstract() ) { ctx.getMessager().printMessage( - method.getExecutable(), - GENERAL_ABSTRACT_RETURN_TYPE, - returnType.describe() + method.getExecutable(), + GENERAL_ABSTRACT_RETURN_TYPE, + returnType.describe() ); error = false; } else if ( !returnType.hasAccessibleConstructor() ) { ctx.getMessager().printMessage( - method.getExecutable(), - Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, - returnType.describe() + method.getExecutable(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + returnType.describe() ); error = false; } @@ -659,11 +659,11 @@ private boolean isReturnTypeAbstractOrCanBeConstructed(Type returnType) { boolean error = true; if ( !returnType.isAbstract() && !returnType.hasAccessibleConstructor() ) { ctx - .getMessager() - .printMessage( - method.getExecutable(), - Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, - returnType.describe() ); + .getMessager() + .printMessage( + method.getExecutable(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + returnType.describe() ); error = false; } return error; @@ -677,12 +677,12 @@ private boolean isReturnTypeAbstractOrCanBeConstructed(Type returnType) { */ private void initializeFactoryMethod(Type returnTypeImpl, SelectionParameters selectionParameters) { List> matchingFactoryMethods = - ObjectFactoryMethodResolver.getMatchingFactoryMethods( - method, - returnTypeImpl, - selectionParameters, - ctx - ); + ObjectFactoryMethodResolver.getMatchingFactoryMethods( + method, + returnTypeImpl, + selectionParameters, + ctx + ); if ( matchingFactoryMethods.isEmpty() ) { if ( factoryMethod == null && returnTypeBuilder != null ) { @@ -692,21 +692,21 @@ private void initializeFactoryMethod(Type returnTypeImpl, SelectionParameters se } else if ( matchingFactoryMethods.size() == 1 ) { factoryMethod = ObjectFactoryMethodResolver.getFactoryMethodReference( - method, - first( matchingFactoryMethods ), - ctx + method, + first( matchingFactoryMethods ), + ctx ); hasFactoryMethod = true; } else { ctx.getMessager().printMessage( - method.getExecutable(), - Message.GENERAL_AMBIGUOUS_FACTORY_METHOD, - returnTypeImpl.describe(), - matchingFactoryMethods.stream() - .map( SelectedMethod::getMethod ) - .map( Method::describe ) - .collect( Collectors.joining( ", " ) ) + method.getExecutable(), + Message.GENERAL_AMBIGUOUS_FACTORY_METHOD, + returnTypeImpl.describe(), + matchingFactoryMethods.stream() + .map( SelectedMethod::getMethod ) + .map( Method::describe ) + .collect( Collectors.joining( ", " ) ) ); hasFactoryMethod = true; } @@ -729,28 +729,28 @@ private ConstructorAccessor getConstructorAccessor(Type type) { Map constructorAccessors = new LinkedHashMap<>(); for ( Element recordComponent : recordComponents ) { TypeMirror recordComponentMirror = ctx.getTypeUtils() - .asMemberOf( (DeclaredType) type.getTypeMirror(), recordComponent ); + .asMemberOf( (DeclaredType) type.getTypeMirror(), recordComponent ); String parameterName = recordComponent.getSimpleName().toString(); Accessor accessor = createConstructorAccessor( - recordComponent, - recordComponentMirror, - parameterName + recordComponent, + recordComponentMirror, + parameterName ); constructorAccessors.put( - parameterName, - accessor + parameterName, + accessor ); parameterBindings.add( ParameterBinding.fromTypeAndName( - ctx.getTypeFactory().getType( recordComponentMirror ), - accessor.getSimpleName() + ctx.getTypeFactory().getType( recordComponentMirror ), + accessor.getSimpleName() ) ); } return new ConstructorAccessor( parameterBindings, constructorAccessors ); } List constructors = ElementFilter.constructorsIn( type.getTypeElement() - .getEnclosedElements() ); + .getEnclosedElements() ); // The rules for picking a constructor are the following: // 1. Constructor annotated with @Default (from any package) has highest precedence @@ -813,17 +813,17 @@ private ConstructorAccessor getConstructorAccessor(Type type) { if ( accessibleConstructors.size() > 1 ) { ctx.getMessager().printMessage( - method.getExecutable(), - GENERAL_AMBIGUOUS_CONSTRUCTORS, - type, - constructors.stream() - .map( ExecutableElement::getParameters ) - .map( ps -> ps.stream() - .map( VariableElement::asType ) - .map( String::valueOf ) - .collect( Collectors.joining( ", ", type.getName() + "(", ")" ) ) - ) - .collect( Collectors.joining( ", " ) ) + method.getExecutable(), + GENERAL_AMBIGUOUS_CONSTRUCTORS, + type, + constructors.stream() + .map( ExecutableElement::getParameters ) + .map( ps -> ps.stream() + .map( VariableElement::asType ) + .map( String::valueOf ) + .collect( Collectors.joining( ", ", type.getName() + "(", ")" ) ) + ) + .collect( Collectors.joining( ", " ) ) ); return null; } @@ -835,17 +835,17 @@ private ConstructorAccessor getConstructorAccessor(Type type) { private ConstructorAccessor getConstructorAccessor(Type type, ExecutableElement constructor) { List constructorParameters = ctx.getTypeFactory() - .getParameters( (DeclaredType) type.getTypeMirror(), constructor ); + .getParameters( (DeclaredType) type.getTypeMirror(), constructor ); List constructorProperties = null; for ( AnnotationMirror annotationMirror : constructor.getAnnotationMirrors() ) { if ( annotationMirror.getAnnotationType() - .asElement() - .getSimpleName() - .contentEquals( "ConstructorProperties" ) ) { + .asElement() + .getSimpleName() + .contentEquals( "ConstructorProperties" ) ) { for ( Entry entry : annotationMirror - .getElementValues() - .entrySet() ) { + .getElementValues() + .entrySet() ) { if ( entry.getKey().getSimpleName().contentEquals( "value" ) ) { constructorProperties = getArrayValues( entry.getValue() ); break; @@ -862,17 +862,17 @@ private ConstructorAccessor getConstructorAccessor(Type type, ExecutableElement String parameterName = constructorParameter.getName(); Element parameterElement = constructorParameter.getElement(); Accessor constructorAccessor = createConstructorAccessor( - parameterElement, - constructorParameter.getType().getTypeMirror(), - parameterName + parameterElement, + constructorParameter.getType().getTypeMirror(), + parameterName ); constructorAccessors.put( - parameterName, - constructorAccessor + parameterName, + constructorAccessor ); parameterBindings.add( ParameterBinding.fromTypeAndName( - constructorParameter.getType(), - constructorAccessor.getSimpleName() + constructorParameter.getType(), + constructorAccessor.getSimpleName() ) ); } @@ -880,9 +880,9 @@ private ConstructorAccessor getConstructorAccessor(Type type, ExecutableElement } else if ( constructorProperties.size() != constructorParameters.size() ) { ctx.getMessager().printMessage( - method.getExecutable(), - GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS, - type + method.getExecutable(), + GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS, + type ); return null; } @@ -894,17 +894,17 @@ else if ( constructorProperties.size() != constructorParameters.size() ) { Parameter constructorParameter = constructorParameters.get( i ); Element parameterElement = constructorParameter.getElement(); Accessor constructorAccessor = createConstructorAccessor( - parameterElement, - constructorParameter.getType().getTypeMirror(), - parameterName + parameterElement, + constructorParameter.getType().getTypeMirror(), + parameterName ); constructorAccessors.put( - parameterName, - constructorAccessor + parameterName, + constructorAccessor ); parameterBindings.add( ParameterBinding.fromTypeAndName( - constructorParameter.getType(), - constructorAccessor.getSimpleName() + constructorParameter.getType(), + constructorAccessor.getSimpleName() ) ); } @@ -914,8 +914,8 @@ else if ( constructorProperties.size() != constructorParameters.size() ) { private Accessor createConstructorAccessor(Element element, TypeMirror accessedType, String parameterName) { String safeParameterName = Strings.getSafeVariableName( - parameterName, - existingVariableNames + parameterName, + existingVariableNames ); existingVariableNames.add( safeParameterName ); return new ParameterElementAccessor( element, accessedType, safeParameterName ); @@ -924,9 +924,9 @@ private Accessor createConstructorAccessor(Element element, TypeMirror accessedT private boolean hasDefaultAnnotationFromAnyPackage(Element element) { for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) { if ( annotationMirror.getAnnotationType() - .asElement() - .getSimpleName() - .contentEquals( "Default" ) ) { + .asElement() + .getSimpleName() + .contentEquals( "Default" ) ) { return true; } } @@ -1014,20 +1014,20 @@ private boolean handleDefinedMappings(Type resultTypeToMap) { private boolean handleDefinedNestedTargetMapping(Set handledTargets, Type resultTypeToMap) { NestedTargetPropertyMappingHolder holder = new NestedTargetPropertyMappingHolder.Builder() - .mappingContext( ctx ) - .method( method ) - .targetPropertiesWriteAccessors( unprocessedTargetProperties ) - .targetPropertyType( resultTypeToMap ) - .mappingReferences( mappingReferences ) - .existingVariableNames( existingVariableNames ) - .build(); + .mappingContext( ctx ) + .method( method ) + .targetPropertiesWriteAccessors( unprocessedTargetProperties ) + .targetPropertyType( resultTypeToMap ) + .mappingReferences( mappingReferences ) + .existingVariableNames( existingVariableNames ) + .build(); unprocessedSourceParameters.removeAll( holder.getProcessedSourceParameters() ); propertyMappings.addAll( holder.getPropertyMappings() ); handledTargets.addAll( holder.getHandledTargets() ); // Store all the unprocessed defined targets. for ( Entry> entry : holder.getUnprocessedDefinedTarget() - .entrySet() ) { + .entrySet() ) { if ( entry.getValue().isEmpty() ) { continue; } @@ -1037,7 +1037,7 @@ private boolean handleDefinedNestedTargetMapping(Set handledTargets, Typ } private boolean handleDefinedMapping(MappingReference mappingRef, Type resultTypeToMap, - Set handledTargets) { + Set handledTargets) { boolean errorOccured = false; PropertyMapping propertyMapping = null; @@ -1049,11 +1049,11 @@ private boolean handleDefinedMapping(MappingReference mappingRef, Type resultTyp for ( String dependency : mapping.getDependsOn() ) { if ( !targetProperties.contains( dependency ) ) { ctx.getMessager().printMessage( - method.getExecutable(), - mapping.getMirror(), - mapping.getDependsOnAnnotationValue(), - Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_DEPENDS_ON, - dependency + method.getExecutable(), + mapping.getMirror(), + mapping.getDependsOnAnnotationValue(), + Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_DEPENDS_ON, + dependency ); errorOccured = true; } @@ -1074,7 +1074,7 @@ private boolean handleDefinedMapping(MappingReference mappingRef, Type resultTyp MappingOptions.InheritContext inheritContext = mapping.getInheritContext(); if ( inheritContext != null ) { if ( inheritContext.isForwarded() && - inheritContext.getTemplateMethod().isUpdateMethod() != method.isUpdateMethod() ) { + inheritContext.getTemplateMethod().isUpdateMethod() != method.isUpdateMethod() ) { // When a configuration is inherited and the template method is not same type as the current // method then we can safely ignore this mapping. // This means that a property which is inherited might be present for a direct mapping @@ -1099,9 +1099,9 @@ else if ( inheritContext.isReversed() ) { if ( targetRef.getPathProperties().isEmpty() ) { msg = Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE; args = new String[] { - targetPropertyName, - resultTypeToMap.describe(), - mostSimilarProperty + targetPropertyName, + resultTypeToMap.describe(), + mostSimilarProperty }; } else { @@ -1109,21 +1109,21 @@ else if ( inheritContext.isReversed() ) { pathProperties.add( mostSimilarProperty ); msg = Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_TYPE; args = new String[] { - targetPropertyName, - resultTypeToMap.describe(), - mapping.getTargetName(), - Strings.join( pathProperties, "." ) + targetPropertyName, + resultTypeToMap.describe(), + mapping.getTargetName(), + Strings.join( pathProperties, "." ) }; } ctx.getMessager() - .printMessage( - mapping.getElement(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - msg, - args - ); + .printMessage( + mapping.getElement(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + msg, + args + ); return true; } else if ( mapping.getInheritContext() != null && mapping.getInheritContext().isReversed() ) { @@ -1138,26 +1138,26 @@ else if ( !mapping.isIgnored() ) { if ( Objects.equals( targetPropertyName, mapping.getTargetName() ) ) { msg = Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_RESULTTYPE; args = new Object[] { - mapping.getTargetName(), - resultTypeToMap.describe() + mapping.getTargetName(), + resultTypeToMap.describe() }; } else { msg = Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_TYPE; args = new Object[] { - targetPropertyName, - resultTypeToMap.describe(), - mapping.getTargetName() + targetPropertyName, + resultTypeToMap.describe(), + mapping.getTargetName() }; } ctx.getMessager() - .printMessage( - mapping.getElement(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - msg, - args - ); + .printMessage( + mapping.getElement(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + msg, + args + ); return true; } } @@ -1169,17 +1169,17 @@ else if ( !mapping.isIgnored() ) { // Even though the property is ignored this is a constructor parameter. // Therefore we have to initialize it Type accessedType = ctx.getTypeFactory() - .getType( targetWriteAccessor.getAccessedType() ); + .getType( targetWriteAccessor.getAccessedType() ); propertyMapping = new JavaExpressionMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .javaExpression( accessedType.getNull() ) - .existingVariableNames( existingVariableNames ) - .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) - .dependsOn( mapping.getDependsOn() ) - .mirror( mapping.getMirror() ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .javaExpression( accessedType.getNull() ) + .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .dependsOn( mapping.getDependsOn() ) + .mirror( mapping.getMirror() ) + .build(); } handledTargets.add( targetPropertyName ); } @@ -1190,17 +1190,17 @@ else if ( !mapping.isIgnored() ) { else if ( mapping.getConstant() != null ) { propertyMapping = new ConstantMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .constantExpression( mapping.getConstant() ) - .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) - .formattingParameters( mapping.getFormattingParameters() ) - .selectionParameters( mapping.getSelectionParameters() ) - .options( mapping ) - .existingVariableNames( existingVariableNames ) - .dependsOn( mapping.getDependsOn() ) - .mirror( mapping.getMirror() ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .constantExpression( mapping.getConstant() ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .formattingParameters( mapping.getFormattingParameters() ) + .selectionParameters( mapping.getSelectionParameters() ) + .options( mapping ) + .existingVariableNames( existingVariableNames ) + .dependsOn( mapping.getDependsOn() ) + .mirror( mapping.getMirror() ) + .build(); handledTargets.add( targetPropertyName ); } @@ -1210,14 +1210,14 @@ else if ( mapping.getConstant() != null ) { else if ( mapping.getJavaExpression() != null ) { propertyMapping = new JavaExpressionMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .javaExpression( mapping.getJavaExpression() ) - .existingVariableNames( existingVariableNames ) - .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) - .dependsOn( mapping.getDependsOn() ) - .mirror( mapping.getMirror() ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .javaExpression( mapping.getJavaExpression() ) + .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .dependsOn( mapping.getDependsOn() ) + .mirror( mapping.getMirror() ) + .build(); handledTargets.add( targetPropertyName ); } // its a plain-old property mapping @@ -1232,8 +1232,8 @@ else if ( mapping.getJavaExpression() != null ) { // and then do parameter name based mapping for ( Parameter sourceParameter : method.getSourceParameters() ) { SourceReference matchingSourceRef = getSourceRefByTargetName( - sourceParameter, - targetPropertyName + sourceParameter, + targetPropertyName ); if ( matchingSourceRef != null ) { if ( sourceRef != null ) { @@ -1241,12 +1241,12 @@ else if ( mapping.getJavaExpression() != null ) { // This can only happen when the target property matches multiple properties // within the different source parameters ctx.getMessager() - .printMessage( - method.getExecutable(), - mappingRef.getMapping().getMirror(), - Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, - targetPropertyName - ); + .printMessage( + method.getExecutable(), + mappingRef.getMapping().getMirror(), + Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, + targetPropertyName + ); break; } // We can't break here since it is possible that the same property exists in multiple @@ -1260,14 +1260,14 @@ else if ( mapping.getJavaExpression() != null ) { if ( sourceRef == null ) { // still no match. Try if one of the parameters has the same name sourceRef = method.getSourceParameters() - .stream() - .filter( p -> targetPropertyName.equals( p.getName() ) ) - .findAny() - .map( p -> new SourceReference.BuilderFromProperty() - .sourceParameter( p ) - .name( targetPropertyName ) - .build() ) - .orElse( null ); + .stream() + .filter( p -> targetPropertyName.equals( p.getName() ) ) + .findAny() + .map( p -> new SourceReference.BuilderFromProperty() + .sourceParameter( p ) + .name( targetPropertyName ) + .build() ) + .orElse( null ); } if ( sourceRef != null ) { @@ -1277,21 +1277,21 @@ else if ( mapping.getJavaExpression() != null ) { // 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() ) - .conditionJavaExpression( mapping.getConditionJavaExpression() ) - .mirror( mapping.getMirror() ) - .options( mapping ) - .build(); + .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() ) + .conditionJavaExpression( mapping.getConditionJavaExpression() ) + .mirror( mapping.getMirror() ) + .options( mapping ) + .build(); handledTargets.add( targetPropertyName ); unprocessedSourceParameters.remove( sourceRef.getParameter() ); unprocessedSourceProperties.remove( sourceRef.getShallowestPropertyName() ); @@ -1305,24 +1305,24 @@ else if ( mapping.getJavaExpression() != null ) { if ( method.getSourceParameters().size() == 1 ) { ctx.getMessager() - .printMessage( - method.getExecutable(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PROPERTY_FROM_TARGET, - method.getSourceParameters().get( 0 ).getName(), - targetPropertyName - ); + .printMessage( + method.getExecutable(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PROPERTY_FROM_TARGET, + method.getSourceParameters().get( 0 ).getName(), + targetPropertyName + ); } else { ctx.getMessager() - .printMessage( - method.getExecutable(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET, - targetPropertyName - ); + .printMessage( + method.getExecutable(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET, + targetPropertyName + ); } } } @@ -1348,21 +1348,21 @@ private void applyTargetThisMapping() { // handle all prior unprocessed target properties, but let duplicates fall through List sourceRefs = targetThis - .getSourceReference() - .push( ctx.getTypeFactory(), ctx.getMessager(), method ) - .stream() - .filter( sr -> unprocessedTargetProperties.containsKey( sr.getDeepestPropertyName() ) - || handledTargetProperties.contains( sr.getDeepestPropertyName() ) ) - .collect( Collectors.toList() ); + .getSourceReference() + .push( ctx.getTypeFactory(), ctx.getMessager(), method ) + .stream() + .filter( sr -> unprocessedTargetProperties.containsKey( sr.getDeepestPropertyName() ) + || handledTargetProperties.contains( sr.getDeepestPropertyName() ) ) + .collect( Collectors.toList() ); // apply name based mapping applyPropertyNameBasedMapping( sourceRefs ); // add handled target properties handledTargetProperties.addAll( sourceRefs.stream() - .map( SourceReference::getDeepestPropertyName ) - .collect( - Collectors.toList() ) ); + .map( SourceReference::getDeepestPropertyName ) + .collect( + Collectors.toList() ) ); } } @@ -1401,24 +1401,24 @@ private void applyPropertyNameBasedMapping(List sourceReference if ( targetPropertyWriteAccessor == null ) { // TODO improve error message ctx.getMessager() - .printMessage( method.getExecutable(), - Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, - targetPropertyName - ); + .printMessage( method.getExecutable(), + Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, + targetPropertyName + ); continue; } ReadAccessor targetPropertyReadAccessor = - method.getResultType().getReadAccessor( targetPropertyName ); + method.getResultType().getReadAccessor( targetPropertyName ); MappingReferences mappingRefs = extractMappingReferences( targetPropertyName, false ); PropertyMapping propertyMapping = new PropertyMappingBuilder().mappingContext( ctx ) - .sourceMethod( method ) - .target( targetPropertyName, targetPropertyReadAccessor, targetPropertyWriteAccessor ) - .sourceReference( sourceRef ) - .existingVariableNames( existingVariableNames ) - .forgeMethodWithMappingReferences( mappingRefs ) - .options( method.getOptions().getBeanMapping() ) - .build(); + .sourceMethod( method ) + .target( targetPropertyName, targetPropertyReadAccessor, targetPropertyWriteAccessor ) + .sourceReference( sourceRef ) + .existingVariableNames( existingVariableNames ) + .forgeMethodWithMappingReferences( mappingRefs ) + .options( method.getOptions().getBeanMapping() ) + .build(); unprocessedSourceParameters.remove( sourceRef.getParameter() ); @@ -1433,7 +1433,7 @@ private void applyPropertyNameBasedMapping(List sourceReference private void applyParameterNameBasedMapping() { Iterator> targetPropertyEntriesIterator = - unprocessedTargetProperties.entrySet().iterator(); + unprocessedTargetProperties.entrySet().iterator(); while ( targetPropertyEntriesIterator.hasNext() ) { @@ -1447,22 +1447,22 @@ private void applyParameterNameBasedMapping() { if ( sourceParameter.getName().equals( targetProperty.getKey() ) ) { SourceReference sourceRef = new SourceReference.BuilderFromProperty() - .sourceParameter( sourceParameter ) - .name( targetProperty.getKey() ) - .build(); + .sourceParameter( sourceParameter ) + .name( targetProperty.getKey() ) + .build(); ReadAccessor targetPropertyReadAccessor = - method.getResultType().getReadAccessor( targetProperty.getKey() ); + method.getResultType().getReadAccessor( targetProperty.getKey() ); MappingReferences mappingRefs = extractMappingReferences( targetProperty.getKey(), false ); PropertyMapping propertyMapping = new PropertyMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .target( targetProperty.getKey(), targetPropertyReadAccessor, targetProperty.getValue() ) - .sourceReference( sourceRef ) - .existingVariableNames( existingVariableNames ) - .forgeMethodWithMappingReferences( mappingRefs ) - .options( method.getOptions().getBeanMapping() ) - .build(); + .mappingContext( ctx ) + .sourceMethod( method ) + .target( targetProperty.getKey(), targetPropertyReadAccessor, targetProperty.getValue() ) + .sourceReference( sourceRef ) + .existingVariableNames( existingVariableNames ) + .forgeMethodWithMappingReferences( mappingRefs ) + .options( method.getOptions().getBeanMapping() ) + .build(); propertyMappings.add( propertyMapping ); targetPropertyEntriesIterator.remove(); @@ -1474,7 +1474,7 @@ private void applyParameterNameBasedMapping() { if ( !sourceParameter.getType().isPrimitive() && !sourceParameter.getType().isArrayType() ) { // We explicitly ignore source properties from primitives or array types Map readAccessors = sourceParameter.getType() - .getPropertyReadAccessors(); + .getPropertyReadAccessors(); for ( String sourceProperty : readAccessors.keySet() ) { unprocessedSourceProperties.remove( sourceProperty ); } @@ -1498,16 +1498,16 @@ private SourceReference getSourceRefByTargetName(Parameter sourceParameter, Stri if ( sourceReadAccessor != null ) { // property mapping PresenceCheckAccessor sourcePresenceChecker = - sourceParameter.getType().getPresenceChecker( targetPropertyName ); + sourceParameter.getType().getPresenceChecker( targetPropertyName ); DeclaredType declaredSourceType = (DeclaredType) sourceParameter.getType().getTypeMirror(); Type returnType = ctx.getTypeFactory().getReturnType( declaredSourceType, sourceReadAccessor ); sourceRef = new SourceReference.BuilderFromProperty().sourceParameter( sourceParameter ) - .type( returnType ) - .readAccessor( sourceReadAccessor ) - .presenceChecker( sourcePresenceChecker ) - .name( targetPropertyName ) - .build(); + .type( returnType ) + .readAccessor( sourceReadAccessor ) + .presenceChecker( sourcePresenceChecker ) + .name( targetPropertyName ) + .build(); } return sourceRef; } @@ -1542,24 +1542,24 @@ private void reportErrorForUnmappedTargetPropertiesIfRequired() { Type sourceType = this.method.getParameters().get( 0 ).getType(); Type targetType = this.method.getReturnType(); ctx.getMessager().printMessage( - this.method.getExecutable(), - Message.PROPERTYMAPPING_FORGED_MAPPING_NOT_FOUND, - sourceType.describe(), - targetType.describe(), - targetType.describe(), - sourceType.describe() + this.method.getExecutable(), + Message.PROPERTYMAPPING_FORGED_MAPPING_NOT_FOUND, + sourceType.describe(), + targetType.describe(), + targetType.describe(), + sourceType.describe() ); } else { ForgedMethodHistory history = forgedMethod.getHistory(); ctx.getMessager().printMessage( - this.method.getExecutable(), - Message.PROPERTYMAPPING_FORGED_MAPPING_WITH_HISTORY_NOT_FOUND, - history.createSourcePropertyErrorMessage(), - history.getTargetType().describe(), - history.createTargetPropertyName(), - history.getTargetType().describe(), - history.getSourceType().describe() + this.method.getExecutable(), + Message.PROPERTYMAPPING_FORGED_MAPPING_WITH_HISTORY_NOT_FOUND, + history.createSourcePropertyErrorMessage(), + history.getTargetType().describe(), + history.createTargetPropertyName(), + history.getTargetType().describe(), + history.getSourceType().describe() ); } } @@ -1567,49 +1567,49 @@ else if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.require if ( !( method instanceof ForgedMethod ) ) { Message msg = unmappedTargetPolicy.getDiagnosticKind() == Diagnostic.Kind.ERROR ? - Message.BEANMAPPING_UNMAPPED_TARGETS_ERROR : Message.BEANMAPPING_UNMAPPED_TARGETS_WARNING; + Message.BEANMAPPING_UNMAPPED_TARGETS_ERROR : Message.BEANMAPPING_UNMAPPED_TARGETS_WARNING; Object[] args = new Object[] { - MessageFormat.format( - "{0,choice,1#property|1 typeParameters = parameterType.getTypeParameters(); if ( typeParameters.size() != 2 || !typeParameters.get( 0 ).isString() ) { Message message = typeParameters.isEmpty() ? - Message.MAPTOBEANMAPPING_RAW_MAP : - Message.MAPTOBEANMAPPING_WRONG_KEY_TYPE; + Message.MAPTOBEANMAPPING_RAW_MAP : + Message.MAPTOBEANMAPPING_WRONG_KEY_TYPE; ctx.getMessager() - .printMessage( - method.getExecutable(), - message, - sourceParameter.getName(), - String.format( - "Map<%s,%s>", - !typeParameters.isEmpty() ? typeParameters.get( 0 ).describe() : "", - typeParameters.size() > 1 ? typeParameters.get( 1 ).describe() : "" - ) - ); + .printMessage( + method.getExecutable(), + message, + sourceParameter.getName(), + String.format( + "Map<%s,%s>", + !typeParameters.isEmpty() ? typeParameters.get( 0 ).describe() : "", + typeParameters.size() > 1 ? typeParameters.get( 1 ).describe() : "" + ) + ); } } } @@ -1701,8 +1701,8 @@ private static class ConstructorAccessor { private final Map constructorAccessors; private ConstructorAccessor( - List parameterBindings, - Map constructorAccessors) { + List parameterBindings, + Map constructorAccessors) { this.parameterBindings = parameterBindings; this.constructorAccessors = constructorAccessors; } @@ -1723,12 +1723,12 @@ private BeanMappingMethod(Method method, MappingReferences mappingReferences, List subclassMappings) { super( - method, - existingVariableNames, - factoryMethod, - mapNullToDefault, - beforeMappingReferences, - afterMappingReferences + method, + existingVariableNames, + factoryMethod, + mapNullToDefault, + beforeMappingReferences, + afterMappingReferences ); //CHECKSTYLE:ON @@ -1745,14 +1745,14 @@ private BeanMappingMethod(Method method, this.constructorMappingsByParameter = new LinkedHashMap<>(); this.constructorConstantMappings = new ArrayList<>(); Set sourceParameterNames = getSourceParameters().stream() - .map( Parameter::getName ) - .collect( Collectors.toSet() ); + .map( Parameter::getName ) + .collect( Collectors.toSet() ); for ( PropertyMapping mapping : propertyMappings ) { if ( mapping.isConstructorMapping() ) { if ( sourceParameterNames.contains( mapping.getSourceBeanName() ) ) { constructorMappingsByParameter.computeIfAbsent( - mapping.getSourceBeanName(), - key -> new ArrayList<>() + mapping.getSourceBeanName(), + key -> new ArrayList<>() ).add( mapping ); } else { @@ -1761,7 +1761,7 @@ private BeanMappingMethod(Method method, } else if ( sourceParameterNames.contains( mapping.getSourceBeanName() ) ) { mappingsByParameter.computeIfAbsent( mapping.getSourceBeanName(), key -> new ArrayList<>() ) - .add( mapping ); + .add( mapping ); } else { constantMappings.add( mapping ); @@ -1807,7 +1807,7 @@ public boolean hasSubclassMappings() { public boolean isAbstractReturnType() { return getFactoryMethod() == null && returnTypeToConstruct != null - && returnTypeToConstruct.isAbstract(); + && returnTypeToConstruct.isAbstract(); } public boolean hasConstructorMappings() { @@ -1845,20 +1845,20 @@ public Set getImportTypes() { public List getSourceParametersExcludingPrimitives() { return getSourceParameters().stream() - .filter( parameter -> !parameter.getType().isPrimitive() ) - .collect( Collectors.toList() ); + .filter( parameter -> !parameter.getType().isPrimitive() ) + .collect( Collectors.toList() ); } public List getSourceParametersNeedingNullCheck() { return getSourceParameters().stream() - .filter( this::needsNullCheck ) - .collect( Collectors.toList() ); + .filter( this::needsNullCheck ) + .collect( Collectors.toList() ); } public List getSourceParametersNotNeedingNullCheck() { return getSourceParameters().stream() - .filter( parameter -> !needsNullCheck( parameter ) ) - .collect( Collectors.toList() ); + .filter( parameter -> !needsNullCheck( parameter ) ) + .collect( Collectors.toList() ); } private boolean needsNullCheck(Parameter parameter) { @@ -1924,4 +1924,4 @@ public boolean equals(Object obj) { return true; } -} \ No newline at end of file +}