55 */
66package org .mapstruct .intellij .codeinsight .references ;
77
8+ import java .util .function .Function ;
9+
810import com .intellij .codeInsight .lookup .LookupElement ;
911import com .intellij .openapi .util .TextRange ;
1012import com .intellij .psi .ElementManipulator ;
1113import com .intellij .psi .ElementManipulators ;
1214import com .intellij .psi .PsiElement ;
15+ import com .intellij .psi .PsiLiteralExpression ;
1316import com .intellij .psi .PsiMethod ;
1417import com .intellij .psi .PsiReference ;
18+ import com .intellij .psi .PsiReferenceExpression ;
1519import com .intellij .psi .PsiType ;
20+ import com .intellij .psi .util .PsiTreeUtil ;
1621import com .intellij .util .IncorrectOperationException ;
1722import org .jetbrains .annotations .NotNull ;
1823import org .jetbrains .annotations .Nullable ;
2833abstract class MapstructBaseReference extends BaseReference {
2934
3035 private final MapstructBaseReference previous ;
36+ private final String value ;
3137
3238 /**
3339 * Create a reference.
@@ -37,9 +43,19 @@ abstract class MapstructBaseReference extends BaseReference {
3743 * @param rangeInElement the range in the {@code element} for which this reference is valid
3844 */
3945 MapstructBaseReference (@ NotNull PsiElement element ,
40- @ Nullable MapstructBaseReference previous , TextRange rangeInElement ) {
46+ @ Nullable MapstructBaseReference previous , TextRange rangeInElement , String value ) {
4147 super ( element , rangeInElement );
4248 this .previous = previous ;
49+ this .value = value ;
50+ }
51+
52+ @ Override
53+ @ NotNull
54+ public String getValue () {
55+ if ( value != null ) {
56+ return value ;
57+ }
58+ return super .getValue ();
4359 }
4460
4561 @ Nullable
@@ -152,30 +168,74 @@ private static ElementManipulator<PsiElement> getManipulator(PsiElement psiEleme
152168 */
153169 static <T extends MapstructBaseReference > PsiReference [] create (PsiElement psiElement ,
154170 ReferenceCreator <T > creator , boolean supportsNested ) {
155- ElementManipulator <PsiElement > manipulator = getManipulator ( psiElement );
156- TextRange rangeInElement = manipulator .getRangeInElement ( psiElement );
157- String targetValue = rangeInElement .substring ( psiElement .getText () );
171+ String targetValue ;
172+ Function <String , TextRange > rangeCreator ;
173+ if ( psiElement instanceof PsiReferenceExpression ) {
174+ PsiElement resolvedPsiElement = ( (PsiReferenceExpression ) psiElement ).resolve ();
175+
176+ PsiLiteralExpression expression = PsiTreeUtil .findChildOfType (
177+ resolvedPsiElement ,
178+ PsiLiteralExpression .class
179+ );
180+
181+ if ( expression == null ) {
182+ return PsiReference .EMPTY_ARRAY ;
183+ }
184+
185+ ElementManipulator <PsiElement > manipulator = getManipulator ( expression );
186+ TextRange rangeInElement = manipulator .getRangeInElement ( expression );
187+ targetValue = rangeInElement .substring ( expression .getText () );
188+ rangeCreator = part -> TextRange .EMPTY_RANGE ;
189+
190+ }
191+ else {
192+ ElementManipulator <PsiElement > manipulator = getManipulator ( psiElement );
193+ TextRange rangeInElement = manipulator .getRangeInElement ( psiElement );
194+ targetValue = rangeInElement .substring ( psiElement .getText () );
195+
196+ rangeCreator = new RangeCreator ( rangeInElement .getStartOffset () );
197+
198+ }
199+
158200 String [] parts = supportsNested ? targetValue .split ( "\\ ." ) : new String [] { targetValue };
159201 if ( parts .length == 0 ) {
160202 return PsiReference .EMPTY_ARRAY ;
161203 }
162- int nextStart = rangeInElement .getStartOffset ();
163204
164205 PsiReference [] references = new PsiReference [parts .length ];
165206 T lastReference = null ;
166207
167208 for ( int i = 0 ; i < parts .length ; i ++ ) {
168209 String part = parts [i ];
210+ lastReference = creator .create ( psiElement , lastReference , rangeCreator .apply ( part ), part );
211+ references [i ] = lastReference ;
212+ }
213+
214+ return references ;
215+ }
216+
217+ private static class RangeCreator implements Function <String , TextRange > {
218+
219+ private int nextStart ;
220+ private boolean first = true ;
221+
222+ private RangeCreator (int nextStart ) {
223+ this .nextStart = nextStart ;
224+ }
225+
226+ @ Override
227+ public TextRange apply (String part ) {
169228 int endOffset = nextStart + part .length ();
170- if ( i != 0 ) {
229+ if ( ! first ) {
171230 nextStart ++;
172231 endOffset ++;
173232 }
174- lastReference = creator .create ( psiElement , lastReference , new TextRange ( nextStart , endOffset ) );
233+ else {
234+ first = false ;
235+ }
236+ TextRange range = new TextRange ( nextStart , endOffset );
175237 nextStart = endOffset ;
176- references [ i ] = lastReference ;
238+ return range ;
177239 }
178-
179- return references ;
180240 }
181241}
0 commit comments