diff --git a/README.md b/README.md
index 000ea87d..c1c16d24 100644
--- a/README.md
+++ b/README.md
@@ -26,8 +26,10 @@ To learn more about MapStruct have a look at the [mapstruct](https://github.com/
* Completion of `target` and `source` properties in `@ValueMapping` annotation
* Completion of `componentModel` in `@Mapper` and `@MapperConfig` annotations
* Completion of `qualifiedByName` in `@Mapping` annotation
+ * Completion of `name` in `@InheritConfiguration` and `@InheritInverseConfiguration` annotations
* Go To Declaration for properties in `target` and `source` to setters / getters
* Go To Declaration for `Mapping#qualifiedByName`
+* Go To Declaration for `name` in `@InheritConfiguration` and `@InheritInverseConfiguration` annotations
* Find usages of properties in `target` and `source` and find usages of setters / getters in `@Mapping` annotations
* Highlighting properties in `target` and `source`
* Errors and Quick fixes:
@@ -41,6 +43,7 @@ To learn more about MapStruct have a look at the [mapstruct](https://github.com/
* `*` used as a source in `@Mapping` annotation with quick fixes: Replace `*` with method parameter name.
* Unknown reference inspection for `source` and `target` in `@Mapping` and `@ValueMapping` annotation.
* Unknown reference inspection for `qualifiedByName` in `@Mapping` annotation
+ * Unknown reference inspection for `name` in `@InheritConfiguration` and `@InheritInverseConfiguration` annotations
## Requirements
diff --git a/description.html b/description.html
index 7c30808c..efc133c7 100644
--- a/description.html
+++ b/description.html
@@ -25,11 +25,13 @@
Completion of target and source properties in @ValueMapping annotation
Completion of componentModel in @Mapper and @MapperConfig annotations
Completion of qualifiedByName in @Mapping annotation
+ Completion of name in @InheritConfiguration and @InheritInverseConfiguration annotations
Go To Declaration for properties in target and source to setters / getters
Find usages of properties in target and source and find usages of setters / getters in @Mapping annotations
Go To Declaration for Mapping#qualifiedByName
+ Go To Declaration for name in @InheritConfiguration and @InheritInverseConfiguration annotations
Highlighting properties in target and source
Refactoring support for properties and methods renaming
Errors and Quick Fixes:
@@ -45,6 +47,7 @@
* used as a source in @Mapping annotations with quick fixes: Replace * with method parameter name.
Unknown reference inspection for source and target in @Mapping and @ValueMapping annotation.
Unknown reference inspection for qualifiedByName in @Mapping annotation.
+ Unknown reference inspection for name in @InheritConfiguration and @InheritInverseConfiguration annotations.
diff --git a/src/main/java/org/mapstruct/intellij/codeinsight/references/InheritConfigurationNameReference.java b/src/main/java/org/mapstruct/intellij/codeinsight/references/InheritConfigurationNameReference.java
new file mode 100644
index 00000000..734c9b36
--- /dev/null
+++ b/src/main/java/org/mapstruct/intellij/codeinsight/references/InheritConfigurationNameReference.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.intellij.codeinsight.references;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiAnnotation;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.mapstruct.intellij.MapStructBundle;
+import org.mapstruct.intellij.inspection.inheritance.SourceMethod;
+
+import static org.mapstruct.intellij.inspection.inheritance.InheritConfigurationUtils.findMappingMethodsFromInheritScope;
+import static org.mapstruct.intellij.util.MapstructUtil.MAPPER_ANNOTATION_FQN;
+import static org.mapstruct.intellij.util.MapstructUtil.asLookupWithRepresentableText;
+import static org.mapstruct.intellij.util.TargetUtils.getRelevantType;
+
+/**
+ * Reference for {@link org.mapstruct.InheritConfiguration#name()} and
+ * {@link org.mapstruct.InheritInverseConfiguration#name()}.
+ *
+ * @author hduelme
+ */
+public class InheritConfigurationNameReference extends MapstructBaseReference {
+
+ private final boolean inverse;
+
+ /**
+ * Create a new {@link InheritConfigurationNameReference} with the provided parameters
+ *
+ * @param element the element that the reference belongs to
+ * @param previousReference the previous reference if there is one (in nested properties for example)
+ * @param rangeInElement the range that the reference represent in the {@code element}
+ * @param value the matched value (useful when {@code rangeInElement} is empty)
+ * @param inverse whether this is the inverse variant ({@link org.mapstruct.InheritInverseConfiguration})
+ */
+ private InheritConfigurationNameReference(PsiElement element,
+ InheritConfigurationNameReference previousReference,
+ TextRange rangeInElement,
+ String value,
+ boolean inverse) {
+ super( element, previousReference, rangeInElement, value );
+ this.inverse = inverse;
+ }
+
+ @Override
+ PsiElement resolveInternal(@NotNull String value, @NotNull PsiType psiType) {
+ return null; // not needed
+ }
+
+ @Override
+ PsiElement resolveInternal(@NotNull String value, @NotNull PsiMethod mappingMethod) {
+
+ java.util.List namedCandidates = candidatesInScope( mappingMethod )
+ .filter( candidate -> value.equals( candidate.getName() ) )
+ .distinct()
+ .toList();
+
+ // Match the disambiguation rule of InheritConfigurationUtils#getResultMethod:
+ // a name value is only valid if it identifies exactly one in-scope candidate.
+ if ( namedCandidates.size() != 1 ) {
+ return null;
+ }
+
+ return namedCandidates.getFirst().getNameIdentifier();
+ }
+
+ @NotNull
+ private Stream candidatesInScope(@NotNull PsiMethod mappingMethod) {
+ return inScopeMethods( mappingMethod )
+ .filter( candidateFilter( mappingMethod ) )
+ .filter( m -> !m.equals( mappingMethod ) )
+ .distinct();
+ }
+
+ @NotNull
+ @Override
+ Object[] getVariantsInternal(@NotNull PsiType psiType) {
+ return LookupElement.EMPTY_ARRAY; // not needed
+ }
+
+ @NotNull
+ @Override
+ Object[] getVariantsInternal(@NotNull PsiMethod mappingMethod) {
+ return candidatesInScope( mappingMethod )
+ .map( this::methodAsLookup )
+ .filter( Objects::nonNull )
+ .toArray();
+ }
+
+ @Nullable
+ private LookupElement methodAsLookup(@NotNull PsiMethod method) {
+ String lookupString = method.getName();
+ if ( lookupString.isEmpty() ) {
+ return null;
+ }
+
+ PsiClass containingClass = method.getContainingClass();
+ String classSimpleName = containingClass != null ? containingClass.getName() : "?";
+
+ return asLookupWithRepresentableText(
+ method,
+ lookupString,
+ lookupString,
+ String.format(
+ " %s#%s(%s)",
+ classSimpleName,
+ method.getName(),
+ formatParameters( method )
+ )
+ );
+ }
+
+ @NotNull
+ private Stream inScopeMethods(@NotNull PsiMethod mappingMethod) {
+ PsiClass containingClass = mappingMethod.getContainingClass();
+ if ( containingClass == null ) {
+ return Stream.empty();
+ }
+
+ PsiAnnotation mapperAnnotation = containingClass.getAnnotation( MAPPER_ANNOTATION_FQN );
+ if ( mapperAnnotation == null ) {
+ return Stream.empty();
+ }
+
+ return findMappingMethodsFromInheritScope( containingClass, mapperAnnotation );
+ }
+
+ @NotNull
+ private Predicate candidateFilter(@NotNull PsiMethod mappingMethod) {
+ PsiType targetType = getRelevantType( mappingMethod );
+ SourceMethod sourceMethod = new SourceMethod( mappingMethod );
+ if ( inverse ) {
+ return candidate -> candidate.getBody() == null && sourceMethod.inverses( candidate, targetType );
+ }
+ return candidate -> candidate.getBody() == null && sourceMethod.canInheritFrom( candidate, targetType );
+ }
+
+ @NotNull
+ private static String formatParameters(@NotNull PsiMethod method) {
+ return Arrays.stream( method.getParameterList().getParameters() )
+ .map( PsiParameter::getType )
+ .map( PsiType::getPresentableText )
+ .collect( java.util.stream.Collectors.joining( ", " ) );
+ }
+
+ @Nullable
+ @Override
+ PsiType resolvedType() {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public String getUnresolvedMessagePattern() {
+ return MapStructBundle.message(
+ inverse ? "unknown.inheritInverseConfiguration.reference" : "unknown.inheritConfiguration.reference"
+ );
+ }
+
+ /**
+ * @param psiElement the literal for which references need to be created
+ * @return the references for the given {@code psiLiteral}
+ */
+ static PsiReference[] createForward(PsiElement psiElement) {
+ return MapstructBaseReference.create( psiElement,
+ InheritConfigurationNameReference::newForward,
+ false );
+ }
+
+ /**
+ * @param psiElement the literal for which references need to be created
+ * @return the references for the given {@code psiLiteral}
+ */
+ static PsiReference[] createInverse(PsiElement psiElement) {
+ return MapstructBaseReference.create( psiElement,
+ InheritConfigurationNameReference::newInverse,
+ false );
+ }
+
+ private static InheritConfigurationNameReference newForward(PsiElement element,
+ InheritConfigurationNameReference previous,
+ TextRange range,
+ String value) {
+ return new InheritConfigurationNameReference( element, previous, range, value, false );
+ }
+
+ private static InheritConfigurationNameReference newInverse(PsiElement element,
+ InheritConfigurationNameReference previous,
+ TextRange range,
+ String value) {
+ return new InheritConfigurationNameReference( element, previous, range, value, true );
+ }
+
+}
diff --git a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructReferenceContributor.java b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructReferenceContributor.java
index f2edb1fc..96d25e85 100644
--- a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructReferenceContributor.java
+++ b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructReferenceContributor.java
@@ -10,6 +10,8 @@
import org.jetbrains.annotations.NotNull;
import static org.mapstruct.intellij.util.MapstructElementUtils.beanMappingElementPattern;
+import static org.mapstruct.intellij.util.MapstructElementUtils.inheritConfigurationElementPattern;
+import static org.mapstruct.intellij.util.MapstructElementUtils.inheritInverseConfigurationElementPattern;
import static org.mapstruct.intellij.util.MapstructElementUtils.mappingElementPattern;
import static org.mapstruct.intellij.util.MapstructElementUtils.valueMappingElementPattern;
@@ -48,6 +50,15 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar)
valueMappingElementPattern( "target" ),
new MappingTargetReferenceProvider( ValueMappingTargetReference::create )
);
+
+ registrar.registerReferenceProvider(
+ inheritConfigurationElementPattern( "name" ),
+ new MappingTargetReferenceProvider( InheritConfigurationNameReference::createForward )
+ );
+ registrar.registerReferenceProvider(
+ inheritInverseConfigurationElementPattern( "name" ),
+ new MappingTargetReferenceProvider( InheritConfigurationNameReference::createInverse )
+ );
}
}
diff --git a/src/main/java/org/mapstruct/intellij/inspection/MapstructReferenceInspection.java b/src/main/java/org/mapstruct/intellij/inspection/MapstructReferenceInspection.java
index d96ecf2c..364d5e23 100644
--- a/src/main/java/org/mapstruct/intellij/inspection/MapstructReferenceInspection.java
+++ b/src/main/java/org/mapstruct/intellij/inspection/MapstructReferenceInspection.java
@@ -22,6 +22,7 @@
import org.jetbrains.annotations.Nullable;
import org.mapstruct.intellij.codeinsight.references.BaseReference;
import org.mapstruct.intellij.codeinsight.references.BaseValueMappingReference;
+import org.mapstruct.intellij.codeinsight.references.InheritConfigurationNameReference;
import org.mapstruct.intellij.util.MapstructUtil;
/**
@@ -75,6 +76,11 @@ private boolean shouldRegisterProblem(BaseReference reference) {
return valueMappingReference.getEnumClass() != null;
}
+ if ( reference instanceof InheritConfigurationNameReference ) {
+ // The name attribute references a method name, not a property that could be a map key.
+ return true;
+ }
+
if ( hasSingleStringKeyMapSourceParameter( reference.getMappingMethod() ) ) {
// MapStruct allows source values as map keys, even if they are not resolvable as Java properties.
// Therefore, we don't report an unresolved reference problem here.
diff --git a/src/main/java/org/mapstruct/intellij/inspection/inheritance/InheritConfigurationUtils.java b/src/main/java/org/mapstruct/intellij/inspection/inheritance/InheritConfigurationUtils.java
index 06f8e146..84f1573f 100644
--- a/src/main/java/org/mapstruct/intellij/inspection/inheritance/InheritConfigurationUtils.java
+++ b/src/main/java/org/mapstruct/intellij/inspection/inheritance/InheritConfigurationUtils.java
@@ -294,7 +294,7 @@ private static Set getApplicablePrototypeMethods(SourceMethod mapp
* @param mapperAnnotation the mapper annotation of the containing class
* @return possible mapping methods to be inherited from
*/
- private static Stream findMappingMethodsFromInheritScope(@NotNull PsiClass containingClass,
+ public static Stream findMappingMethodsFromInheritScope(@NotNull PsiClass containingClass,
@NotNull PsiAnnotation mapperAnnotation) {
Stream localAndParentMethods = Arrays.stream( containingClass.getAllMethods() );
diff --git a/src/main/java/org/mapstruct/intellij/util/MapstructElementUtils.java b/src/main/java/org/mapstruct/intellij/util/MapstructElementUtils.java
index 7d041c20..ac0c5cdc 100644
--- a/src/main/java/org/mapstruct/intellij/util/MapstructElementUtils.java
+++ b/src/main/java/org/mapstruct/intellij/util/MapstructElementUtils.java
@@ -69,6 +69,25 @@ public static PsiJavaElementPattern.Capture beanMappingElementPatter
return elementPattern( parameterName, MapstructUtil.BEAN_MAPPING_FQN );
}
+ /**
+ * @param parameterName the name of the parameter in the {@code @InheritConfiguration} annotation
+ *
+ * @return an element pattern for a parameter in the {@code @InheritConfiguration} annotation
+ */
+ public static PsiJavaElementPattern.Capture inheritConfigurationElementPattern(String parameterName) {
+ return elementPattern( parameterName, MapstructUtil.INHERIT_CONFIGURATION_FQN );
+ }
+
+ /**
+ * @param parameterName the name of the parameter in the {@code @InheritInverseConfiguration} annotation
+ *
+ * @return an element pattern for a parameter in the {@code @InheritInverseConfiguration} annotation
+ */
+ public static PsiJavaElementPattern.Capture inheritInverseConfigurationElementPattern(
+ String parameterName) {
+ return elementPattern( parameterName, MapstructUtil.INHERIT_INVERSE_CONFIGURATION_FQN );
+ }
+
private static PsiJavaElementPattern.Capture elementPattern(String parameterName,
String annotationFQN) {
return psiElement()
diff --git a/src/main/resources/org/mapstruct/intellij/messages/MapStructBundle.properties b/src/main/resources/org/mapstruct/intellij/messages/MapStructBundle.properties
index 9a5608bd..7b51e5f4 100644
--- a/src/main/resources/org/mapstruct/intellij/messages/MapStructBundle.properties
+++ b/src/main/resources/org/mapstruct/intellij/messages/MapStructBundle.properties
@@ -47,3 +47,5 @@ plugin.settings.quickFix.preferSourceBeforeTargetInMapping=Prefer source before
unknown.property=Unknown property ''{0}''
unknown.enum.constant=Unknown enum constant ''{0}''
unknown.qualifiedByName.reference=Unknown @Named reference ''{0}''
+unknown.inheritConfiguration.reference=Unknown @InheritConfiguration method ''{0}''
+unknown.inheritInverseConfiguration.reference=Unknown @InheritInverseConfiguration method ''{0}''
diff --git a/src/test/java/org/mapstruct/intellij/completion/InheritConfigurationCompletionTestCase.java b/src/test/java/org/mapstruct/intellij/completion/InheritConfigurationCompletionTestCase.java
new file mode 100644
index 00000000..3bbc7206
--- /dev/null
+++ b/src/test/java/org/mapstruct/intellij/completion/InheritConfigurationCompletionTestCase.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.intellij.completion;
+
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementPresentation;
+import org.mapstruct.intellij.MapstructBaseCompletionTestCase;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mapstruct.intellij.testutil.TestUtils.createMethod;
+
+public class InheritConfigurationCompletionTestCase extends MapstructBaseCompletionTestCase {
+
+ @Override
+ protected String getTestDataPath() {
+ return "testData/completion/inheritconfiguration";
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ addDirectoryToProject( "../../mapping/dto" );
+ }
+
+ public void testInheritConfigurationByNameCompletion() {
+ configureByTestName();
+ assertThat( myItems )
+ .extracting( LookupElement::getLookupString )
+ .containsExactlyInAnyOrder( "carDtoToCarIgnoringSeatCount", "carDtoToCarIgnoringManufacturingDate" );
+
+ assertThat( myItems )
+ .extracting( LookupElementPresentation::renderElement )
+ .usingRecursiveFieldByFieldElementComparator()
+ .containsExactlyInAnyOrder(
+ createMethod(
+ "carDtoToCarIgnoringSeatCount",
+ "Car",
+ " InheritConfigurationCompletion#carDtoToCarIgnoringSeatCount(CarDto)"
+ ),
+ createMethod(
+ "carDtoToCarIgnoringManufacturingDate",
+ "Car",
+ " InheritConfigurationCompletion#carDtoToCarIgnoringManufacturingDate(CarDto)"
+ )
+ );
+ }
+
+ public void testInheritConfigurationWithMapperConfigCompletion() {
+ configureByTestName();
+ assertThat( myItems )
+ .extracting( LookupElement::getLookupString )
+ .containsExactlyInAnyOrder( "configSourceToTarget", "configSourceToTargetIgnoringSeats" );
+
+ assertThat( myItems )
+ .extracting( LookupElementPresentation::renderElement )
+ .usingRecursiveFieldByFieldElementComparator()
+ .containsExactlyInAnyOrder(
+ createMethod(
+ "configSourceToTarget",
+ "Car",
+ " ConfigCompleteMapperConfig#configSourceToTarget(CarDto)"
+ ),
+ createMethod(
+ "configSourceToTargetIgnoringSeats",
+ "Car",
+ " ConfigCompleteMapperConfig#configSourceToTargetIgnoringSeats(CarDto)"
+ )
+ );
+ }
+
+ public void testInheritInverseConfigurationByNameCompletion() {
+ configureByTestName();
+ assertThat( myItems )
+ .extracting( LookupElement::getLookupString )
+ .containsExactlyInAnyOrder( "carToCarDto", "carToCarDtoIgnoringDriver" );
+
+ assertThat( myItems )
+ .extracting( LookupElementPresentation::renderElement )
+ .usingRecursiveFieldByFieldElementComparator()
+ .containsExactlyInAnyOrder(
+ createMethod(
+ "carToCarDto",
+ "CarDto",
+ " InheritInverseConfigurationByNameCompletion#carToCarDto(Car)"
+ ),
+ createMethod(
+ "carToCarDtoIgnoringDriver",
+ "CarDto",
+ " InheritInverseConfigurationByNameCompletion#carToCarDtoIgnoringDriver(Car)"
+ )
+ );
+ }
+
+}
diff --git a/src/test/java/org/mapstruct/intellij/inspection/MapstructReferenceInspectionTest.java b/src/test/java/org/mapstruct/intellij/inspection/MapstructReferenceInspectionTest.java
index 97703559..67c2ec1f 100644
--- a/src/test/java/org/mapstruct/intellij/inspection/MapstructReferenceInspectionTest.java
+++ b/src/test/java/org/mapstruct/intellij/inspection/MapstructReferenceInspectionTest.java
@@ -49,4 +49,20 @@ public void testUnknownIgnoreUnmappedSourceReference() {
public void testUnknownQualifiedByNameReferenceReference() {
doTest();
}
+
+ public void testUnknownInheritConfigurationNameReference() {
+ doTest();
+ }
+
+ public void testUnknownInheritConfigurationNameReferenceWithMapSource() {
+ doTest();
+ }
+
+ public void testUnknownInheritInverseConfigurationNameReference() {
+ doTest();
+ }
+
+ public void testInheritConfigurationWithMapperConfigReference() {
+ doTest();
+ }
}
diff --git a/testData/completion/inheritconfiguration/InheritConfigurationByNameCompletion.java b/testData/completion/inheritconfiguration/InheritConfigurationByNameCompletion.java
new file mode 100644
index 00000000..819d8b5c
--- /dev/null
+++ b/testData/completion/inheritconfiguration/InheritConfigurationByNameCompletion.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.test.complex;
+
+import org.example.dto.Car;
+import org.example.dto.CarDto;
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.ReportingPolicy;
+
+@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
+public interface InheritConfigurationCompletion {
+
+ @Mapping(target = "numberOfSeats", ignore = true)
+ @Mapping(target = "manufacturingDate", source = "manufacturingYear")
+ @Mapping(target = "free", source = "available")
+ Car carDtoToCarIgnoringSeatCount(CarDto car);
+
+ @Mapping(target = "manufacturingDate", ignore = true)
+ @Mapping(target = "free", source = "available")
+ @Mapping(target = "driver", source = "myDriver")
+ @Mapping(target = "numberOfSeats", source = "seatCount")
+ Car carDtoToCarIgnoringManufacturingDate(CarDto car);
+
+ @InheritConfiguration(name = "")
+ void carDtoIntoCar(CarDto carDto, @MappingTarget Car car);
+
+}
diff --git a/testData/completion/inheritconfiguration/InheritConfigurationWithMapperConfigCompletion.java b/testData/completion/inheritconfiguration/InheritConfigurationWithMapperConfigCompletion.java
new file mode 100644
index 00000000..6d397aea
--- /dev/null
+++ b/testData/completion/inheritconfiguration/InheritConfigurationWithMapperConfigCompletion.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.test.complex;
+
+import org.example.dto.Car;
+import org.example.dto.CarDto;
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.MapperConfig;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+
+@MapperConfig
+interface ConfigCompleteMapperConfig {
+
+ @Mapping(target = "manufacturingDate", source = "manufacturingYear")
+ @Mapping(target = "free", source = "available")
+ Car configSourceToTarget(CarDto carDto);
+
+ @Mapping(target = "numberOfSeats", source = "seatCount")
+ @Mapping(target = "free", source = "available")
+ @Mapping(target = "driver", source = "myDriver")
+ Car configSourceToTargetIgnoringSeats(CarDto carDto);
+
+}
+
+@Mapper(config = ConfigCompleteMapperConfig.class)
+interface InheritConfigurationWithMapperConfigCompletion {
+
+ @InheritConfiguration(name = "")
+ void carDtoIntoCar(CarDto carDto, @MappingTarget Car car);
+
+}
diff --git a/testData/completion/inheritconfiguration/InheritInverseConfigurationByNameCompletion.java b/testData/completion/inheritconfiguration/InheritInverseConfigurationByNameCompletion.java
new file mode 100644
index 00000000..65e54bb4
--- /dev/null
+++ b/testData/completion/inheritconfiguration/InheritInverseConfigurationByNameCompletion.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.test.complex;
+
+import org.example.dto.Car;
+import org.example.dto.CarDto;
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.ReportingPolicy;
+
+@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
+public interface InheritInverseConfigurationByNameCompletion {
+
+ @Mapping(target = "numberOfSeats", ignore = true)
+ @Mapping(target = "manufacturingDate", source = "manufacturingYear")
+ CarDto carToCarDto(Car car);
+
+ @Mapping(target = "driver", ignore = true)
+ CarDto carToCarDtoIgnoringDriver(Car car);
+
+ @InheritInverseConfiguration(name = "")
+ Car carDtoToCar(CarDto carDto, @MappingTarget Car car);
+
+}
diff --git a/testData/inspection/InheritConfigurationWithMapperConfigReference.java b/testData/inspection/InheritConfigurationWithMapperConfigReference.java
new file mode 100644
index 00000000..f8a91d8b
--- /dev/null
+++ b/testData/inspection/InheritConfigurationWithMapperConfigReference.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.MapperConfig;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.ReportingPolicy;
+
+class SourceForConfig {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+
+class TargetForConfig {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+
+@MapperConfig
+interface InheritConfigurationWithMapperConfig {
+
+ @Mapping(target = "name", source = "name")
+ TargetForConfig configSourceToTarget(SourceForConfig source);
+
+}
+
+@Mapper(config = InheritConfigurationWithMapperConfig.class,
+ unmappedTargetPolicy = ReportingPolicy.WARN)
+interface MapperThatReferencesConfig {
+
+ @InheritConfiguration(name = "configSourceToTarget")
+ void sourceIntoTarget(SourceForConfig source, @MappingTarget TargetForConfig target);
+
+ @InheritConfiguration(name = "doesNotExist")
+ void sourceIntoAnotherTarget(SourceForConfig source, @MappingTarget TargetForConfig target);
+
+}
diff --git a/testData/inspection/UnknownInheritConfigurationNameReference.java b/testData/inspection/UnknownInheritConfigurationNameReference.java
new file mode 100644
index 00000000..4aab48d3
--- /dev/null
+++ b/testData/inspection/UnknownInheritConfigurationNameReference.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.ReportingPolicy;
+
+class Source {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+
+class Target {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+
+@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
+interface InheritConfigurationUnknownNameMapper {
+
+ @Mapping(target = "name", source = "name")
+ Target sourceToTarget(Source source);
+
+ @InheritConfiguration(name = "doesNotExist")
+ void sourceIntoTarget(Source source, @MappingTarget Target target);
+
+ @InheritConfiguration(name ="")
+ void sourceIntoAnotherTarget(Source source, @MappingTarget Target target);
+
+}
diff --git a/testData/inspection/UnknownInheritConfigurationNameReferenceWithMapSource.java b/testData/inspection/UnknownInheritConfigurationNameReferenceWithMapSource.java
new file mode 100644
index 00000000..778d14e7
--- /dev/null
+++ b/testData/inspection/UnknownInheritConfigurationNameReferenceWithMapSource.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+
+import java.util.Map;
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.ReportingPolicy;
+
+interface InheritConfigurationMapSource {
+
+ class Source {
+
+ private String value;
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+
+ class Target {
+
+ private String value;
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+}
+
+@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
+interface InheritConfigurationMapSourceMapper {
+
+ @Mapping(target = "value", source = "source.value")
+ InheritConfigurationMapSource.Target mapToTarget(Map source);
+
+ @InheritConfiguration(name = "doesNotExist")
+ void copyIntoTarget(Map source, @MappingTarget InheritConfigurationMapSource.Target target);
+
+}
diff --git a/testData/inspection/UnknownInheritInverseConfigurationNameReference.java b/testData/inspection/UnknownInheritInverseConfigurationNameReference.java
new file mode 100644
index 00000000..7783f3ea
--- /dev/null
+++ b/testData/inspection/UnknownInheritInverseConfigurationNameReference.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
+ */
+
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.ReportingPolicy;
+
+class Source {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+
+class Target {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+
+@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
+interface InheritInverseConfigurationUnknownNameMapper {
+
+ @Mapping(target = "name", source = "name")
+ Source targetToSource(Target target);
+
+ @InheritInverseConfiguration(name = "doesNotExist")
+ Target inverse(Source source);
+
+ @InheritInverseConfiguration(name ="")
+ Target inverseAnother(Source source);
+
+}