Skip to content

Commit 88ebd38

Browse files
committed
#163 Reference support for @InheritConfiguration and @InheritInverseConfiguration
1 parent 4b48a62 commit 88ebd38

13 files changed

+512
-47
lines changed

src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructBaseReference.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import static org.mapstruct.intellij.util.MapstructUtil.canDescendIntoType;
2727

2828
/**
29-
* A base reference to target / source annotation.
29+
* A base reference to annotations holding a reference and possibly nested types.
3030
*
3131
* @author Filip Hrisafov
3232
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
package org.mapstruct.intellij.codeinsight.references;
7+
8+
import java.util.Objects;
9+
10+
import com.intellij.openapi.util.TextRange;
11+
import com.intellij.psi.PsiElement;
12+
import com.intellij.psi.PsiMethod;
13+
import com.intellij.psi.PsiReference;
14+
import org.jetbrains.annotations.NotNull;
15+
import org.mapstruct.InheritConfiguration;
16+
import org.mapstruct.intellij.util.MapStructVersion;
17+
import org.mapstruct.intellij.util.MapstructUtil;
18+
19+
import static org.mapstruct.intellij.inspection.inheritance.InheritConfigurationUtils.findInheritConfigurationMethods;
20+
21+
/**
22+
* Reference for {@link InheritConfiguration#name()}.
23+
*
24+
* @author Oliver Erhart
25+
*/
26+
class MapstructMappingInheritConfigurationReference extends MapstructNonNestedBaseReference {
27+
28+
private final MapStructVersion mapStructVersion;
29+
30+
/**
31+
* Create a new {@link MapstructMappingInheritConfigurationReference} with the provided parameters
32+
*
33+
* @param element the element that the reference belongs to
34+
* @param previousReference the previous reference if there is one (in nested properties for example)
35+
* @param rangeInElement the range that the reference represent in the {@code element}
36+
* @param value the matched value (useful when {@code rangeInElement} is empty)
37+
*/
38+
private MapstructMappingInheritConfigurationReference(
39+
PsiElement element,
40+
MapstructMappingInheritConfigurationReference previousReference,
41+
TextRange rangeInElement, String value
42+
) {
43+
super( element, previousReference, rangeInElement, value );
44+
mapStructVersion = MapstructUtil.resolveMapStructProjectVersion( element.getContainingFile()
45+
.getOriginalFile() );
46+
}
47+
48+
@Override
49+
PsiElement resolveInternal(@NotNull String value, @NotNull PsiMethod mappingMethod) {
50+
51+
return findInheritConfigurationMethods( mappingMethod, mapStructVersion )
52+
.filter( a -> Objects.equals( a.getName(), value ) )
53+
.findAny()
54+
.orElse( null );
55+
}
56+
57+
@NotNull
58+
@Override
59+
Object[] getVariantsInternal(@NotNull PsiMethod mappingMethod) {
60+
61+
return findInheritConfigurationMethods( mappingMethod, mapStructVersion )
62+
.map( method -> MapstructUtil.asLookup( method, method.getName(), method.getName() ) )
63+
.filter( Objects::nonNull )
64+
.toArray();
65+
}
66+
67+
/**
68+
* @param psiElement the literal for which references need to be created
69+
* @return the references for the given {@code psiLiteral}
70+
*/
71+
static PsiReference[] create(PsiElement psiElement) {
72+
return MapstructBaseReference.create( psiElement, MapstructMappingInheritConfigurationReference::new, false );
73+
}
74+
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
package org.mapstruct.intellij.codeinsight.references;
7+
8+
import java.util.Objects;
9+
10+
import com.intellij.openapi.util.TextRange;
11+
import com.intellij.psi.PsiElement;
12+
import com.intellij.psi.PsiMethod;
13+
import com.intellij.psi.PsiReference;
14+
import org.jetbrains.annotations.NotNull;
15+
import org.mapstruct.InheritInverseConfiguration;
16+
import org.mapstruct.intellij.util.MapStructVersion;
17+
import org.mapstruct.intellij.util.MapstructUtil;
18+
19+
import static org.mapstruct.intellij.inspection.inheritance.InheritConfigurationUtils.findInheritInverseConfigurationMethods;
20+
21+
/**
22+
* Reference for {@link InheritInverseConfiguration#name()}.
23+
*
24+
* @author Oliver Erhart
25+
*/
26+
class MapstructMappingInheritInverseConfigurationReference extends MapstructNonNestedBaseReference {
27+
28+
private final MapStructVersion mapStructVersion;
29+
30+
/**
31+
* Create a new {@link MapstructMappingInheritInverseConfigurationReference} with the provided parameters
32+
*
33+
* @param element the element that the reference belongs to
34+
* @param previousReference the previous reference if there is one (in nested properties for example)
35+
* @param rangeInElement the range that the reference represent in the {@code element}
36+
* @param value the matched value (useful when {@code rangeInElement} is empty)
37+
*/
38+
private MapstructMappingInheritInverseConfigurationReference(
39+
PsiElement element,
40+
MapstructMappingInheritInverseConfigurationReference previousReference,
41+
TextRange rangeInElement,
42+
String value
43+
) {
44+
45+
super( element, previousReference, rangeInElement, value );
46+
mapStructVersion = MapstructUtil.resolveMapStructProjectVersion( element.getContainingFile()
47+
.getOriginalFile() );
48+
}
49+
50+
@Override
51+
PsiElement resolveInternal(@NotNull String value, @NotNull PsiMethod mappingMethod) {
52+
53+
return findInheritInverseConfigurationMethods( mappingMethod, mapStructVersion )
54+
.filter( a -> Objects.equals( a.getName(), value ) )
55+
.findAny()
56+
.orElse( null );
57+
}
58+
59+
@NotNull
60+
@Override
61+
Object[] getVariantsInternal(@NotNull PsiMethod mappingMethod) {
62+
63+
return findInheritInverseConfigurationMethods( mappingMethod, mapStructVersion )
64+
.map( method -> MapstructUtil.asLookup( method, method.getName(), method.getName() ) )
65+
.filter( Objects::nonNull )
66+
.toArray();
67+
}
68+
69+
/**
70+
* @param psiElement the literal for which references need to be created
71+
* @return the references for the given {@code psiLiteral}
72+
*/
73+
static PsiReference[] create(PsiElement psiElement) {
74+
return MapstructBaseReference.create(
75+
psiElement,
76+
MapstructMappingInheritInverseConfigurationReference::new,
77+
false
78+
);
79+
}
80+
81+
}

src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructMappingQualifiedByNameReference.java

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import java.util.Arrays;
99
import java.util.Objects;
1010
import java.util.Optional;
11-
import java.util.stream.Collectors;
1211
import java.util.stream.Stream;
1312

1413
import com.intellij.codeInsight.lookup.LookupElement;
@@ -18,7 +17,6 @@
1817
import com.intellij.psi.PsiClass;
1918
import com.intellij.psi.PsiElement;
2019
import com.intellij.psi.PsiMethod;
21-
import com.intellij.psi.PsiParameter;
2220
import com.intellij.psi.PsiReference;
2321
import com.intellij.psi.PsiType;
2422
import org.jetbrains.annotations.NotNull;
@@ -31,14 +29,13 @@
3129
import static org.mapstruct.intellij.util.MapstructUtil.NAMED_ANNOTATION_FQN;
3230
import static org.mapstruct.intellij.util.MapstructUtil.MAPPER_ANNOTATION_FQN;
3331
import static org.mapstruct.intellij.util.MapstructUtil.MAPPER_CONFIG_ANNOTATION_FQN;
34-
import static org.mapstruct.intellij.util.MapstructUtil.asLookupWithRepresentableText;
3532

3633
/**
3734
* Reference for {@link org.mapstruct.Mapping#qualifiedByName()}.
3835
*
3936
* @author Oliver Erhart
4037
*/
41-
class MapstructMappingQualifiedByNameReference extends MapstructBaseReference {
38+
class MapstructMappingQualifiedByNameReference extends MapstructNonNestedBaseReference {
4239

4340
/**
4441
* Create a new {@link MapstructMappingQualifiedByNameReference} with the provided parameters
@@ -54,11 +51,6 @@ private MapstructMappingQualifiedByNameReference(PsiElement element,
5451
super( element, previousReference, rangeInElement, value );
5552
}
5653

57-
@Override
58-
PsiElement resolveInternal(@NotNull String value, @NotNull PsiType psiType) {
59-
return null; // not needed
60-
}
61-
6254
@Override
6355
PsiElement resolveInternal(@NotNull String value, @NotNull PsiMethod mappingMethod) {
6456

@@ -80,12 +72,6 @@ private String getNamedValue(PsiMethod method) {
8072
return getStringAttributeValue( namedAnnotation, "value" );
8173
}
8274

83-
@NotNull
84-
@Override
85-
Object[] getVariantsInternal(@NotNull PsiType psiType) {
86-
return LookupElement.EMPTY_ARRAY; // not needed
87-
}
88-
8975
@NotNull
9076
@Override
9177
Object[] getVariantsInternal(@NotNull PsiMethod mappingMethod) {
@@ -139,31 +125,7 @@ private LookupElement methodAsLookup(@NotNull PsiMethod method) {
139125
return null;
140126
}
141127

142-
return asLookupWithRepresentableText(
143-
method,
144-
lookupString,
145-
lookupString,
146-
String.format(
147-
" %s#%s(%s)",
148-
Objects.requireNonNull( method.getContainingClass() ).getName(),
149-
method.getName(),
150-
formatParameters( method )
151-
)
152-
);
153-
}
154-
155-
@NotNull
156-
private static String formatParameters(@NotNull PsiMethod method) {
157-
return Arrays.stream( method.getParameterList().getParameters() )
158-
.map( PsiParameter::getType )
159-
.map( PsiType::getPresentableText )
160-
.collect( Collectors.joining( ", " ) );
161-
}
162-
163-
@Nullable
164-
@Override
165-
PsiType resolvedType() {
166-
return null;
128+
return MapstructUtil.asLookup( method, lookupString, lookupString );
167129
}
168130

169131
/**
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
package org.mapstruct.intellij.codeinsight.references;
7+
8+
import com.intellij.codeInsight.lookup.LookupElement;
9+
import com.intellij.openapi.util.TextRange;
10+
import com.intellij.psi.PsiElement;
11+
import com.intellij.psi.PsiType;
12+
import org.jetbrains.annotations.NotNull;
13+
import org.jetbrains.annotations.Nullable;
14+
15+
/**
16+
* A base reference to mapstruct annotations without nested types.
17+
*
18+
* @author Oliver Erhart
19+
*/
20+
public abstract class MapstructNonNestedBaseReference extends MapstructBaseReference {
21+
22+
/**
23+
* Create a reference.
24+
*
25+
* @param element the literal where the text is
26+
* @param previous the previous reference ({@code null} if there is no previous reference)
27+
* @param rangeInElement the range in the {@code element} for which this reference is valid
28+
*/
29+
MapstructNonNestedBaseReference(@NotNull PsiElement element,
30+
@Nullable MapstructBaseReference previous,
31+
TextRange rangeInElement, String value) {
32+
super( element, previous, rangeInElement, value );
33+
}
34+
35+
@Override
36+
final PsiElement resolveInternal(@NotNull String value, @NotNull PsiType psiType) {
37+
return null; // not needed
38+
}
39+
40+
@NotNull
41+
@Override
42+
final Object[] getVariantsInternal(@NotNull PsiType psiType) {
43+
return LookupElement.EMPTY_ARRAY; // not needed
44+
}
45+
46+
@Override
47+
@Nullable
48+
final PsiType resolvedType() {
49+
return null; // not needed
50+
}
51+
}

src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructReferenceContributor.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import org.jetbrains.annotations.NotNull;
1111

1212
import static org.mapstruct.intellij.util.MapstructElementUtils.beanMappingElementPattern;
13+
import static org.mapstruct.intellij.util.MapstructElementUtils.inheritConfigurationElementPattern;
14+
import static org.mapstruct.intellij.util.MapstructElementUtils.inheritInverseConfigurationElementPattern;
1315
import static org.mapstruct.intellij.util.MapstructElementUtils.mappingElementPattern;
1416
import static org.mapstruct.intellij.util.MapstructElementUtils.valueMappingElementPattern;
1517

@@ -48,6 +50,16 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar)
4850
valueMappingElementPattern( "target" ),
4951
new MappingTargetReferenceProvider( ValueMappingTargetReference::create )
5052
);
53+
54+
registrar.registerReferenceProvider(
55+
inheritConfigurationElementPattern( "name" ),
56+
new MappingTargetReferenceProvider( MapstructMappingInheritConfigurationReference::create )
57+
);
58+
registrar.registerReferenceProvider(
59+
inheritInverseConfigurationElementPattern( "name" ),
60+
new MappingTargetReferenceProvider( MapstructMappingInheritInverseConfigurationReference::create )
61+
);
62+
5163
}
5264

5365
}

0 commit comments

Comments
 (0)