IDEADEV-40829 "​Original IntelliJ Cast" should not propose cast that is already present

This commit is contained in:
peter
2009-10-14 23:43:29 +01:00
parent 72fd46bc9e
commit 545a78a12f
3 changed files with 47 additions and 7 deletions
@@ -27,7 +27,9 @@ import com.intellij.psi.*;
import com.intellij.psi.filters.ContextGetter;
import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
import com.intellij.psi.filters.getters.*;
import com.intellij.psi.scope.BaseScopeProcessor;
import com.intellij.psi.scope.ElementClassFilter;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Consumer;
import com.intellij.util.IncorrectOperationException;
@@ -108,7 +110,7 @@ public class BasicExpressionCompletionContributor extends ExpressionSmartComplet
}
}
processDataflowExpressionTypes(position, expectedType, new Consumer<LookupElement>() {
processDataflowExpressionTypes(position, expectedType, result.getPrefixMatcher(), new Consumer<LookupElement>() {
public void consume(LookupElement decorator) {
result.addElement(decorator);
}
@@ -125,11 +127,38 @@ public class BasicExpressionCompletionContributor extends ExpressionSmartComplet
}
public static void processDataflowExpressionTypes(PsiElement position, @Nullable PsiType expectedType, Consumer<LookupElement> consumer) {
public static void processDataflowExpressionTypes(PsiElement position, @Nullable PsiType expectedType, final PrefixMatcher matcher, Consumer<LookupElement> consumer) {
final PsiExpression context = PsiTreeUtil.getParentOfType(position, PsiExpression.class);
if (context == null) return;
final Map<PsiExpression,PsiType> map = GuessManager.getInstance(position.getProject()).getControlFlowExpressionTypes(context);
if (map.isEmpty()) {
return;
}
PsiScopesUtil.treeWalkUp(new BaseScopeProcessor() {
public boolean execute(PsiElement element, ResolveState state) {
if (element instanceof PsiLocalVariable) {
if (!matcher.prefixMatches(((PsiLocalVariable)element).getName())) {
return true;
}
final PsiExpression expression = ((PsiLocalVariable)element).getInitializer();
if (expression instanceof PsiTypeCastExpression) {
PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)expression;
final PsiExpression operand = typeCastExpression.getOperand();
if (operand != null) {
final PsiType dfaCasted = map.get(operand);
if (dfaCasted != null && dfaCasted.equals(typeCastExpression.getType())) {
map.remove(operand);
}
}
}
}
return true;
}
}, context, context.getContainingFile());
for (final PsiExpression expression : map.keySet()) {
final PsiType castType = map.get(expression);
final PsiType baseType = expression.getType();
@@ -57,6 +57,18 @@ public class ReferenceExpressionCompletionContributor extends ExpressionSmartCom
private static final PsiMethodPattern OBJECT_METHOD_PATTERN = psiMethod().withName(
PsiJavaPatterns.string().oneOf("hashCode", "equals", "finalize", "wait", "notify", "notifyAll", "getClass", "clone", "toString")).
definedInClass(CommonClassNames.JAVA_LANG_OBJECT);
private static final PrefixMatcher TRUE_MATCHER = new PrefixMatcher("") {
@Override
public boolean prefixMatches(@NotNull String name) {
return true;
}
@NotNull
@Override
public PrefixMatcher cloneWithPrefix(@NotNull String prefix) {
return this;
}
};
@NotNull
private static ElementFilter getReferenceFilter(PsiElement element, boolean allowRecursion) {
@@ -111,7 +123,7 @@ public class ReferenceExpressionCompletionContributor extends ExpressionSmartCom
if (isSecond) {
if (!psiElement().afterLeaf(".").accepts(element)) {
BasicExpressionCompletionContributor.processDataflowExpressionTypes(element, null, new Consumer<LookupElement>() {
BasicExpressionCompletionContributor.processDataflowExpressionTypes(element, null, TRUE_MATCHER, new Consumer<LookupElement>() {
public void consume(LookupElement baseItem) {
addSecondCompletionVariants(element, reference, baseItem, parameters, result);
}
@@ -162,10 +162,10 @@ public class GuessManagerImpl extends GuessManager {
getTopmostBlock(forPlace).accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitTypeCastExpression(PsiTypeCastExpression expression) {
final PsiTypeElement castType = expression.getCastType();
final PsiType castType = expression.getType();
final PsiExpression operand = expression.getOperand();
if (operand != null && castType != null) {
allCasts.put(operand, castType.getType());
allCasts.put(operand, castType);
}
super.visitTypeCastExpression(expression);
}
@@ -346,8 +346,7 @@ public class GuessManagerImpl extends GuessManager {
if (pattern.parameterIndex < 0){ // return value
if (methodCall.getParent() instanceof PsiTypeCastExpression &&
(rangeToIgnore == null || !rangeToIgnore.contains(methodCall.getTextRange()))) {
final PsiTypeElement castType = ((PsiTypeCastExpression)methodCall.getParent()).getCastType();
return castType == null ? null : castType.getType();
return ((PsiTypeCastExpression)methodCall.getParent()).getType();
}
}
else{