From 545a78a12febda4d19a7bee6ea6bfa3e99e26487 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 14 Oct 2009 13:57:13 +0100 Subject: [PATCH] =?UTF-8?q?IDEADEV-40829=20"=E2=80=8BOriginal=20IntelliJ?= =?UTF-8?q?=20Cast"=20should=20not=20propose=20cast=20that=20is=20already?= =?UTF-8?q?=20present?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BasicExpressionCompletionContributor.java | 33 +++++++++++++++++-- ...erenceExpressionCompletionContributor.java | 14 +++++++- .../guess/impl/GuessManagerImpl.java | 7 ++-- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java index 3cccda00023c..375005195896 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java @@ -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() { + processDataflowExpressionTypes(position, expectedType, result.getPrefixMatcher(), new Consumer() { 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 consumer) { + public static void processDataflowExpressionTypes(PsiElement position, @Nullable PsiType expectedType, final PrefixMatcher matcher, Consumer consumer) { final PsiExpression context = PsiTreeUtil.getParentOfType(position, PsiExpression.class); if (context == null) return; final Map 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(); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java index 0ac18ff97fcd..ad326bb12581 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java @@ -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() { + BasicExpressionCompletionContributor.processDataflowExpressionTypes(element, null, TRUE_MATCHER, new Consumer() { public void consume(LookupElement baseItem) { addSecondCompletionVariants(element, reference, baseItem, parameters, result); } diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java index 9254fbd80115..ef229d0e292f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java @@ -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{