mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#367 fix detection of overridden methods
This commit is contained in:
parent
d0b3ba071d
commit
0c26b78702
@ -23,6 +23,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
@ -184,21 +185,29 @@ public class Executables {
|
|||||||
*/
|
*/
|
||||||
public static List<ExecutableElement> getAllEnclosedExecutableElements(Elements elementUtils, TypeElement element) {
|
public static List<ExecutableElement> getAllEnclosedExecutableElements(Elements elementUtils, TypeElement element) {
|
||||||
List<ExecutableElement> enclosedElements = new ArrayList<ExecutableElement>();
|
List<ExecutableElement> enclosedElements = new ArrayList<ExecutableElement>();
|
||||||
addEnclosingElementsIncludingSuper( elementUtils, enclosedElements, element );
|
addEnclosingElementsIncludingSuper( elementUtils, enclosedElements, element, element );
|
||||||
|
|
||||||
return enclosedElements;
|
return enclosedElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addEnclosingElementsIncludingSuper(Elements elementUtils, List<ExecutableElement> alreadyAdded,
|
private static void addEnclosingElementsIncludingSuper(Elements elementUtils, List<ExecutableElement> alreadyAdded,
|
||||||
TypeElement element) {
|
TypeElement element, TypeElement parentType) {
|
||||||
addNotYetOverridden( elementUtils, alreadyAdded, methodsIn( element.getEnclosedElements() ) );
|
addNotYetOverridden( elementUtils, alreadyAdded, methodsIn( element.getEnclosedElements() ), parentType );
|
||||||
|
|
||||||
if ( hasNonObjectSuperclass( element ) ) {
|
if ( hasNonObjectSuperclass( element ) ) {
|
||||||
addEnclosingElementsIncludingSuper( elementUtils, alreadyAdded, asTypeElement( element.getSuperclass() ) );
|
addEnclosingElementsIncludingSuper(
|
||||||
|
elementUtils,
|
||||||
|
alreadyAdded,
|
||||||
|
asTypeElement( element.getSuperclass() ),
|
||||||
|
parentType );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( TypeMirror interfaceType : element.getInterfaces() ) {
|
for ( TypeMirror interfaceType : element.getInterfaces() ) {
|
||||||
addEnclosingElementsIncludingSuper( elementUtils, alreadyAdded, asTypeElement( interfaceType ) );
|
addEnclosingElementsIncludingSuper(
|
||||||
|
elementUtils,
|
||||||
|
alreadyAdded,
|
||||||
|
asTypeElement( interfaceType ),
|
||||||
|
parentType );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -207,12 +216,14 @@ public class Executables {
|
|||||||
* @param alreadyCollected methods that have already been collected and to which the not-yet-overridden methods will
|
* @param alreadyCollected methods that have already been collected and to which the not-yet-overridden methods will
|
||||||
* be added
|
* be added
|
||||||
* @param methodsToAdd methods to add to alreadyAdded, if they are not yet overridden by an element in the list
|
* @param methodsToAdd methods to add to alreadyAdded, if they are not yet overridden by an element in the list
|
||||||
|
* @param parentType the type for with elements are collected
|
||||||
*/
|
*/
|
||||||
private static void addNotYetOverridden(Elements elementUtils, List<ExecutableElement> alreadyCollected,
|
private static void addNotYetOverridden(Elements elementUtils, List<ExecutableElement> alreadyCollected,
|
||||||
List<ExecutableElement> methodsToAdd) {
|
List<ExecutableElement> methodsToAdd, TypeElement parentType) {
|
||||||
List<ExecutableElement> safeToAdd = new ArrayList<ExecutableElement>( methodsToAdd.size() );
|
List<ExecutableElement> safeToAdd = new ArrayList<ExecutableElement>( methodsToAdd.size() );
|
||||||
for ( ExecutableElement toAdd : methodsToAdd ) {
|
for ( ExecutableElement toAdd : methodsToAdd ) {
|
||||||
if ( isNotObjectEquals( toAdd ) && wasNotYetOverridden( elementUtils, alreadyCollected, toAdd ) ) {
|
if ( isNotObjectEquals( toAdd )
|
||||||
|
&& wasNotYetOverridden( elementUtils, alreadyCollected, toAdd, parentType ) ) {
|
||||||
safeToAdd.add( toAdd );
|
safeToAdd.add( toAdd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,15 +252,13 @@ public class Executables {
|
|||||||
* @param methods the list of already collected methods of one type hierarchy (order is from sub-types to
|
* @param methods the list of already collected methods of one type hierarchy (order is from sub-types to
|
||||||
* super-types)
|
* super-types)
|
||||||
* @param executable the method to check
|
* @param executable the method to check
|
||||||
*
|
* @param parentType the type for which elements are collected
|
||||||
* @return {@code true}, iff the given executable was not yet overridden by a method in the given list.
|
* @return {@code true}, iff the given executable was not yet overridden by a method in the given list.
|
||||||
*/
|
*/
|
||||||
private static boolean wasNotYetOverridden(Elements elementUtils, List<ExecutableElement> alreadyAdded,
|
private static boolean wasNotYetOverridden(Elements elementUtils, List<ExecutableElement> alreadyAdded,
|
||||||
ExecutableElement executable) {
|
ExecutableElement executable, TypeElement parentType) {
|
||||||
for ( ExecutableElement executableInSubtype : alreadyAdded ) {
|
for ( ExecutableElement executableInSubtype : alreadyAdded ) {
|
||||||
TypeElement declaringType = (TypeElement) executableInSubtype.getEnclosingElement();
|
if ( elementUtils.overrides( executableInSubtype, executable, parentType ) ) {
|
||||||
|
|
||||||
if ( elementUtils.overrides( executableInSubtype, executable, declaringType ) ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ import static org.fest.assertions.Assertions.assertThat;
|
|||||||
ReferencedMapperInterface.class,
|
ReferencedMapperInterface.class,
|
||||||
AbstractDto.class,
|
AbstractDto.class,
|
||||||
Identifiable.class,
|
Identifiable.class,
|
||||||
|
HasId.class,
|
||||||
|
AlsoHasId.class,
|
||||||
Measurable.class
|
Measurable.class
|
||||||
})
|
})
|
||||||
@RunWith(AnnotationProcessorTestRunner.class)
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2014 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.abstractclass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andreas Gudian
|
||||||
|
*/
|
||||||
|
public interface AlsoHasId {
|
||||||
|
Long getId();
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2014 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.abstractclass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andreas Gudian
|
||||||
|
*/
|
||||||
|
public interface HasId {
|
||||||
|
Long getId();
|
||||||
|
}
|
@ -19,9 +19,10 @@
|
|||||||
package org.mapstruct.ap.test.abstractclass;
|
package org.mapstruct.ap.test.abstractclass;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import javax.xml.ws.Holder;
|
import javax.xml.ws.Holder;
|
||||||
|
|
||||||
public class Source extends AbstractDto {
|
public class Source extends AbstractDto implements HasId, AlsoHasId {
|
||||||
|
|
||||||
private final int size;
|
private final int size;
|
||||||
private final Calendar birthday;
|
private final Calendar birthday;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user