Skip to content

Commit 1eaab98

Browse files
committed
Add quick fix for ignoring all unmapped target properties
Closes #43
1 parent 7e4a244 commit 1eaab98

12 files changed

+180
-16
lines changed

change-notes.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<h2>1.2.0</h2>
33
<ul>
44
<li>Support for public fields (auto completion and unmapped target / source inspection warnings)</li>
5+
<li>Quick Fix: Add ignore all unmapped target properties</li>
56
<li>Bug fix: Correctly resolve fluent Boolean accessor</li>
67
<li>Bug fix: Only treat public non-static getters and setters as accessors</li>
78
</ul>

src/main/java/org/mapstruct/intellij/inspection/UnmappedTargetPropertiesInspection.java

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
*/
66
package org.mapstruct.intellij.inspection;
77

8+
import java.util.ArrayList;
9+
import java.util.Collection;
10+
import java.util.Collections;
11+
import java.util.List;
812
import java.util.Set;
913
import java.util.function.Supplier;
1014
import java.util.stream.Collectors;
@@ -90,18 +94,26 @@ public void visitMethod(PsiMethod method) {
9094
.sorted()
9195
.collect( Collectors.joining( ", " ) )
9296
);
93-
UnmappedTargetPropertyFix[] quickFixes = allTargetProperties.stream()
97+
List<UnmappedTargetPropertyFix> quickFixes = new ArrayList<>( missingTargetProperties * 2 + 1 );
98+
99+
allTargetProperties.stream()
94100
.sorted()
95101
.flatMap( property -> Stream.of(
96102
createAddIgnoreUnmappedTargetPropertyFix( method, property ),
97103
createAddUnmappedTargetPropertyFix( method, property )
98104
) )
99-
.toArray( UnmappedTargetPropertyFix[]::new );
105+
.forEach( quickFixes::add );
106+
107+
if ( missingTargetProperties > 1 ) {
108+
// If there is more than one add ignore all
109+
quickFixes.add( createAddIgnoreAllUnmappedTargetPropertiesFix( method, allTargetProperties ) );
110+
}
111+
100112
//noinspection ConstantConditions
101113
holder.registerProblem(
102114
method.getNameIdentifier(),
103115
descriptionTemplate,
104-
quickFixes
116+
quickFixes.toArray( UnmappedTargetPropertyFix.EMPTY_ARRAY )
105117
);
106118
}
107119
}
@@ -137,14 +149,16 @@ private static PsiType getTargetType(PsiMethod method) {
137149

138150
private static class UnmappedTargetPropertyFix extends LocalQuickFixOnPsiElement {
139151

152+
private static final UnmappedTargetPropertyFix[] EMPTY_ARRAY = new UnmappedTargetPropertyFix[0];
153+
140154
private final String myText;
141155
private final String myFamilyName;
142-
private final Supplier<PsiAnnotation> myAnnotationSupplier;
156+
private final Supplier<Collection<PsiAnnotation>> myAnnotationSupplier;
143157

144158
private UnmappedTargetPropertyFix(@NotNull PsiMethod modifierListOwner,
145159
@NotNull String text,
146160
@NotNull String familyName,
147-
@NotNull Supplier<PsiAnnotation> annotationSupplier) {
161+
@NotNull Supplier<Collection<PsiAnnotation>> annotationSupplier) {
148162
super( modifierListOwner );
149163
myText = text;
150164
myFamilyName = familyName;
@@ -186,7 +200,9 @@ public void invoke(@NotNull Project project,
186200
@NotNull PsiElement endElement) {
187201
PsiMethod mappingMethod = (PsiMethod) startElement;
188202

189-
addMappingAnnotation( project, mappingMethod, myAnnotationSupplier.get() );
203+
for ( PsiAnnotation annotation : myAnnotationSupplier.get() ) {
204+
addMappingAnnotation( project, mappingMethod, annotation );
205+
}
190206
}
191207

192208
}
@@ -202,8 +218,10 @@ public void invoke(@NotNull Project project,
202218
*/
203219
private static UnmappedTargetPropertyFix createAddUnmappedTargetPropertyFix(PsiMethod method, String target) {
204220
String fqn = MapstructUtil.MAPPING_ANNOTATION_FQN;
205-
Supplier<PsiAnnotation> annotationSupplier = () -> JavaPsiFacade.getElementFactory( method.getProject() )
206-
.createAnnotationFromText( "@" + fqn + "(target = \"" + target + "\", source=\"\")", null );
221+
Supplier<Collection<PsiAnnotation>> annotationSupplier =
222+
() -> Collections.singleton( JavaPsiFacade.getElementFactory(
223+
method.getProject() )
224+
.createAnnotationFromText( "@" + fqn + "(target = \"" + target + "\", source=\"\")", null ) );
207225
String message = MapStructBundle.message( "inspection.add.unmapped.target.property", target );
208226
return new UnmappedTargetPropertyFix(
209227
method,
@@ -224,8 +242,10 @@ private static UnmappedTargetPropertyFix createAddUnmappedTargetPropertyFix(PsiM
224242
*/
225243
private static UnmappedTargetPropertyFix createAddIgnoreUnmappedTargetPropertyFix(PsiMethod method, String target) {
226244
String fqn = MapstructUtil.MAPPING_ANNOTATION_FQN;
227-
Supplier<PsiAnnotation> annotationSupplier = () -> JavaPsiFacade.getElementFactory( method.getProject() )
228-
.createAnnotationFromText( "@" + fqn + "(target = \"" + target + "\", ignore= true)", null );
245+
Supplier<Collection<PsiAnnotation>> annotationSupplier =
246+
() -> Collections.singleton( JavaPsiFacade.getElementFactory(
247+
method.getProject() )
248+
.createAnnotationFromText( "@" + fqn + "(target = \"" + target + "\", ignore= true)", null ) );
229249
String message = MapStructBundle.message( "inspection.add.ignore.unmapped.target.property", target );
230250
return new UnmappedTargetPropertyFix(
231251
method,
@@ -234,4 +254,37 @@ private static UnmappedTargetPropertyFix createAddIgnoreUnmappedTargetPropertyFi
234254
annotationSupplier
235255
);
236256
}
257+
258+
/**
259+
* Add ignore all unmapped properties fix. Property fix that adds {@link org.mapstruct.Mapping} annotations that
260+
* ignores all the given {@code targets}
261+
*
262+
* @param method the method to which the property needs to be added
263+
* @param targetProperties the names of the target properties that should be ignored
264+
*
265+
* @return the Local Quick fix
266+
*/
267+
private static UnmappedTargetPropertyFix createAddIgnoreAllUnmappedTargetPropertiesFix(PsiMethod method,
268+
Collection<String> targetProperties) {
269+
String fqn = MapstructUtil.MAPPING_ANNOTATION_FQN;
270+
Supplier<Collection<PsiAnnotation>> annotationSupplier = () -> {
271+
List<PsiAnnotation> annotations = new ArrayList<>( targetProperties.size() );
272+
targetProperties.stream()
273+
.sorted()
274+
.forEach( targetProperty -> annotations.add( JavaPsiFacade.getElementFactory( method.getProject() )
275+
.createAnnotationFromText(
276+
"@" + fqn + "(target = \"" + targetProperty + "\", ignore= true)",
277+
null
278+
) ) );
279+
return annotations;
280+
};
281+
String message = MapStructBundle.message( "inspection.add.ignore.all.unmapped.target.properties" );
282+
return new UnmappedTargetPropertyFix(
283+
method,
284+
message,
285+
MapStructBundle.message( "intention.add.ignore.all.unmapped.target.properties" ),
286+
annotationSupplier
287+
);
288+
}
289+
237290
}

src/main/resources/org/mapstruct/intellij/messages/MapStructBundle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
group.names.mapstruct.issues=MapStruct
2+
inspection.add.ignore.all.unmapped.target.properties=Ignore all unmapped target properties
23
inspection.add.ignore.unmapped.target.property=Ignore unmapped target property: ''{0}''
34
inspection.add.unmapped.target.property=Add unmapped target property: ''{0}''
45
inspection.missing.annotation=@Mapper or @MapperConfig annotation missing
@@ -10,5 +11,6 @@ inspection.wrong.usage.mappers.factory.non.mapstruct=Using mappers factory for n
1011
inspection.wrong.usage.mappers.factory.non.default=Using Mappers factory with non default component model
1112
inspection.wrong.usage.mappers.factory.remove.component.model=Remove ''{0}'' componentModel from ''{1}'' @Mapper
1213
inspection.wrong.usage.mappers.factory.remove.mappers.usage=Remove usage of Mappers factory
14+
intention.add.ignore.all.unmapped.target.properties=Add ignore all unmapped target properties
1315
intention.add.ignore.unmapped.target.property=Add ignore unmapped target property
1416
intention.add.unmapped.target.property=Add unmapped target property

src/test/java/org/mapstruct/intellij/inspection/UnmappedFluentTargetPropertiesInspectionTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ public void testUnmappedFluentTargetProperties() {
4949
"Add unmapped target property: 'moreTarget'",
5050
"Ignore unmapped target property: 'testName'",
5151
"Add unmapped target property: 'testName'",
52+
"Ignore all unmapped target properties",
5253
"Ignore unmapped target property: 'testName'",
5354
"Add unmapped target property: 'testName'",
5455
"Ignore unmapped target property: 'matching'",
5556
"Add unmapped target property: 'matching'",
5657
"Ignore unmapped target property: 'moreTarget'",
57-
"Add unmapped target property: 'moreTarget'"
58+
"Add unmapped target property: 'moreTarget'",
59+
"Ignore all unmapped target properties"
5860
);
5961

6062
allQuickFixes.forEach( myFixture::launchAction );
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
package org.mapstruct.intellij.inspection;
7+
8+
import java.util.List;
9+
10+
import com.intellij.codeInsight.intention.IntentionAction;
11+
import org.jetbrains.annotations.NotNull;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
15+
/**
16+
* @author Filip Hrisafov
17+
*/
18+
public class UnmappedIgnoreAllTargetPropertiesInspectionTest extends BaseInspectionTest {
19+
20+
@NotNull
21+
@Override
22+
protected Class<UnmappedTargetPropertiesInspection> getInspection() {
23+
return UnmappedTargetPropertiesInspection.class;
24+
}
25+
26+
@Override
27+
protected void setUp() throws Exception {
28+
super.setUp();
29+
myFixture.copyFileToProject(
30+
"UnmappedTargetPropertiesData.java",
31+
"org/example/data/UnmappedTargetPropertiesData.java"
32+
);
33+
}
34+
35+
public void testUnmappedIgnoreAllTargetProperties() {
36+
doTest();
37+
String testName = getTestName( false );
38+
List<IntentionAction> allQuickFixes = myFixture.getAllQuickFixes();
39+
40+
assertThat( allQuickFixes )
41+
.extracting( IntentionAction::getText )
42+
.as( "Intent Text" )
43+
.containsExactly(
44+
"Ignore unmapped target property: 'moreTarget'",
45+
"Add unmapped target property: 'moreTarget'",
46+
"Ignore unmapped target property: 'testName'",
47+
"Add unmapped target property: 'testName'",
48+
"Ignore all unmapped target properties"
49+
);
50+
51+
myFixture.launchAction( allQuickFixes.get( 4 ) );
52+
myFixture.checkResultByFile( testName + "_after.java" );
53+
}
54+
}

src/test/java/org/mapstruct/intellij/inspection/UnmappedTargetPropertiesInspectionTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,19 @@ public void testUnmappedTargetProperties() {
5656
"Add unmapped target property: 'moreTarget'",
5757
"Ignore unmapped target property: 'testName'",
5858
"Add unmapped target property: 'testName'",
59+
"Ignore all unmapped target properties",
5960
"Ignore unmapped target property: 'moreTarget'",
6061
"Add unmapped target property: 'moreTarget'",
6162
"Ignore unmapped target property: 'testName'",
6263
"Add unmapped target property: 'testName'",
64+
"Ignore all unmapped target properties",
6365
"Ignore unmapped target property: 'testName'",
6466
"Add unmapped target property: 'testName'",
6567
"Ignore unmapped target property: 'matching'",
6668
"Add unmapped target property: 'matching'",
6769
"Ignore unmapped target property: 'moreTarget'",
68-
"Add unmapped target property: 'moreTarget'"
70+
"Add unmapped target property: 'moreTarget'",
71+
"Ignore all unmapped target properties"
6972
);
7073

7174
allQuickFixes.forEach( myFixture::launchAction );

src/test/java/org/mapstruct/intellij/inspection/UnmappedTargetPropertiesJdk8InspectionTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ public void testUnmappedTargetPropertiesJdk8() {
4949
"Add unmapped target property: 'moreTarget'",
5050
"Ignore unmapped target property: 'testName'",
5151
"Add unmapped target property: 'testName'",
52+
"Ignore all unmapped target properties",
5253
"Ignore unmapped target property: 'testName'",
5354
"Add unmapped target property: 'testName'",
5455
"Ignore unmapped target property: 'matching'",
5556
"Add unmapped target property: 'matching'",
5657
"Ignore unmapped target property: 'moreTarget'",
57-
"Add unmapped target property: 'moreTarget'"
58+
"Add unmapped target property: 'moreTarget'",
59+
"Ignore all unmapped target properties"
5860
);
5961

6062
allQuickFixes.forEach( myFixture::launchAction );

testData/inspection/UnmappedFluentTargetProperties_after.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ interface SingleMappingMapper {
4040
@Mapper
4141
interface NoMappingMapper {
4242

43+
@Mapping(target = "testName", ignore = true)
44+
@Mapping(target = "moreTarget", ignore = true)
4345
@Mapping(target = "testName", source = "")
4446
@Mapping(target = "testName", ignore = true)
4547
@Mapping(target = "moreTarget", source = "")
@@ -70,6 +72,8 @@ interface UpdateMapper {
7072
@Mapper
7173
interface MultiSourceUpdateMapper {
7274

75+
@Mapping(target = "moreTarget", ignore = true)
76+
@Mapping(target = "matching", ignore = true)
7377
@Mapping(target = "moreTarget", source = "")
7478
@Mapping(target = "moreTarget", ignore = true)
7579
@Mapping(target = "matching", source = "")
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
7+
import org.mapstruct.Mapper;
8+
import org.example.data.UnmappedTargetPropertiesData.Target;
9+
import org.example.data.UnmappedTargetPropertiesData.Source;
10+
11+
@Mapper
12+
interface NoMappingsMapper {
13+
14+
Target <warning descr="Unmapped target properties: moreTarget, testName">map</warning>(Source source);
15+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
7+
import org.mapstruct.Mapper;
8+
import org.example.data.UnmappedTargetPropertiesData.Target;
9+
import org.example.data.UnmappedTargetPropertiesData.Source;
10+
import org.mapstruct.Mapping;
11+
12+
@Mapper
13+
interface NoMappingsMapper {
14+
15+
@Mapping(target = "testName", ignore = true)
16+
@Mapping(target = "moreTarget", ignore = true)
17+
Target map(Source source);
18+
}

0 commit comments

Comments
 (0)