mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: find diamond types with pattern with explicit types
This commit is contained in:
+55
-27
@@ -719,6 +719,52 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
private static PsiTypeElement[] getTypeParameters(PsiJavaCodeReferenceElement referenceElement, boolean replaceDiamondWithExplicitTypes) {
|
||||
final PsiReferenceParameterList referenceElementParameterList = referenceElement.getParameterList();
|
||||
if (referenceElementParameterList == null) {
|
||||
return null;
|
||||
}
|
||||
final PsiTypeElement[] typeParameterElements = referenceElementParameterList.getTypeParameterElements();
|
||||
if (typeParameterElements.length != 1 || !replaceDiamondWithExplicitTypes) {
|
||||
return typeParameterElements;
|
||||
}
|
||||
final PsiType type = typeParameterElements[0].getType();
|
||||
if (!(type instanceof PsiDiamondType)) {
|
||||
return typeParameterElements;
|
||||
}
|
||||
final PsiDiamondType diamondType = (PsiDiamondType)type;
|
||||
final PsiDiamondType.DiamondInferenceResult inferenceResult = diamondType.resolveInferredTypes();
|
||||
final StringBuilder text = new StringBuilder(referenceElement.getQualifiedName());
|
||||
text.append('<');
|
||||
boolean comma = false;
|
||||
for (PsiType inferredType : inferenceResult.getInferredTypes()) {
|
||||
if (comma) {
|
||||
text.append(',');
|
||||
}
|
||||
else {
|
||||
comma = true;
|
||||
}
|
||||
text.append(inferredType.getCanonicalText());
|
||||
}
|
||||
text.append('>');
|
||||
final PsiJavaCodeReferenceElement newReferenceElement =
|
||||
JavaPsiFacade.getElementFactory(referenceElement.getProject()).createReferenceFromText(text.toString(), referenceElement);
|
||||
final PsiReferenceParameterList newParameterList = newReferenceElement.getParameterList();
|
||||
return newParameterList == null ? null : newParameterList.getTypeParameterElements();
|
||||
}
|
||||
|
||||
private static boolean hasDiamondTypeParameter(PsiElement element) {
|
||||
if (!(element instanceof PsiJavaCodeReferenceElement)) {
|
||||
return false;
|
||||
}
|
||||
final PsiJavaCodeReferenceElement javaCodeReferenceElement = (PsiJavaCodeReferenceElement)element;
|
||||
final PsiReferenceParameterList parameterList = javaCodeReferenceElement.getParameterList();
|
||||
if (parameterList == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiTypeElement[] elements = parameterList.getTypeParameterElements();
|
||||
return elements.length == 1 && elements[0].getType() instanceof PsiDiamondType;
|
||||
}
|
||||
|
||||
private boolean matchType(final PsiElement patternType, final PsiElement matchedType) {
|
||||
PsiElement patternElement = getInnermostComponent(patternType);
|
||||
@@ -726,10 +772,8 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
PsiElement[] typeParameters = null;
|
||||
if (matchedElement instanceof PsiJavaCodeReferenceElement) {
|
||||
final PsiReferenceParameterList parameterList = ((PsiJavaCodeReferenceElement)matchedElement).getParameterList();
|
||||
if (parameterList != null) {
|
||||
typeParameters = parameterList.getTypeParameterElements();
|
||||
}
|
||||
final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)matchedElement;
|
||||
typeParameters = getTypeParameters(referenceElement, !hasDiamondTypeParameter(patternElement));
|
||||
}
|
||||
else if (matchedElement instanceof PsiTypeParameter) {
|
||||
matchedElement = ((PsiTypeParameter)matchedElement).getNameIdentifier();
|
||||
@@ -821,13 +865,11 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
else {
|
||||
final PsiElement element2 = ((PsiJavaReference)matchedElement).resolve();
|
||||
|
||||
if (element2 instanceof PsiClass) {
|
||||
final String name = ((PsiClass)element2).getQualifiedName();
|
||||
return caseSensitive ? text.equals(name) : text.equalsIgnoreCase(name);
|
||||
}
|
||||
else {
|
||||
return MatchUtils.compareWithNoDifferenceToPackage(text, text2, !caseSensitive);
|
||||
if (!(element2 instanceof PsiClass)) {
|
||||
return false;
|
||||
}
|
||||
final String name = ((PsiClass)element2).getQualifiedName();
|
||||
return caseSensitive ? text.equals(name) : text.equalsIgnoreCase(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,27 +879,13 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
if (element instanceof PsiClass) {
|
||||
result = ((PsiClass)element).getQualifiedName();
|
||||
if (result == null) result = element.getText();
|
||||
} else if (element instanceof PsiJavaCodeReferenceElement) {
|
||||
result = ((PsiJavaCodeReferenceElement)element).getCanonicalText();
|
||||
} else {
|
||||
result = element.getText();
|
||||
}
|
||||
final int whitespace = lastIndexOfWhitespace(result);
|
||||
if (whitespace >= 0) {
|
||||
// strips off any annotations
|
||||
result = result.substring(whitespace + 1);
|
||||
}
|
||||
final int index = result.indexOf('<');
|
||||
if (index == -1) {
|
||||
return result;
|
||||
}
|
||||
return result.substring(0, index);
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
private static int lastIndexOfWhitespace(@NotNull CharSequence s) {
|
||||
for (int i = s.length() - 1; i >= 0; i--) {
|
||||
if (Character.isWhitespace(s.charAt(i))) return i;
|
||||
}
|
||||
return -1;
|
||||
return index == -1 ? result : result.substring(0, index);
|
||||
}
|
||||
|
||||
private boolean checkMatchWithingHierarchy(PsiElement el2, SubstitutionHandler handler, PsiElement context) {
|
||||
|
||||
+12
@@ -3467,4 +3467,16 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
assertEquals("find parameterized method calls 3", 3, findMatchesCount(source, "'_a.<'_b>'_c('_d*)"));
|
||||
assertEquals("find parameterized method calls 4", 4, findMatchesCount(source, "'_a.<'_b+>'_c('_d*)"));
|
||||
}
|
||||
|
||||
public void testFindDiamondTypes() {
|
||||
String source = "class A<X, Y> {}" +
|
||||
"class B {{" +
|
||||
" A<Integer, String> a1 = new A<>();" +
|
||||
" A<Integer, String> a2 = new A<Integer, String>();" +
|
||||
" A<Double, Boolean> a3 = new A<>();" +
|
||||
" A<Double, Boolean> a4 = new A<>();" +
|
||||
"}}";
|
||||
assertEquals("find diamond new expressions", 3, findMatchesCount(source, "new A<>()"));
|
||||
assertEquals("find parameterized new expressions", 2, findMatchesCount(source, "new A<Integer, String>()"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user