#2673: Fix optional wrapping pattern throwing exception when primitive types are present

MethodMatcher incorrectly reported that a primitive type matches a candidate for a type var
This commit is contained in:
Zegveld 2021-12-11 14:16:19 +01:00 committed by GitHub
parent 5de813c16f
commit ea45666d66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 2 deletions

View File

@ -10,7 +10,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.lang.model.type.DeclaredType; import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;
@ -239,6 +238,8 @@ public class MethodMatcher {
return true; return true;
} }
boolean foundAMatch = false;
for ( Type mthdParType : candidateMethod.getTypeParameters() ) { for ( Type mthdParType : candidateMethod.getTypeParameters() ) {
// typeFromCandidateMethod itself is a generic type, e.g. <T> String method( T par ); // typeFromCandidateMethod itself is a generic type, e.g. <T> String method( T par );
@ -256,6 +257,8 @@ public class MethodMatcher {
continue; continue;
} }
foundAMatch = true; // there is a rare case where we do not arrive here at all.
// resolved something at this point, a candidate can be fetched or created // resolved something at this point, a candidate can be fetched or created
TypeVarCandidate typeVarCandidate; TypeVarCandidate typeVarCandidate;
if ( candidates.containsKey( mthdParType ) ) { if ( candidates.containsKey( mthdParType ) ) {
@ -297,7 +300,7 @@ public class MethodMatcher {
return false; return false;
} }
} }
return true; return foundAMatch;
} }
/** /**

View File

@ -0,0 +1,66 @@
/*
* 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._2673;
import java.util.Optional;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author Ben Zegveld
*/
@Mapper
public interface Issue2673Mapper {
Issue2673Mapper INSTANCE = Mappers.getMapper( Issue2673Mapper.class );
Target map(Source source);
default <T> T map(Optional<T> opt) {
return opt.orElse( null );
}
default <T> Optional<T> map(T t) {
return Optional.ofNullable( t );
}
class Target {
private final int primitive;
private final String nonPrimitive;
public Target(int primitive, String nonPrimitive) {
this.primitive = primitive;
this.nonPrimitive = nonPrimitive;
}
public int getPrimitive() {
return primitive;
}
public String getNonPrimitive() {
return nonPrimitive;
}
}
class Source {
private final int primitive;
private final Optional<String> nonPrimitive;
public Source(int primitive, Optional<String> nonPrimitive) {
this.primitive = primitive;
this.nonPrimitive = nonPrimitive;
}
public int getPrimitive() {
return primitive;
}
public Optional<String> getNonPrimitive() {
return nonPrimitive;
}
}
}

View File

@ -0,0 +1,24 @@
/*
* 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._2673;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses;
/**
* @author Ben Zegveld
*/
@WithClasses({
Issue2673Mapper.class
})
class Issue2673Test {
@ProcessorTest
@IssueKey( "2673" )
void shouldCompile() {
}
}