#899 Refactoring adderwrapper, simplifying SourceRHS.

This commit is contained in:
sjaakd 2016-09-20 21:28:45 +02:00
parent 488eae2de2
commit afaca926ae
12 changed files with 70 additions and 84 deletions

View File

@ -18,6 +18,7 @@
*/ */
package org.mapstruct.ap.internal.model; package org.mapstruct.ap.internal.model;
import java.util.HashSet;
import static org.mapstruct.ap.internal.util.Collections.first; import static org.mapstruct.ap.internal.util.Collections.first;
import java.util.List; import java.util.List;
@ -105,12 +106,11 @@ public class IterableMappingMethod extends MappingMethod {
Assignment assignment = ctx.getMappingResolver().getTargetAssignment( Assignment assignment = ctx.getMappingResolver().getTargetAssignment(
method, method,
"collection element", "collection element",
sourceElementType,
targetElementType, targetElementType,
null, // there is no targetPropertyName null, // there is no targetPropertyName
formattingParameters, formattingParameters,
selectionParameters, selectionParameters,
new SourceRHS( loopVariableName, sourceElementType ), new SourceRHS( loopVariableName, sourceElementType, new HashSet<String>() ),
false false
); );

View File

@ -18,6 +18,7 @@
*/ */
package org.mapstruct.ap.internal.model; package org.mapstruct.ap.internal.model;
import java.util.HashSet;
import static org.mapstruct.ap.internal.util.Collections.first; import static org.mapstruct.ap.internal.util.Collections.first;
import java.util.List; import java.util.List;
@ -108,12 +109,11 @@ public class MapMappingMethod extends MappingMethod {
Assignment keyAssignment = ctx.getMappingResolver().getTargetAssignment( Assignment keyAssignment = ctx.getMappingResolver().getTargetAssignment(
method, method,
"map key", "map key",
keySourceType,
keyTargetType, keyTargetType,
null, // there is no targetPropertyName null, // there is no targetPropertyName
keyFormattingParameters, keyFormattingParameters,
keySelectionParameters, keySelectionParameters,
new SourceRHS( "entry.getKey()", keySourceType ), new SourceRHS( "entry.getKey()", keySourceType, new HashSet<String>() ),
false false
); );
@ -135,12 +135,11 @@ public class MapMappingMethod extends MappingMethod {
Assignment valueAssignment = ctx.getMappingResolver().getTargetAssignment( Assignment valueAssignment = ctx.getMappingResolver().getTargetAssignment(
method, method,
"map value", "map value",
valueSourceType,
valueTargetType, valueTargetType,
null, // there is no targetPropertyName null, // there is no targetPropertyName
valueFormattingParameters, valueFormattingParameters,
valueSelectionParameters, valueSelectionParameters,
new SourceRHS( "entry.getValue()", valueSourceType ), new SourceRHS( "entry.getValue()", valueSourceType, new HashSet<String>() ),
false false
); );

View File

@ -76,7 +76,6 @@ public class MappingBuilderContext {
* *
* @param mappingMethod target mapping method * @param mappingMethod target mapping method
* @param mappedElement used for error messages * @param mappedElement used for error messages
* @param sourceType parameter to match
* @param targetType return type to match * @param targetType return type to match
* @param targetPropertyName name of the target property * @param targetPropertyName name of the target property
* @param formattingParameters used for formatting dates and numbers * @param formattingParameters used for formatting dates and numbers
@ -93,7 +92,7 @@ public class MappingBuilderContext {
* </ol> * </ol>
*/ */
@SuppressWarnings("checkstyle:parameternumber") @SuppressWarnings("checkstyle:parameternumber")
Assignment getTargetAssignment(Method mappingMethod, String mappedElement, Type sourceType, Type targetType, Assignment getTargetAssignment(Method mappingMethod, String mappedElement, Type targetType,
String targetPropertyName, FormattingParameters formattingParameters, String targetPropertyName, FormattingParameters formattingParameters,
SelectionParameters selectionParameters, SourceRHS sourceRHS, SelectionParameters selectionParameters, SourceRHS sourceRHS,
boolean preferUpdateMethods); boolean preferUpdateMethods);

View File

@ -133,6 +133,11 @@ public class MethodReference extends MappingMethod implements Assignment {
return assignment.getSourceType(); return assignment.getSourceType();
} }
@Override
public String createLocalVarName( String desiredName ) {
return assignment.createLocalVarName( desiredName );
}
@Override @Override
public String getSourceLocalVarName() { public String getSourceLocalVarName() {
return assignment.getSourceLocalVarName(); return assignment.getSourceLocalVarName();

View File

@ -212,15 +212,11 @@ public class PropertyMapping extends ModelElement {
// handle source // handle source
String sourceElement = getSourceElement(); String sourceElement = getSourceElement();
Type sourceType = getSourceType(); Type sourceType = getSourceType();
SourceRHS sourceRHS; SourceRHS sourceRHS = getSourceRHS();
if ( targetWriteAccessorType == TargetWriteAccessorType.ADDER && sourceType.isCollectionType() ) { if ( targetWriteAccessorType == TargetWriteAccessorType.ADDER && sourceType.isCollectionType() ) {
// handle adder, if source is collection then use iterator element type as source type. // handle adder, if source is collection then use iterator element type as source type.
// sourceRef becomes a local variable in the itereation.
sourceType = sourceType.getTypeParameters().get( 0 ); sourceType = sourceType.getTypeParameters().get( 0 );
sourceRHS = new SourceRHS( Executables.getElementNameForAdder( targetWriteAccessor ), sourceType ); sourceRHS = new SourceRHS( sourceRHS.getSourceReference(), sourceType, existingVariableNames );
}
else {
sourceRHS = getSourceRHS();
} }
// all the tricky cases will be excluded for the time being. // all the tricky cases will be excluded for the time being.
@ -235,7 +231,6 @@ public class PropertyMapping extends ModelElement {
Assignment assignment = ctx.getMappingResolver().getTargetAssignment( Assignment assignment = ctx.getMappingResolver().getTargetAssignment(
method, method,
sourceElement, sourceElement,
sourceType,
targetType, targetType,
targetPropertyName, targetPropertyName,
formattingParameters, formattingParameters,
@ -320,7 +315,7 @@ public class PropertyMapping extends ModelElement {
result = assignToPlainViaSetter( sourceType, targetType, rightHandSide ); result = assignToPlainViaSetter( sourceType, targetType, rightHandSide );
} }
else { else {
result = assignToPlainViaAdder( sourceType, rightHandSide ); result = assignToPlainViaAdder( rightHandSide );
} }
return result; return result;
@ -391,18 +386,12 @@ public class PropertyMapping extends ModelElement {
} }
} }
private Assignment assignToPlainViaAdder(Type sourceType, Assignment rightHandSide) { private Assignment assignToPlainViaAdder( Assignment rightHandSide) {
Assignment result = rightHandSide; Assignment result = rightHandSide;
if ( getSourceType().isCollectionType() ) { if ( getSourceType().isCollectionType() ) {
result = new AdderWrapper( result = new AdderWrapper( result, method.getThrownTypes() );
result,
method.getThrownTypes(),
getSourceRHS().getSourceReference(),
sourceType
);
result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
} }
else { else {
// Possibly adding null to a target collection. So should be surrounded by an null check. // Possibly adding null to a target collection. So should be surrounded by an null check.
@ -495,13 +484,13 @@ public class PropertyMapping extends ModelElement {
// parameter reference // parameter reference
if ( propertyEntries.isEmpty() ) { if ( propertyEntries.isEmpty() ) {
return new SourceRHS( sourceParam.getName(), getSourceType() ); return new SourceRHS( sourceParam.getName(), getSourceType(), existingVariableNames );
} }
// simple property // simple property
else if ( propertyEntries.size() == 1 ) { else if ( propertyEntries.size() == 1 ) {
PropertyEntry propertyEntry = propertyEntries.get( 0 ); PropertyEntry propertyEntry = propertyEntries.get( 0 );
return new SourceRHS( sourceParam.getName() String sourceRef = sourceParam.getName() + "." + propertyEntry.getReadAccessor().getSimpleName() + "()";
+ "." + propertyEntry.getReadAccessor().getSimpleName() + "()", propertyEntry.getType() ); return new SourceRHS( sourceRef, propertyEntry.getType(), existingVariableNames );
} }
// nested property given as dot path // nested property given as dot path
else { else {
@ -532,7 +521,8 @@ public class PropertyMapping extends ModelElement {
else { else {
forgedName = ctx.getExistingMappingMethod( nestedPropertyMapping ).getName(); forgedName = ctx.getExistingMappingMethod( nestedPropertyMapping ).getName();
} }
return new SourceRHS( forgedName + "( " + sourceParam.getName() + " )", getSourceType() ); String sourceRef = forgedName + "( " + sourceParam.getName() + " )";
return new SourceRHS( sourceRef, getSourceType(), existingVariableNames );
} }
} }
@ -686,12 +676,11 @@ public class PropertyMapping extends ModelElement {
assignment = ctx.getMappingResolver().getTargetAssignment( assignment = ctx.getMappingResolver().getTargetAssignment(
method, method,
mappedElement, mappedElement,
sourceType,
targetType, targetType,
targetPropertyName, targetPropertyName,
formattingParameters, formattingParameters,
selectionParameters, selectionParameters,
new SourceRHS( constantExpression, sourceType ), new SourceRHS( constantExpression, sourceType, existingVariableNames ),
method.getMappingTargetParameter() != null method.getMappingTargetParameter() != null
); );
} }
@ -756,7 +745,7 @@ public class PropertyMapping extends ModelElement {
// String String quotation marks. // String String quotation marks.
String enumExpression = constantExpression.substring( 1, constantExpression.length() - 1 ); String enumExpression = constantExpression.substring( 1, constantExpression.length() - 1 );
if ( targetType.getEnumConstants().contains( enumExpression ) ) { if ( targetType.getEnumConstants().contains( enumExpression ) ) {
assignment = new SourceRHS( enumExpression, targetType ); assignment = new SourceRHS( enumExpression, targetType, existingVariableNames );
assignment = new EnumConstantWrapper( assignment, targetType ); assignment = new EnumConstantWrapper( assignment, targetType );
} }
else { else {
@ -782,7 +771,7 @@ public class PropertyMapping extends ModelElement {
} }
public PropertyMapping build() { public PropertyMapping build() {
Assignment assignment = new SourceRHS( javaExpression, null ); Assignment assignment = new SourceRHS( javaExpression, null, existingVariableNames );
if ( Executables.isSetterMethod( targetWriteAccessor ) ) { if ( Executables.isSetterMethod( targetWriteAccessor ) ) {
// setter, so wrap in setter // setter, so wrap in setter

View File

@ -25,6 +25,7 @@ import java.util.Set;
import org.mapstruct.ap.internal.model.assignment.Assignment; import org.mapstruct.ap.internal.model.assignment.Assignment;
import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.ModelElement;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.util.Strings;
/** /**
* SourceRHS Assignment. Right Hand Side (RHS), source part of the assignment. * SourceRHS Assignment. Right Hand Side (RHS), source part of the assignment.
@ -36,10 +37,12 @@ public class SourceRHS extends ModelElement implements Assignment {
private final String sourceReference; private final String sourceReference;
private final Type sourceType; private final Type sourceType;
private String sourceLocalVarName; private String sourceLocalVarName;
private final Set<String> existingVariableNames;
public SourceRHS(String sourceReference, Type sourceType ) { public SourceRHS(String sourceReference, Type sourceType, Set<String> existingVariableNames ) {
this.sourceReference = sourceReference; this.sourceReference = sourceReference;
this.sourceType = sourceType; this.sourceType = sourceType;
this.existingVariableNames = existingVariableNames;
} }
@Override @Override
@ -52,6 +55,11 @@ public class SourceRHS extends ModelElement implements Assignment {
return sourceType; return sourceType;
} }
@Override
public String createLocalVarName(String desiredName) {
return Strings.getSaveVariableName( desiredName, existingVariableNames );
}
@Override @Override
public String getSourceLocalVarName() { public String getSourceLocalVarName() {
return sourceLocalVarName; return sourceLocalVarName;

View File

@ -91,6 +91,11 @@ public class TypeConversion extends ModelElement implements Assignment {
return assignment.getSourceType(); return assignment.getSourceType();
} }
@Override
public String createLocalVarName( String desiredName ) {
return assignment.createLocalVarName( desiredName );
}
@Override @Override
public String getSourceLocalVarName() { public String getSourceLocalVarName() {
return assignment.getSourceLocalVarName(); return assignment.getSourceLocalVarName();

View File

@ -33,18 +33,14 @@ import org.mapstruct.ap.internal.model.common.Type;
public class AdderWrapper extends AssignmentWrapper { public class AdderWrapper extends AssignmentWrapper {
private final List<Type> thrownTypesToExclude; private final List<Type> thrownTypesToExclude;
private final String sourceReference; private final String sourceIteratorName;
private final Type sourceType;
public AdderWrapper( public AdderWrapper( Assignment decoratedAssignment, List<Type> thrownTypesToExclude ) {
Assignment decoratedAssignment,
List<Type> thrownTypesToExclude,
String sourceReference,
Type sourceType) {
super( decoratedAssignment ); super( decoratedAssignment );
this.thrownTypesToExclude = thrownTypesToExclude; this.thrownTypesToExclude = thrownTypesToExclude;
this.sourceReference = sourceReference; this.sourceIteratorName =
this.sourceType = sourceType; decoratedAssignment.createLocalVarName( decoratedAssignment.getSourceType().getName() );
decoratedAssignment.setSourceLocalVarName( sourceIteratorName );
} }
@Override @Override
@ -61,25 +57,15 @@ public class AdderWrapper extends AssignmentWrapper {
return result; return result;
} }
public Type getSourceType() {
return sourceType;
}
@Override
public String getSourceReference() {
return sourceReference;
}
@Override @Override
public Set<Type> getImportTypes() { public Set<Type> getImportTypes() {
Set<Type> imported = new HashSet<Type>(); Set<Type> imported = new HashSet<Type>();
imported.addAll( super.getImportTypes() ); imported.addAll( super.getImportTypes() );
imported.add( sourceType ); imported.add( getSourceType() );
return imported; return imported;
} }
public String getIteratorReference() { public String getSourceIteratorName() {
return getAssignment().getSourceReference(); return sourceIteratorName;
} }
} }

View File

@ -78,12 +78,20 @@ public interface Assignment {
String getSourceReference(); String getSourceReference();
/** /**
* the source type. * the source type used in the matching process
* *
* @return source type (can be null) * @return source type (can be null)
*/ */
Type getSourceType(); Type getSourceType();
/**
* safe (local) element variable name when dealing with collections.
*
* @param desiredName the desired name
* @return the desired name, made unique
*/
String createLocalVarName( String desiredName );
/** /**
* a local variable name for supporting a null check and avoiding executing a nested method forged method twice * a local variable name for supporting a null check and avoiding executing a nested method forged method twice
* *

View File

@ -86,4 +86,9 @@ public abstract class AssignmentWrapper extends ModelElement implements Assignme
return decoratedAssignment.isUpdateMethod(); return decoratedAssignment.isUpdateMethod();
} }
@Override
public String createLocalVarName( String desiredName ) {
return decoratedAssignment.createLocalVarName( desiredName );
}
} }

View File

@ -106,7 +106,7 @@ public class MappingResolverImpl implements MappingResolver {
@Override @Override
@SuppressWarnings("checkstyle:parameternumber") @SuppressWarnings("checkstyle:parameternumber")
public Assignment getTargetAssignment(Method mappingMethod, String mappedElement, Type sourceType, public Assignment getTargetAssignment(Method mappingMethod, String mappedElement,
Type targetType, String targetPropertyName, FormattingParameters formattingParameters, Type targetType, String targetPropertyName, FormattingParameters formattingParameters,
SelectionParameters selectionParameters, SourceRHS sourceRHS, boolean preferUpdateMapping) { SelectionParameters selectionParameters, SourceRHS sourceRHS, boolean preferUpdateMapping) {
@ -130,7 +130,7 @@ public class MappingResolverImpl implements MappingResolver {
criteria criteria
); );
return attempt.getTargetAssignment( sourceType, targetType ); return attempt.getTargetAssignment( sourceRHS.getSourceType(), targetType );
} }
@Override @Override

View File

@ -18,29 +18,11 @@
limitations under the License. limitations under the License.
--> -->
<#if (thrownTypes?size == 0) > <#import "../macro/CommonMacros.ftl" as lib>
for ( <@includeModel object=sourceType/> ${iteratorReference} : ${sourceReference} ) { <@lib.handleExceptions>
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@includeModel object=assignment if ( ${sourceReference} != null ) {
targetBeanName=ext.targetBeanName for ( <@includeModel object=sourceType/> ${sourceIteratorName} : ${sourceReference} ) {
existingInstanceMapping=ext.existingInstanceMapping ${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@lib.handleAssignment/> );
targetReadAccessorName=ext.targetReadAccessorName
targetWriteAccessorName=ext.targetWriteAccessorName
targetType=ext.targetType/> );
}
<#else>
try {
for ( <@includeModel object=sourceType/> ${iteratorReference} : ${sourceReference} ) {
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@includeModel object=assignment
targetBeanName=ext.targetBeanName
existingInstanceMapping=ext.existingInstanceMapping
targetReadAccessorName=ext.targetReadAccessorName
targetWriteAccessorName=ext.targetWriteAccessorName
targetType=ext.targetType/> );
} }
} }
<#list thrownTypes as exceptionType> </@lib.handleExceptions>
catch ( <@includeModel object=exceptionType/> e ) {
throw new RuntimeException( e );
}
</#list>
</#if>