Skip to content

Commit

Permalink
mapstruct#1742 Fix builder optional
Browse files Browse the repository at this point in the history
  • Loading branch information
sjaakd committed May 11, 2019
1 parent 02d51d3 commit e0d7e0b
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.mapstruct.ap.internal.model.common.Assignment;
import org.mapstruct.ap.internal.model.common.SourceRHS;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.source.BeanMapping;
import org.mapstruct.ap.internal.model.source.ForgedMethod;
import org.mapstruct.ap.internal.model.source.ForgedMethodHistory;
import org.mapstruct.ap.internal.util.Strings;
Expand Down Expand Up @@ -63,7 +64,12 @@ Assignment forgeMapping(SourceRHS sourceRHS, Type sourceType, Type targetType) {
true
);

return createForgedAssignment( sourceRHS, ctx.getTypeFactory().builderTypeFor( targetType ), forgedMethod );
return createForgedAssignment(
sourceRHS,
ctx.getTypeFactory()
.builderTypeFor( targetType, BeanMapping.builderPrismFor( method ).orElse( null ) ),
forgedMethod
);
}

private String getName(Type sourceType, Type targetType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@

import org.mapstruct.ap.internal.model.common.BuilderType;
import org.mapstruct.ap.internal.model.source.BeanMapping;
import org.mapstruct.ap.internal.model.source.MappingOptions;
import org.mapstruct.ap.internal.model.source.Method;
import org.mapstruct.ap.internal.prism.BuilderPrism;
import org.mapstruct.ap.internal.util.MapperConfiguration;
import org.mapstruct.ap.internal.util.Message;
import org.mapstruct.ap.internal.util.Strings;

Expand All @@ -38,11 +36,7 @@ public static MethodReference getBuilderFinisherMethod(Method method, BuilderTyp
return null;
}

Optional<BuilderPrism> beanMethodBuilder = Optional.ofNullable( method.getMappingOptions() )
.map( MappingOptions::getBeanMapping )
.flatMap( BeanMapping::getBuilder );
Optional<BuilderPrism> builderMapping = method.getMapperConfiguration().getBuilderPrism( beanMethodBuilder );

Optional<BuilderPrism> builderMapping = BeanMapping.builderPrismFor( method );
if ( !builderMapping.isPresent() && buildMethods.size() == 1 ) {
return MethodReference.forMethodCall( first( buildMethods ).getSimpleName().toString() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.mapstruct.ap.internal.model.source.SelectionParameters;
import org.mapstruct.ap.internal.model.source.SourceReference;
import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria;
import org.mapstruct.ap.internal.prism.BuilderPrism;
import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism;
import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism;
import org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism;
Expand Down Expand Up @@ -112,7 +113,8 @@ public T targetReadAccessor(Accessor targetReadAccessor) {
public T targetWriteAccessor(Accessor targetWriteAccessor) {
this.targetWriteAccessor = targetWriteAccessor;
this.targetType = ctx.getTypeFactory().getType( targetWriteAccessor.getAccessedType() );
this.targetBuilderType = ctx.getTypeFactory().builderTypeFor( this.targetType );
BuilderPrism builderPrism = BeanMapping.builderPrismFor( method ).orElse( null );
this.targetBuilderType = ctx.getTypeFactory().builderTypeFor( this.targetType, builderPrism );
this.targetWriteAccessorType = targetWriteAccessor.getAccessorType();
return (T) this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

import org.mapstruct.ap.internal.prism.BuilderPrism;
import org.mapstruct.ap.internal.util.AnnotationProcessingException;
import org.mapstruct.ap.internal.util.Collections;
import org.mapstruct.ap.internal.util.Extractor;
Expand Down Expand Up @@ -521,7 +522,10 @@ private ImplementationType getImplementationType(TypeMirror mirror) {
return null;
}

private BuilderInfo findBuilder(TypeMirror type, boolean report) {
private BuilderInfo findBuilder(TypeMirror type, BuilderPrism builderPrism, boolean report) {
if ( builderPrism != null && builderPrism.noBuilder() ) {
return null;
}
try {
return roundContext.getAnnotationProcessorContext()
.getBuilderProvider()
Expand Down Expand Up @@ -664,17 +668,17 @@ private boolean canBeProcessed(TypeMirror type) {
return true;
}

public BuilderType builderTypeFor( Type type ) {
public BuilderType builderTypeFor( Type type, BuilderPrism builderPrism ) {
if ( type != null ) {
BuilderInfo builderInfo = findBuilder( type.getTypeMirror(), true );
BuilderInfo builderInfo = findBuilder( type.getTypeMirror(), builderPrism, true );
return BuilderType.create( builderInfo, type, this, this.typeUtils );
}
return null;
}

public Type effectiveResultTypeFor( Type type ) {
public Type effectiveResultTypeFor( Type type, BuilderPrism builderPrism ) {
if ( type != null ) {
BuilderInfo builderInfo = findBuilder( type.getTypeMirror(), false );
BuilderInfo builderInfo = findBuilder( type.getTypeMirror(), builderPrism, false );
BuilderType builderType = BuilderType.create( builderInfo, type, this, this.typeUtils );
return builderType != null ? builderType.getBuilder() : type;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,14 @@ public List<String> getIgnoreUnmappedSourceProperties() {
return ignoreUnmappedSourceProperties;
}

public Optional<BuilderPrism> getBuilder() {
return Optional.ofNullable( builder );
/**
* derives the builder prism given the options and configuration
* @param method containing mandatory configuration and the mapping options (optionally containing a beanmapping)
* @return a BuilderPrism as optional
*/
public static Optional<BuilderPrism> builderPrismFor(Method method) {
return method.getMapperConfiguration()
.getBuilderPrism( Optional.ofNullable( method.getMappingOptions().getBeanMapping() )
.map( b -> b.builder ) );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,10 @@ public void applyIgnoreAll(MappingOptions inherited, SourceMethod method, Format
CollectionMappingStrategyPrism cms = method.getMapperConfiguration().getCollectionMappingStrategy();
Type writeType = method.getResultType();
if ( !method.isUpdateMethod() ) {
writeType = typeFactory.effectiveResultTypeFor( writeType );
writeType = typeFactory.effectiveResultTypeFor(
writeType,
BeanMapping.builderPrismFor( method ).orElse( null )
);
}
Map<String, Accessor> writeAccessors = writeType.getPropertyWriteAccessors( cms );
List<String> mappedPropertyNames = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory;
import org.mapstruct.ap.internal.prism.BuilderPrism;
import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism;
import org.mapstruct.ap.internal.util.AccessorNamingUtils;
import org.mapstruct.ap.internal.util.FormattingMessager;
Expand Down Expand Up @@ -207,9 +208,27 @@ private List<PropertyEntry> getTargetEntries(Type type, String[] entryNames) {

// check if an entry alread exists, otherwise create
String[] fullName = Arrays.copyOfRange( entryNames, 0, i + 1 );
BuilderType builderType = method.isUpdateMethod() ? null : typeFactory.builderTypeFor( nextType );
PropertyEntry propertyEntry = PropertyEntry.forTargetReference( fullName, targetReadAccessor,
targetWriteAccessor, nextType, builderType );
BuilderType builderType;
PropertyEntry propertyEntry = null;
if ( method.isUpdateMethod() ) {
propertyEntry = PropertyEntry.forTargetReference( fullName,
targetReadAccessor,
targetWriteAccessor,
nextType,
null
);
}
else {
BuilderPrism builderPrism = BeanMapping.builderPrismFor( method ).orElse( null );
builderType = typeFactory.builderTypeFor( nextType, builderPrism );
propertyEntry = PropertyEntry.forTargetReference( fullName,
targetReadAccessor,
targetWriteAccessor,
nextType,
builderType
);

}
targetEntries.add( propertyEntry );
}

Expand Down Expand Up @@ -264,11 +283,12 @@ else if ( targetWriteAccessor == null ) {
* search for setters and getters within the updating type.
*/
private Type typeBasedOnMethod(Type type) {
if ( method.isUpdateMethod() ) {
if ( method.isUpdateMethod() ) {
return type;
}
else {
return typeFactory.effectiveResultTypeFor( type );
BuilderPrism builderPrism = BeanMapping.builderPrismFor( method ).orElse( null );
return typeFactory.effectiveResultTypeFor( type, builderPrism );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@
import org.mapstruct.ap.internal.model.common.FormattingParameters;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory;
import org.mapstruct.ap.internal.model.source.BeanMapping;
import org.mapstruct.ap.internal.model.source.MappingOptions;
import org.mapstruct.ap.internal.model.source.Method;
import org.mapstruct.ap.internal.model.source.SelectionParameters;
import org.mapstruct.ap.internal.model.source.SourceMethod;
import org.mapstruct.ap.internal.option.Options;
import org.mapstruct.ap.internal.prism.BuilderPrism;
import org.mapstruct.ap.internal.prism.DecoratedWithPrism;
import org.mapstruct.ap.internal.prism.InheritConfigurationPrism;
import org.mapstruct.ap.internal.prism.InheritInverseConfigurationPrism;
Expand Down Expand Up @@ -369,11 +371,12 @@ else if ( method.isStreamMapping() ) {
}
else {
this.messager.note( 1, Message.BEANMAPPING_CREATE_NOTE, method );
BuilderPrism builderPrism = BeanMapping.builderPrismFor( method ).orElse( null );
BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder();
BeanMappingMethod beanMappingMethod = builder
.mappingContext( mappingContext )
.sourceMethod( method )
.returnTypeBuilder( typeFactory.builderTypeFor( method.getReturnType() ) )
.returnTypeBuilder( typeFactory.builderTypeFor( method.getReturnType(), builderPrism ) )
.build();

if ( beanMappingMethod != null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ private boolean checkParameterAndReturnType(ExecutableElement method, List<Param

if ( returnType.getTypeMirror().getKind() != TypeKind.VOID &&
!resultType.isAssignableTo( returnType ) &&
!resultType.isAssignableTo( typeFactory.effectiveResultTypeFor( returnType ) ) ) {
!resultType.isAssignableTo( typeFactory.effectiveResultTypeFor( returnType, null ) ) ) {
messager.printMessage( method, Message.RETRIEVAL_NON_ASSIGNABLE_RESULTTYPE );
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
*/
package org.mapstruct.ap.test.builder.off;

import java.util.List;

public class SimpleMutablePerson {
private String fullName;

Expand Down

0 comments on commit e0d7e0b

Please sign in to comment.