Inline inner: rise conflict for getClass invocation (IDEA-39608)

This commit is contained in:
anna
2010-02-01 17:13:33 +03:00
parent 7a8e58a984
commit 172de67c03
3 changed files with 46 additions and 13 deletions
@@ -134,7 +134,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
}
public MultiMap<PsiElement, String> getConflicts(final UsageInfo[] usages) {
MultiMap<PsiElement, String> result = new MultiMap<PsiElement, String>();
final MultiMap<PsiElement, String> result = new MultiMap<PsiElement, String>();
ReferencedElementsCollector collector = new ReferencedElementsCollector() {
protected void checkAddMember(@NotNull final PsiMember member) {
if (PsiTreeUtil.isAncestor(myClass, member, false)) {
@@ -150,17 +150,13 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
}
};
InlineMethodProcessor.addInaccessibleMemberConflicts(myClass, usages, collector, result);
for (UsageInfo usage : usages) {
final PsiElement element = usage.getElement();
if (element == null) continue;
final PsiElement parent = element.getParent();
if (parent == null) continue;
if (parent instanceof PsiNewExpression && PsiTreeUtil.isAncestor(myClass, parent, false)) {
result.putValue(parent, "Class cannot be inlined because a call to its constructor inside body");
}
final PsiElement grandPa = parent.getParent();
if (grandPa instanceof PsiParameter && PsiTreeUtil.isAncestor(myClass, grandPa, false)) {
for (PsiReference psiReference : ReferencesSearch.search(grandPa)) {
myClass.accept(new JavaRecursiveElementVisitor(){
@Override
public void visitParameter(PsiParameter parameter) {
super.visitParameter(parameter);
if (PsiUtil.resolveClassInType(parameter.getType()) != myClass) return;
for (PsiReference psiReference : ReferencesSearch.search(parameter)) {
final PsiElement refElement = psiReference.getElement();
if (refElement instanceof PsiExpression) {
final PsiReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(refElement, PsiReferenceExpression.class);
@@ -178,7 +174,29 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
}
}
}
}
@Override
public void visitNewExpression(PsiNewExpression expression) {
super.visitNewExpression(expression);
if (PsiUtil.resolveClassInType(expression.getType()) != myClass) return;
result.putValue(expression, "Class cannot be inlined because a call to its constructor inside body");
}
@Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
if (qualifierExpression != null && PsiUtil.resolveClassInType(qualifierExpression.getType()) != myClass) return;
final PsiElement resolved = methodExpression.resolve();
if (resolved instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)resolved;
if ("getClass".equals(method.getName()) && method.getParameterList().getParametersCount() == 0) {
result.putValue(methodExpression, "Result of getClass() invocation would be changed");
}
}
}
});
return result;
}
@@ -0,0 +1,11 @@
class Simple {
void foo(Simple s) {
final Class<? extends Simple> aClass = getClass();
final Class<? extends Simple> aClass1 = s.getClass();
final Class<? extends String> nonConflictStrClass = "".getClass();
}
}
class Usage {
Simple s = new Sim<caret>ple();
}
@@ -337,6 +337,10 @@ public class InlineToAnonymousClassTest extends LightCodeInsightTestCase {
"Field <b><code>C2.a</code></b> that is used in inlined method is not accessible from call site(s) in method <b><code>C2User.test()</code></b>");
}
public void testGetClassConflict() throws Exception {
doTestConflict("Result of getClass() invocation would be changed", "Result of getClass() invocation would be changed");
}
public void doTestConflict(final String... expected) throws Exception {
InlineToAnonymousClassProcessor processor = prepareProcessor();
UsageInfo[] usages = processor.findUsages();