Skip to content

Commit c21a4d0

Browse files
committed
Fix Kotlin @ignored element pattern for @IgnoredList container support
The Kotlin element pattern for @ignored used `insideAnnotationParam` which only matches standalone annotations. Changed to use `insideRepeatableAnnotationParam` with `IGNORED_LIST_ANNOTATION_FQN` so references and completion work when @ignored is nested inside @IgnoredList. Also fixed `insideRepeatableAnnotationParam` in `KotlinElementPattern` to use `withAncestor(2, ...)` instead of `withParent(...)` to support array parameters like `targets = ["..."]` where a collection literal sits between the string and the value argument. Added tests for @IgnoredList in both Java and Kotlin: - Completion with @IgnoredList container (Java and Kotlin) - Standalone @ignored completion in Kotlin - TargetPropertyMappedMoreThanOnce inspection with @IgnoredList
1 parent df6867d commit c21a4d0

File tree

8 files changed

+178
-3
lines changed

8 files changed

+178
-3
lines changed

src/main/java/org/mapstruct/intellij/util/MapstructKotlinElementUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ public static KotlinElementPattern.Capture<? extends PsiElement> beanMappingElem
7070
public static KotlinElementPattern.Capture<? extends PsiElement> ignoredElementPattern(String parameterName) {
7171
return elementPattern(
7272
parameterName,
73-
MapstructUtil.IGNORED_ANNOTATION_FQN
73+
MapstructUtil.IGNORED_ANNOTATION_FQN,
74+
MapstructUtil.IGNORED_LIST_ANNOTATION_FQN
7475
);
7576
}
7677

src/main/java/org/mapstruct/intellij/util/patterns/KotlinElementPattern.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ public Self insideRepeatableAnnotationParam(
3737

3838
KtValueArgumentPattern ktValueArgumentPattern = ktValueArgument().withName( parameterName );
3939
return withElementType( KtStubElementTypes.STRING_TEMPLATE ).andOr(
40-
withParent(
40+
withAncestor(
41+
2,
4142
ktValueArgumentPattern
4243
.withAncestor( 5, ktAnnotation().qName( annotationHolderQualifiedName ) )
4344
),
4445

45-
withParent(
46+
withAncestor(
47+
2,
4648
ktValueArgumentPattern
4749
.withSuperParent( 2, ktAnnotation().qName( annotationQualifiedName ) )
4850
)

src/test/java/org/mapstruct/intellij/completion/IgnoredTargetsCompletionTestCase.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,37 @@ public void testIgnoredTargetsMultipleAnnotations() {
173173
"available"
174174
);
175175
}
176+
177+
public void testIgnoredTargetsWithIgnoredList() {
178+
configureByTestName();
179+
assertThat( myItems )
180+
.extracting( LookupElement::getLookupString )
181+
.containsExactlyInAnyOrder(
182+
"manufacturingYear",
183+
"myDriver",
184+
"passengers",
185+
"price",
186+
"category",
187+
"available"
188+
);
189+
}
190+
191+
public void testIgnoredTargetsNoPrefixKotlin() {
192+
configureByFile( "/" + getTestName( false ) + ".kt" );
193+
assertCarDtoAutoComplete();
194+
}
195+
196+
public void testIgnoredTargetsWithIgnoredListKotlin() {
197+
configureByFile( "/" + getTestName( false ) + ".kt" );
198+
assertThat( myItems )
199+
.extracting( LookupElement::getLookupString )
200+
.containsExactlyInAnyOrder(
201+
"manufacturingYear",
202+
"myDriver",
203+
"passengers",
204+
"price",
205+
"category",
206+
"available"
207+
);
208+
}
176209
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public void testTargetPropertyMappedMoreThanOnceWithIgnored() {
2828
doTest();
2929
}
3030

31+
public void testTargetPropertyMappedMoreThanOnceWithIgnoredList() {
32+
doTest();
33+
}
34+
3135
public void testTargetPropertyMappedMoreThanOnce() {
3236
doTest();
3337
String testName = getTestName( false );
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 https://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
package org.mapstruct.ap.test.complex
7+
8+
import org.mapstruct.Ignored
9+
import org.mapstruct.Mapper
10+
import org.example.dto.Car
11+
import org.example.dto.CarDtoKt
12+
13+
@Mapper
14+
interface IgnoredTargetsNoPrefixKotlin {
15+
16+
@Ignored(targets = ["<caret>"])
17+
fun carToCarDto(car: Car): CarDtoKt
18+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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.ap.test.complex;
7+
8+
import org.mapstruct.Ignored;
9+
import org.mapstruct.IgnoredList;
10+
import org.mapstruct.Mapper;
11+
import org.example.dto.Car;
12+
import org.example.dto.CarDto;
13+
14+
@Mapper
15+
public interface IgnoredTargetsWithIgnoredList {
16+
17+
@IgnoredList({
18+
@Ignored(targets = { "make", "seatCount" }),
19+
@Ignored(targets = { "<caret>" })
20+
})
21+
CarDto carToCarDto(Car car);
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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.ap.test.complex
7+
8+
import org.mapstruct.Ignored
9+
import org.mapstruct.IgnoredList
10+
import org.mapstruct.Mapper
11+
import org.example.dto.Car
12+
import org.example.dto.CarDtoKt
13+
14+
@Mapper
15+
interface IgnoredTargetsWithIgnoredListKotlin {
16+
17+
@IgnoredList(
18+
Ignored(targets = ["make", "seatCount"]),
19+
Ignored(targets = ["<caret>"])
20+
)
21+
fun carToCarDto(car: Car): CarDtoKt
22+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
7+
import org.mapstruct.Ignored;
8+
import org.mapstruct.IgnoredList;
9+
import org.mapstruct.Mapper;
10+
import org.mapstruct.Mapping;
11+
12+
class Source {
13+
private String name;
14+
15+
public String getName() {
16+
return name;
17+
}
18+
19+
public void setName(String name) {
20+
this.name = name;
21+
}
22+
}
23+
24+
class Target {
25+
private String testName;
26+
private String moreTarget;
27+
28+
public String getTestName() {
29+
return testName;
30+
}
31+
32+
public void setTestName(String testName) {
33+
this.testName = testName;
34+
}
35+
36+
public String getMoreTarget() {
37+
return moreTarget;
38+
}
39+
40+
public void setMoreTarget(String moreTarget) {
41+
this.moreTarget = moreTarget;
42+
}
43+
}
44+
45+
@Mapper
46+
interface MappingAndIgnoredListSameTargetMapper {
47+
48+
@Mapping(target = <error descr="Target property 'testName' must not be mapped more than once.">"testName"</error>, source = "name")
49+
@IgnoredList({
50+
@Ignored(targets = { <error descr="Target property 'testName' must not be mapped more than once.">"testName"</error> })
51+
})
52+
Target map(Source source);
53+
}
54+
55+
@Mapper
56+
interface IgnoredListDuplicateTargetMapper {
57+
58+
@IgnoredList({
59+
@Ignored(targets = { <error descr="Target property 'testName' must not be mapped more than once.">"testName"</error> }),
60+
@Ignored(targets = { <error descr="Target property 'testName' must not be mapped more than once.">"testName"</error> })
61+
})
62+
Target map(Source source);
63+
}
64+
65+
@Mapper
66+
interface IgnoredListNoConflictMapper {
67+
68+
@IgnoredList({
69+
@Ignored(targets = { "testName" }),
70+
@Ignored(targets = { "moreTarget" })
71+
})
72+
Target map(Source source);
73+
}

0 commit comments

Comments
 (0)