Skip to content

Commit

Permalink
#3113 Use LinkedHashSet, LinkedHashSet new factory methods for java >…
Browse files Browse the repository at this point in the history
…= 19
  • Loading branch information
Obolrom authored Sep 2, 2024
1 parent 23f4802 commit 4d9894b
Show file tree
Hide file tree
Showing 16 changed files with 1,605 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,34 @@ public class ImplementationType {
private final Type type;
private final boolean initialCapacityConstructor;
private final boolean loadFactorAdjustment;
private final String factoryMethodName;

private ImplementationType(Type type, boolean initialCapacityConstructor, boolean loadFactorAdjustment) {
private ImplementationType(
Type type,
boolean initialCapacityConstructor,
boolean loadFactorAdjustment,
String factoryMethodName
) {
this.type = type;
this.initialCapacityConstructor = initialCapacityConstructor;
this.loadFactorAdjustment = loadFactorAdjustment;
this.factoryMethodName = factoryMethodName;
}

public static ImplementationType withDefaultConstructor(Type type) {
return new ImplementationType( type, false, false );
return new ImplementationType( type, false, false, null );
}

public static ImplementationType withInitialCapacity(Type type) {
return new ImplementationType( type, true, false );
return new ImplementationType( type, true, false, null );
}

public static ImplementationType withLoadFactorAdjustment(Type type) {
return new ImplementationType( type, true, true );
return new ImplementationType( type, true, true, null );
}

public static ImplementationType withFactoryMethod(Type type, String factoryMethodName) {
return new ImplementationType( type, true, false, factoryMethodName );
}

/**
Expand All @@ -44,7 +55,7 @@ public static ImplementationType withLoadFactorAdjustment(Type type) {
* @return a new implementation type with the given {@code type}
*/
public ImplementationType createNew(Type type) {
return new ImplementationType( type, initialCapacityConstructor, loadFactorAdjustment );
return new ImplementationType( type, initialCapacityConstructor, loadFactorAdjustment, factoryMethodName );
}

/**
Expand All @@ -71,4 +82,8 @@ public boolean hasInitialCapacityConstructor() {
public boolean isLoadFactorAdjustment() {
return loadFactorAdjustment;
}

public String getFactoryMethodName() {
return factoryMethodName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,28 @@
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.WildcardType;
import org.mapstruct.ap.internal.util.ElementUtils;
import org.mapstruct.ap.internal.util.TypeUtils;

import org.mapstruct.ap.internal.gem.BuilderGem;
import org.mapstruct.ap.internal.util.AnnotationProcessingException;
import org.mapstruct.ap.internal.util.Collections;
import org.mapstruct.ap.internal.util.ElementUtils;
import org.mapstruct.ap.internal.util.Extractor;
import org.mapstruct.ap.internal.util.FormattingMessager;
import org.mapstruct.ap.internal.util.JavaStreamConstants;
import org.mapstruct.ap.internal.util.Message;
import org.mapstruct.ap.internal.util.NativeTypes;
import org.mapstruct.ap.internal.util.RoundContext;
import org.mapstruct.ap.internal.util.Strings;
import org.mapstruct.ap.internal.util.TypeUtils;
import org.mapstruct.ap.internal.util.accessor.Accessor;
import org.mapstruct.ap.internal.version.VersionInformation;
import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor;
import org.mapstruct.ap.spi.BuilderInfo;
import org.mapstruct.ap.spi.MoreThanOneBuilderCreationMethodException;
import org.mapstruct.ap.spi.TypeHierarchyErroneousException;

import static org.mapstruct.ap.internal.model.common.ImplementationType.withDefaultConstructor;
import static org.mapstruct.ap.internal.model.common.ImplementationType.withFactoryMethod;
import static org.mapstruct.ap.internal.model.common.ImplementationType.withInitialCapacity;
import static org.mapstruct.ap.internal.model.common.ImplementationType.withLoadFactorAdjustment;

Expand All @@ -82,6 +84,8 @@ public class TypeFactory {
sb.append( ')' );
return sb.toString();
};
private static final String LINKED_HASH_SET_FACTORY_METHOD_NAME = "newLinkedHashSet";
private static final String LINKED_HASH_MAP_FACTORY_METHOD_NAME = "newLinkedHashMap";

private final ElementUtils elementUtils;
private final TypeUtils typeUtils;
Expand All @@ -100,7 +104,8 @@ public class TypeFactory {
private final boolean loggingVerbose;

public TypeFactory(ElementUtils elementUtils, TypeUtils typeUtils, FormattingMessager messager,
RoundContext roundContext, Map<String, String> notToBeImportedTypes, boolean loggingVerbose) {
RoundContext roundContext, Map<String, String> notToBeImportedTypes, boolean loggingVerbose,
VersionInformation versionInformation) {
this.elementUtils = elementUtils;
this.typeUtils = typeUtils;
this.messager = messager;
Expand All @@ -118,11 +123,22 @@ public TypeFactory(ElementUtils elementUtils, TypeUtils typeUtils, FormattingMes
implementationTypes.put( Collection.class.getName(), withInitialCapacity( getType( ArrayList.class ) ) );
implementationTypes.put( List.class.getName(), withInitialCapacity( getType( ArrayList.class ) ) );

implementationTypes.put( Set.class.getName(), withLoadFactorAdjustment( getType( LinkedHashSet.class ) ) );
boolean sourceVersionAtLeast19 = versionInformation.isSourceVersionAtLeast19();
implementationTypes.put(
Set.class.getName(),
sourceVersionAtLeast19 ?
withFactoryMethod( getType( LinkedHashSet.class ), LINKED_HASH_SET_FACTORY_METHOD_NAME ) :
withLoadFactorAdjustment( getType( LinkedHashSet.class ) )
);
implementationTypes.put( SortedSet.class.getName(), withDefaultConstructor( getType( TreeSet.class ) ) );
implementationTypes.put( NavigableSet.class.getName(), withDefaultConstructor( getType( TreeSet.class ) ) );

implementationTypes.put( Map.class.getName(), withLoadFactorAdjustment( getType( LinkedHashMap.class ) ) );
implementationTypes.put(
Map.class.getName(),
sourceVersionAtLeast19 ?
withFactoryMethod( getType( LinkedHashMap.class ), LINKED_HASH_MAP_FACTORY_METHOD_NAME ) :
withLoadFactorAdjustment( getType( LinkedHashMap.class ) )
);
implementationTypes.put( SortedMap.class.getName(), withDefaultConstructor( getType( TreeMap.class ) ) );
implementationTypes.put( NavigableMap.class.getName(), withDefaultConstructor( getType( TreeMap.class ) ) );
implementationTypes.put(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public DefaultModelElementProcessorContext(ProcessingEnvironment processingEnvir
messager,
roundContext,
notToBeImported,
options.isVerbose()
options.isVerbose(),
versionInformation
);
this.options = options;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class DefaultVersionInformation implements VersionInformation {
private final String runtimeVendor;
private final String compiler;
private final boolean sourceVersionAtLeast9;
private final boolean sourceVersionAtLeast19;
private final boolean eclipseJDT;
private final boolean javac;

Expand All @@ -53,6 +54,7 @@ public class DefaultVersionInformation implements VersionInformation {
this.javac = compiler.startsWith( COMPILER_NAME_JAVAC );
// If the difference between the source version and RELEASE_6 is more that 2 than we are at least on 9
this.sourceVersionAtLeast9 = sourceVersion.compareTo( SourceVersion.RELEASE_6 ) > 2;
this.sourceVersionAtLeast19 = sourceVersion.compareTo( SourceVersion.RELEASE_6 ) > 12;
}

@Override
Expand Down Expand Up @@ -80,6 +82,11 @@ public boolean isSourceVersionAtLeast9() {
return sourceVersionAtLeast9;
}

@Override
public boolean isSourceVersionAtLeast19() {
return sourceVersionAtLeast19;
}

@Override
public boolean isEclipseJDTCompiler() {
return eclipseJDT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public interface VersionInformation {

boolean isSourceVersionAtLeast9();

boolean isSourceVersionAtLeast19();

boolean isEclipseJDTCompiler();

boolean isJavacCompiler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
<@includeModel object=factoryMethod targetType=resultType/>
<#elseif enumSet>
EnumSet.noneOf( <@includeModel object=enumSetElementType raw=true/>.class )
<#else>
new
<#if resultType.implementationType??>
<@includeModel object=resultType.implementationType/><#if ext.useSizeIfPossible?? && ext.useSizeIfPossible && canUseSize>( <@sizeForCreation /> )<#else>()</#if>
<#elseif resultType.implementation??>
<#if resultType.implementation.factoryMethodName?? && ext.useSizeIfPossible?? && ext.useSizeIfPossible && canUseSize>
<@includeModel object=resultType.implementationType raw=true />.${resultType.implementation.factoryMethodName}( <@sizeForCreation /> )
<#else>
<@includeModel object=resultType/>()</#if>
new <@includeModel object=resultType.implementationType/><#if ext.useSizeIfPossible?? && ext.useSizeIfPossible && canUseSize>( <@sizeForCreation /> )<#else>()</#if>
</#if>
<#else>
new <@includeModel object=resultType/>()
</#if>
</@compress>
<#macro sizeForCreation>
<@compress single_line=true>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,8 @@ public Map<Class<?>, Class<?>> getServices() {
public Collection<String> getTestDependencies() {
return testDependencies;
}

public Compiler getCompiler() {
return compiler;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,15 @@ public class GeneratedSource implements BeforeTestExecutionCallback, AfterTestEx
*/
private ThreadLocal<String> sourceOutputDir = new ThreadLocal<>();

private Compiler compiler;

private List<Class<?>> fixturesFor = new ArrayList<>();

@Override
public void beforeTestExecution(ExtensionContext context) throws Exception {
CompilationRequest compilationRequest = context.getStore( NAMESPACE )
.get( context.getUniqueId() + "-compilationRequest", CompilationRequest.class );
this.compiler = compilationRequest.getCompiler();
setSourceOutputDir( context.getStore( NAMESPACE )
.get( compilationRequest, CompilationCache.class )
.getLastSourceOutputDir() );
Expand Down Expand Up @@ -118,13 +121,13 @@ public JavaFileAssert forJavaFile(String path) {

private void handleFixtureComparison() throws UnsupportedEncodingException {
for ( Class<?> fixture : fixturesFor ) {
String expectedFixture = FIXTURES_ROOT + getMapperName( fixture );
URL expectedFile = getClass().getClassLoader().getResource( expectedFixture );
String fixtureName = getMapperName( fixture );
URL expectedFile = getExpectedResource( fixtureName );
if ( expectedFile == null ) {
fail( String.format(
"No reference file could be found for Mapper %s. You should create a file %s",
fixture.getName(),
expectedFixture
FIXTURES_ROOT + fixtureName
) );
}
else {
Expand All @@ -135,4 +138,16 @@ private void handleFixtureComparison() throws UnsupportedEncodingException {
}

}

private URL getExpectedResource( String fixtureName ) {
ClassLoader classLoader = getClass().getClassLoader();
for ( int version = Runtime.version().feature(); version >= 11 && compiler != Compiler.ECLIPSE; version-- ) {
URL resource = classLoader.getResource( FIXTURES_ROOT + "/" + version + "/" + fixtureName );
if ( resource != null ) {
return resource;
}
}

return classLoader.getResource( FIXTURES_ROOT + fixtureName );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* 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._1453;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.processing.Generated;

@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2024-06-18T14:48:39+0200",
comments = "version: , compiler: javac, environment: Java 21.0.2 (Eclipse Adoptium)"
)
public class Issue1453MapperImpl implements Issue1453Mapper {

@Override
public AuctionDto map(Auction auction) {
if ( auction == null ) {
return null;
}

AuctionDto auctionDto = new AuctionDto();

auctionDto.setPayments( paymentListToPaymentDtoList( auction.getPayments() ) );
auctionDto.setOtherPayments( paymentListToPaymentDtoList( auction.getOtherPayments() ) );
auctionDto.setMapPayments( paymentPaymentMapToPaymentDtoPaymentDtoMap( auction.getMapPayments() ) );
auctionDto.setMapSuperPayments( paymentPaymentMapToPaymentDtoPaymentDtoMap( auction.getMapSuperPayments() ) );

return auctionDto;
}

@Override
public List<AuctionDto> mapExtend(List<? extends Auction> auctions) {
if ( auctions == null ) {
return null;
}

List<AuctionDto> list = new ArrayList<AuctionDto>( auctions.size() );
for ( Auction auction : auctions ) {
list.add( map( auction ) );
}

return list;
}

@Override
public List<? super AuctionDto> mapSuper(List<Auction> auctions) {
if ( auctions == null ) {
return null;
}

List<? super AuctionDto> list = new ArrayList<AuctionDto>( auctions.size() );
for ( Auction auction : auctions ) {
list.add( map( auction ) );
}

return list;
}

@Override
public Map<AuctionDto, AuctionDto> mapExtend(Map<? extends Auction, ? extends Auction> auctions) {
if ( auctions == null ) {
return null;
}

Map<AuctionDto, AuctionDto> map = LinkedHashMap.newLinkedHashMap( auctions.size() );

for ( java.util.Map.Entry<? extends Auction, ? extends Auction> entry : auctions.entrySet() ) {
AuctionDto key = map( entry.getKey() );
AuctionDto value = map( entry.getValue() );
map.put( key, value );
}

return map;
}

@Override
public Map<? super AuctionDto, ? super AuctionDto> mapSuper(Map<Auction, Auction> auctions) {
if ( auctions == null ) {
return null;
}

Map<? super AuctionDto, ? super AuctionDto> map = LinkedHashMap.newLinkedHashMap( auctions.size() );

for ( java.util.Map.Entry<Auction, Auction> entry : auctions.entrySet() ) {
AuctionDto key = map( entry.getKey() );
AuctionDto value = map( entry.getValue() );
map.put( key, value );
}

return map;
}

protected PaymentDto paymentToPaymentDto(Payment payment) {
if ( payment == null ) {
return null;
}

PaymentDto paymentDto = new PaymentDto();

paymentDto.setPrice( payment.getPrice() );

return paymentDto;
}

protected List<PaymentDto> paymentListToPaymentDtoList(List<Payment> list) {
if ( list == null ) {
return null;
}

List<PaymentDto> list1 = new ArrayList<PaymentDto>( list.size() );
for ( Payment payment : list ) {
list1.add( paymentToPaymentDto( payment ) );
}

return list1;
}

protected Map<PaymentDto, PaymentDto> paymentPaymentMapToPaymentDtoPaymentDtoMap(Map<Payment, Payment> map) {
if ( map == null ) {
return null;
}

Map<PaymentDto, PaymentDto> map1 = LinkedHashMap.newLinkedHashMap( map.size() );

for ( java.util.Map.Entry<Payment, Payment> entry : map.entrySet() ) {
PaymentDto key = paymentToPaymentDto( entry.getKey() );
PaymentDto value = paymentToPaymentDto( entry.getValue() );
map1.put( key, value );
}

return map1;
}
}
Loading

0 comments on commit 4d9894b

Please sign in to comment.