@@ -165,6 +165,10 @@ private LocatorResponse matchTypeNodeReturnComponent(Type node, String qualified
165165 return new LocatorResponse (defaultLevel , replacementFound , replacedNode , false , false );
166166 } else {
167167 int ret = typeParamMatches == TYPE_PARAMS_COUNT_MATCH ? ERASURE_MATCH : IMPOSSIBLE_MATCH ;
168+ boolean isErasurePattern = isPatternErasureMatch ();
169+ boolean isEquivPattern = isPatternEquivalentMatch ();
170+ if ( ret == ERASURE_MATCH && !isErasurePattern && !isEquivPattern )
171+ ret = IMPOSSIBLE_MATCH ;
168172 return new LocatorResponse (ret , replacementFound , replacedNode , false , false );
169173 }
170174 }
@@ -231,21 +235,26 @@ public LocatorResponse match(Type node, NodeSetWrapper nodeSet, MatchLocator loc
231235 level = IMPOSSIBLE_MATCH ;
232236
233237 if ( level != IMPOSSIBLE_MATCH ) {
234- Name n = getSimpleNameNodeFromType (node );
235- if ( n != null ) {
236-
237- nodeSet .addMatch (n , level );
238- return new LocatorResponse (level , true , n , true , true );
239- } else {
240- int v = nodeSet .addMatch (node , level );
241- return toResponse (v , true );
238+ if ( !preferParamaterizedNode () || patternPrefersSimpleName ()) {
239+ Name n = getSimpleNameNodeFromType (node );
240+ if ( n != null ) {
241+ nodeSet .addMatch (n , level );
242+ return new LocatorResponse (level , true , n , true , true );
243+ }
242244 }
245+ int v = nodeSet .addMatch (node , level );
246+ return toResponse (v , true );
243247 }
244248 }
245249 }
246250 return toResponse (IMPOSSIBLE_MATCH );
247251 }
248252
253+ private boolean patternPrefersSimpleName () {
254+ return false ;
255+ // char[] qual = this.locator.pattern.qualification;
256+ // return qual == null;
257+ }
249258 private boolean isPatternErasureMatch () {
250259 int r = this .locator .pattern .getMatchRule ();
251260 return (r & SearchPattern .R_ERASURE_MATCH ) == SearchPattern .R_ERASURE_MATCH ;
@@ -297,21 +306,41 @@ private int validateTypeParameters(Type node) {
297306 return TYPE_PARAMS_NO_MATCH ;
298307 }
299308 for ( int j = 0 ; j < thisLevelTypeParams .length ; j ++ ) {
300- String typeFromPattern = new String (thisLevelTypeParams [j ]);
301- IBinding patternTypeBinding = JdtCoreDomPackagePrivateUtility .findBindingForType (node , typeFromPattern );
302- IBinding b = DOMASTNodeUtils .getBinding ((ASTNode )typeArgs .get (j ));
303- String sig = b == null ? null : b instanceof JavacTypeBinding jctb ? jctb .getGenericTypeSignature (false ) : b .getKey ();
304- if ( sig .startsWith ("+" ) && b instanceof ITypeBinding tb ) {
305- boolean canContinue = validateOneTypeParameterExtends (typeFromPattern , sig , tb , patternTypeBinding );
309+ String patternSig = new String (thisLevelTypeParams [j ]);
310+ IBinding patternTypeBinding = JdtCoreDomPackagePrivateUtility .findBindingForType (node , patternSig );
311+ IBinding domBinding = DOMASTNodeUtils .getBinding ((ASTNode )typeArgs .get (j ));
312+ String domSig = domBinding == null ? null : domBinding instanceof JavacTypeBinding jctb ? jctb .getGenericTypeSignature (false ) : domBinding .getKey ();
313+ if ( patternSig .equals (("*" )))
314+ continue ;
315+ if ( patternSig .equals (domSig )) {
316+ continue ;
317+ }
318+ if ( domSig .startsWith ("+" ) && domBinding instanceof ITypeBinding domTypeBinding ) {
319+ boolean canContinue = validateOneTypeParameterExtends (domSig , domTypeBinding , patternSig , patternTypeBinding );
306320 if ( !canContinue ) {
307321 return TYPE_PARAMS_COUNT_MATCH ;
308322 }
309- } else if ( sig .startsWith ("-" ) && b instanceof ITypeBinding tb ) {
310- boolean canContinue = validateOneTypeParameterSuper (typeFromPattern , sig , tb , patternTypeBinding );
323+ } else if ( domSig .startsWith ("-" ) && domBinding instanceof ITypeBinding domTypeBinding ) {
324+ boolean canContinue = validateOneTypeParameterSuper (patternSig , patternTypeBinding , domSig , domTypeBinding );
311325 if ( !canContinue ) {
312326 return TYPE_PARAMS_COUNT_MATCH ;
313327 }
314- } else if ( !typeFromPattern .equals (sig )) {
328+ } else if ( patternSig .startsWith ("+" ) && patternTypeBinding instanceof ITypeBinding patternBinding ) {
329+ boolean canContinue = validateOneTypeParameterExtends (patternSig , patternBinding , domSig , domBinding );
330+ if ( !canContinue ) {
331+ return TYPE_PARAMS_COUNT_MATCH ;
332+ }
333+ } else if ( patternSig .startsWith ("-" ) && patternTypeBinding instanceof ITypeBinding patternBinding ) {
334+ boolean canContinue = validateOneTypeParameterSuper (domSig , domBinding , patternSig , patternBinding );
335+ if ( !canContinue ) {
336+ return TYPE_PARAMS_COUNT_MATCH ;
337+ }
338+ } else if ( patternSig .startsWith ("Q" )) {
339+ String patternSig2 = patternSig .substring (1 );
340+ if ( !patternSig2 .equals (domSig .substring (1 )) && !domSig .endsWith ("." + patternSig2 )) {
341+ return TYPE_PARAMS_COUNT_MATCH ;
342+ }
343+ } else if ( !patternSig .equals (domSig )) {
315344 return TYPE_PARAMS_COUNT_MATCH ;
316345 }
317346 }
@@ -333,21 +362,32 @@ private int validateTypeParameters(Type node) {
333362 return TYPE_PARAMS_MATCH ;
334363 }
335364
336- private boolean validateOneTypeParameterExtends (String typeFromPattern , String sig , ITypeBinding tb , IBinding patternTypeBinding ) {
337- boolean isQuestionMark = "+Ljava/lang/Object;" .equals (sig );
365+ private boolean validateOneTypeParameterExtends (String criteriaSignature , ITypeBinding criteriaBinding , String evaluateSignature , IBinding evaluateBinding ) {
366+ boolean isQuestionMark = "+Ljava/lang/Object;" .equals (criteriaSignature );
338367 if ( isQuestionMark ) {
339368 // TODO - if pattern is <Unresolved1,Unresolved2> we must return no_match
340369 return true ;
341370 }
342- String remaining = sig .substring (1 );
343- ITypeBinding [] bounds = tb .getTypeBounds ();
371+ boolean evaluateSigIsUnresolved = false ;
372+ String evaluateSigTrimmed = null ;
373+ if ( evaluateSignature .startsWith ("Q" )) {
374+ evaluateSigTrimmed = evaluateSignature .substring (1 );
375+ evaluateSigIsUnresolved = true ;
376+ } else if ( evaluateSignature .startsWith ("+Q" )) {
377+ evaluateSigTrimmed = evaluateSignature .substring (2 );
378+ evaluateSigIsUnresolved = true ;
379+ }
380+ ITypeBinding [] bounds = criteriaBinding .getTypeBounds ();
344381 if ( bounds != null && bounds .length == 1 && bounds [0 ] != null ) {
345382 ITypeBinding b1 = bounds [0 ];
346383 String boundSig = b1 == null ? null : b1 instanceof JavacTypeBinding jctb ? jctb .getGenericTypeSignature (false ) : b1 .getKey ();
347- if ( typeFromPattern .equals (boundSig )) {
384+ if ( evaluateSignature .equals (boundSig )) {
348385 return true ;
349386 }
350- if ( patternTypeBinding instanceof ITypeBinding itb ) {
387+ if ( evaluateSigIsUnresolved && boundSig .endsWith ("." + evaluateSigTrimmed )) {
388+ return true ;
389+ }
390+ if ( !evaluateSigIsUnresolved && evaluateBinding instanceof ITypeBinding itb ) {
351391 ITypeBinding working = itb ;
352392 while (working != null ) {
353393 ITypeBinding superClaz = working .getSuperclass ();
@@ -367,21 +407,43 @@ private boolean validateOneTypeParameterExtends(String typeFromPattern, String s
367407 return true ;
368408 }
369409
370- private boolean validateOneTypeParameterSuper (String typeFromPattern , String sig , ITypeBinding tb , IBinding patternTypeBinding ) {
371- String remaining = sig .substring (1 );
372- ITypeBinding b1 = tb .getBound ();
410+ private boolean validateOneTypeParameterSuper (String evaluateSig , IBinding evaluateBinding , String criteriaSig , ITypeBinding criteriaBinding ) {
411+ boolean evaluateSigIsUnresolved = evaluateSig .startsWith ("Q" );
412+ String evaluateSigTrimmed = evaluateSig .substring (1 );
413+ ITypeBinding b1 = criteriaBinding .getBound ();
373414 if ( b1 != null ) {
374415 String boundSig = b1 == null ? null : b1 instanceof JavacTypeBinding jctb ? jctb .getGenericTypeSignature (false ) : b1 .getKey ();
375- if ( typeFromPattern .equals (boundSig )) {
416+ if ( evaluateSig .equals (boundSig )) {
376417 return true ;
377418 }
378- if ( patternTypeBinding instanceof ITypeBinding itb ) {
419+ if (evaluateSigIsUnresolved ) {
379420 ITypeBinding working = b1 ;
380421 while (working != null ) {
381422 ITypeBinding superClaz = working .getSuperclass ();
382423 if ( superClaz != null ) {
383424 String superClazKey = b1 == null ? null : superClaz instanceof JavacTypeBinding jctb ? jctb .getGenericTypeSignature (false ) : superClaz .getKey ();
384- if ( superClazKey .equals (typeFromPattern )) {
425+ if ( superClazKey != null && superClazKey .length () > 0 ) {
426+ if ( superClazKey .equals (evaluateSig )) {
427+ return true ;
428+ }
429+ if ( superClazKey .substring (1 ).equals (evaluateSigTrimmed )) {
430+ return true ;
431+ }
432+ if ( superClazKey .endsWith ("." + evaluateSigTrimmed )) {
433+ return true ;
434+ }
435+ }
436+ }
437+ working = superClaz ;
438+ }
439+ return false ;
440+ } else if ( evaluateBinding instanceof ITypeBinding ) {
441+ ITypeBinding working = b1 ;
442+ while (working != null ) {
443+ ITypeBinding superClaz = working .getSuperclass ();
444+ if ( superClaz != null ) {
445+ String superClazKey = b1 == null ? null : superClaz instanceof JavacTypeBinding jctb ? jctb .getGenericTypeSignature (false ) : superClaz .getKey ();
446+ if ( superClazKey != null && superClazKey .equals (evaluateSig )) {
385447 return true ;
386448 }
387449 }
@@ -413,19 +475,16 @@ private String getQualifiedNameFromType(Type query) {
413475 }
414476
415477 private String getNameStringFromType (Type node ) {
416- if (node instanceof SimpleType simple ) {
417- if (simple .getName () instanceof SimpleName name ) {
418- return name .getIdentifier ();
419- }
420- if (simple .getName () instanceof QualifiedName name ) {
421- return name .getName ().getIdentifier ();
422- }
423- } else if (node instanceof QualifiedType qualified ) {
424- return qualified .getName ().getIdentifier ();
425- } else if ( node instanceof ParameterizedType ptt ) {
426- return getNameStringFromType (ptt .getType ());
478+ Name nnode = getNameNodeFromType (node );
479+ nnode = (nnode instanceof QualifiedName qn ? qn .getName () : nnode );
480+ return getNameStringFromNameObject (nnode );
481+ }
482+
483+ private String getNameStringFromNameObject (Name nnode ) {
484+ if (nnode instanceof SimpleName name ) {
485+ return name .getIdentifier ();
427486 }
428- return null ;
487+ return nnode == null ? null : nnode . toString () ;
429488 }
430489
431490 private org .eclipse .jdt .core .dom .Name getSimpleNameNodeFromType (Type node ) {
@@ -449,6 +508,18 @@ private org.eclipse.jdt.core.dom.Name getNameNodeFromType(Type node) {
449508 }
450509 return null ;
451510 }
511+
512+ private org .eclipse .jdt .core .dom .Name getQualifierNameNodeFromType (Type node ) {
513+ if (node instanceof SimpleType simple ) {
514+ return simple .getName ();
515+ } else if (node instanceof QualifiedType qualified ) {
516+ return getQualifierNameNodeFromType (qualified .getQualifier ());
517+ } else if ( node instanceof ParameterizedType ptt ) {
518+ return getQualifierNameNodeFromType (ptt .getType ());
519+ }
520+ return null ;
521+ }
522+
452523
453524 private String fqqnFromImport (String firstSegment ) {
454525 if ( firstSegment == null )
@@ -636,7 +707,7 @@ private int resolveLevelForTypeBindingWithTypeArguments(ITypeBinding typeBinding
636707 char [][][] patternTypeArgArray = this .locator .pattern .getTypeArguments ();
637708 int patternTypeArgsLength = patternTypeArgArray == null ? -1 :
638709 patternTypeArgArray [0 ] == null ? -1 :
639- patternTypeArgArray [0 ].length == 0 ? - 1 : patternTypeArgArray [ 0 ]. length ;
710+ patternTypeArgArray [0 ].length ;
640711 boolean bindingIsRaw = typeBinding .isRawType ();
641712 boolean bindingIsGeneric = typeBinding .isGenericType ();
642713 boolean bindingIsParameterized = typeBinding .isParameterizedType ();
@@ -793,6 +864,16 @@ protected int resolveLevelForType(ITypeBinding typeBinding) {
793864
794865 @ Override
795866 public void reportSearchMatch (MatchLocator locator , ASTNode node , SearchMatch match ) throws CoreException {
867+ // boolean matchIsEr = match.isErasure();
868+ // boolean matchIsEq = match.isEquivalent();
869+ // boolean matchIsEx = match.isExact();
870+ // boolean report = (this.isErasureMatch && match.isErasure())
871+ // || ((this.isErasureMatch || this.isEquivalentMatch) && match.isEquivalent())
872+ // || match.isExact();
873+ boolean report = (this .isErasureMatch && match .isErasure ()) || (this .isEquivalentMatch && match .isEquivalent ()) || match .isExact ();
874+ if (!report )
875+ return ;
876+
796877 ASTNode replacementNode = null ;
797878 if ( node instanceof QualifiedType qtt ) {
798879 replacementNode = findNodeMatchingPatternQualifier (qtt .getQualifier ());
@@ -809,17 +890,40 @@ public void reportSearchMatch(MatchLocator locator, ASTNode node, SearchMatch ma
809890 match .setLength (newLength );
810891 }
811892
812- // boolean matchIsEr = match.isErasure();
813- // boolean matchIsEq = match.isEquivalent();
814- // boolean matchIsEx = match.isExact();
815- // boolean report = (this.isErasureMatch && match.isErasure())
816- // || ((this.isErasureMatch || this.isEquivalentMatch) && match.isEquivalent())
817- // || match.isExact();
818- boolean report = (this .isErasureMatch && match .isErasure ()) || (this .isEquivalentMatch && match .isEquivalent ()) || match .isExact ();
819- if (!report ) return ;
820-
893+ ASTNode working = (replacementNode != null ? replacementNode : node );
894+ int trimQualifierStart = findTrimQualifierStart (working );
895+ if ( trimQualifierStart != -1 ) {
896+ int matchStart = match .getOffset ();
897+ int matchEnd = matchStart + match .getLength ();
898+ int newStart = trimQualifierStart ;
899+ int newLength = matchEnd - newStart ;
900+ match .setOffset (newStart );
901+ match .setLength (newLength );
902+ }
821903 SearchMatchingUtility .reportSearchMatch (locator , match );
822904 }
905+
906+
907+ private int findTrimQualifierStart (ASTNode working ) {
908+ String needle = this .locator .pattern .qualification == null ? null : new String (this .locator .pattern .qualification );
909+ if ( needle == null && working instanceof Type workingType ) {
910+ ASTNode n1 = getSimpleNameNodeFromType (workingType );
911+ if ( n1 != null ) {
912+ return n1 .getStartPosition ();
913+ }
914+ }
915+ if ( needle != null && working instanceof Type workingType ) {
916+ Name n = getQualifierNameNodeFromType (workingType );
917+ n = (n instanceof QualifiedName qn ? qn .getName () : n );
918+ String asString = getNameStringFromNameObject (n );
919+ if ( asString != null ) {
920+ if (this .locator .matchesName (this .locator .pattern .qualification , asString .toCharArray ())) {
921+ return n .getStartPosition ();
922+ }
923+ }
924+ }
925+ return -1 ;
926+ }
823927 private ASTNode findNodeMatchingPatternQualifier (Type qualifier ) {
824928 if ( qualifier instanceof ParameterizedType pt ) {
825929 return findNodeMatchingPatternQualifier (pt .getType ());
0 commit comments