summaryrefslogtreecommitdiff
path: root/java/java-impl/src/com/intellij/codeInsight
diff options
context:
space:
mode:
Diffstat (limited to 'java/java-impl/src/com/intellij/codeInsight')
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java58
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java6
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java39
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java43
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAbstractMethodFromUsageFix.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java19
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java14
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java13
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java54
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java42
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java11
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java11
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/impl/ShortenToStaticImportProcessor.java13
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java12
20 files changed, 260 insertions, 114 deletions
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java
index d5d927cf44fc..182f79c94bce 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java
@@ -48,43 +48,55 @@ public class ExternalAnnotationsLineMarkerProvider implements LineMarkerProvider
@Nullable
@Override
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
- if (element instanceof PsiParameter) return null;
+ if (!(element instanceof PsiModifierListOwner)) return null;
+ if (element instanceof PsiParameter || element instanceof PsiLocalVariable) return null;
- PsiModifierListOwner owner = null;
- if (element instanceof PsiModifierListOwner) {
- final PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)element;
- final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(modifierListOwner.getProject());
- PsiAnnotation[] externalAnnotations = annotationsManager.findExternalAnnotations(modifierListOwner);
- if (externalAnnotations != null && externalAnnotations.length > 0) {
- owner = (PsiModifierListOwner)element;
- } else if (element instanceof PsiMethod) {
- final PsiParameter[] parameters = ((PsiMethod)element).getParameterList().getParameters();
- for (PsiParameter parameter : parameters) {
- externalAnnotations = annotationsManager.findExternalAnnotations(parameter);
- if (externalAnnotations != null && externalAnnotations.length > 0) {
- owner = (PsiMethod)element;
- break;
- }
- }
- }
- }
-
- if (owner == null) {
+ if (!shouldShowSignature(preferCompiledElement((PsiModifierListOwner)element))) {
return null;
}
final Function<PsiModifierListOwner, String> annotationsCollector = new Function<PsiModifierListOwner, String>() {
@Override
public String fun(PsiModifierListOwner owner) {
- return XmlStringUtil.wrapInHtml(JavaDocInfoGenerator.generateSignature(owner));
+ return XmlStringUtil.wrapInHtml(JavaDocInfoGenerator.generateSignature(preferCompiledElement(owner)));
}
};
- return new LineMarkerInfo<PsiModifierListOwner>(owner, owner.getTextOffset(), AllIcons.Gutter.ExtAnnotation,
+ return new LineMarkerInfo<PsiModifierListOwner>((PsiModifierListOwner)element, element.getTextOffset(), AllIcons.Gutter.ExtAnnotation,
Pass.UPDATE_ALL,
annotationsCollector, new MyIconGutterHandler(),
GutterIconRenderer.Alignment.LEFT);
}
+ private static PsiModifierListOwner preferCompiledElement(PsiModifierListOwner element) {
+ PsiElement original = element.getOriginalElement();
+ return original instanceof PsiModifierListOwner ? (PsiModifierListOwner)original : element;
+ }
+
+ private static boolean shouldShowSignature(PsiModifierListOwner owner) {
+ if (hasNonCodeAnnotations(owner)) {
+ return true;
+ }
+
+ if (owner instanceof PsiMethod) {
+ for (PsiParameter parameter : ((PsiMethod)owner).getParameterList().getParameters()) {
+ if (hasNonCodeAnnotations(parameter)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean hasNonCodeAnnotations(@NotNull PsiModifierListOwner element) {
+ Project project = element.getProject();
+ PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(project).findExternalAnnotations(element);
+ if (externalAnnotations != null && externalAnnotations.length > 0) {
+ return true;
+ }
+ return InferredAnnotationsManager.getInstance(project).findInferredAnnotations(element).length > 0;
+ }
+
@Override
public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result) {}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java
index 4ff8ca2ec5f8..cbc9653b6adf 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java
@@ -21,6 +21,7 @@ import com.intellij.diagnostic.AttachmentFactory;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.ClassConditionKey;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -38,6 +39,7 @@ import java.util.Set;
* @author peter
*/
public class JavaChainLookupElement extends LookupElementDecorator<LookupElement> implements TypedLookupItem {
+ public static final Key<Boolean> CHAIN_QUALIFIER = Key.create("CHAIN_QUALIFIER");
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.JavaChainLookupElement");
public static final ClassConditionKey<JavaChainLookupElement> CLASS_CONDITION_KEY = ClassConditionKey.create(JavaChainLookupElement.class);
private final LookupElement myQualifier;
@@ -109,9 +111,12 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
public void handleInsert(InsertionContext context) {
final Document document = context.getEditor().getDocument();
document.replaceString(context.getStartOffset(), context.getTailOffset(), ";");
+ myQualifier.putUserData(CHAIN_QUALIFIER, true);
final InsertionContext qualifierContext = CompletionUtil.emulateInsertion(context, context.getStartOffset(), myQualifier);
OffsetKey oldStart = context.trackOffset(context.getStartOffset(), false);
+ PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(document);
+
int start = CharArrayUtil.shiftForward(context.getDocument().getCharsSequence(), context.getStartOffset(), " \t\n");
if (shouldParenthesizeQualifier(context.getFile(), start, qualifierContext.getTailOffset())) {
final String space = CodeStyleSettingsManager.getSettings(qualifierContext.getProject()).SPACE_WITHIN_PARENTHESES ? " " : "";
@@ -165,6 +170,7 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
if (expr instanceof PsiJavaCodeReferenceElement ||
expr instanceof PsiMethodCallExpression ||
+ expr instanceof PsiNewExpression ||
expr instanceof PsiArrayAccessExpression) {
return false;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
index be6d8146ce3d..f5a8253ab5ab 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
@@ -98,7 +98,8 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
context.setTailOffset(context.getOffset(refEnd));
context.commitDocument();
- if (shouldInsertParentheses(file.findElementAt(context.getTailOffset() - 1))) {
+ if (item.getUserData(JavaChainLookupElement.CHAIN_QUALIFIER) == null &&
+ shouldInsertParentheses(file.findElementAt(context.getTailOffset() - 1))) {
if (ConstructorInsertHandler.insertParentheses(context, item, psiClass, false)) {
fillTypeArgs |= psiClass.hasTypeParameters() && PsiUtil.getLanguageLevel(file).isAtLeast(LanguageLevel.JDK_1_5);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
index 7310227a80f0..fba10a633432 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
@@ -426,7 +426,7 @@ public class JavaCompletionContributor extends CompletionContributor {
if (JavaCompletionData.isAfterPrimitiveOrArrayType(position)) {
return false;
}
-
+
return true;
}
@@ -466,11 +466,11 @@ public class JavaCompletionContributor extends CompletionContributor {
methods: for (PsiMethod method : annoClass.getMethods()) {
if (!(method instanceof PsiAnnotationMethod)) continue;
-
+
final String attrName = method.getName();
for (PsiNameValuePair existingAttr : existingPairs) {
if (PsiTreeUtil.isAncestor(existingAttr, insertedElement, false)) break;
- if (Comparing.equal(existingAttr.getName(), attrName) ||
+ if (Comparing.equal(existingAttr.getName(), attrName) ||
PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(attrName) && existingAttr.getName() == null) continue methods;
}
LookupElementBuilder element = LookupElementBuilder.createWithIcon(method).withInsertHandler(new InsertHandler<LookupElement>() {
@@ -479,7 +479,7 @@ public class JavaCompletionContributor extends CompletionContributor {
final Editor editor = context.getEditor();
TailType.EQ.processTail(editor, editor.getCaretModel().getOffset());
context.setAddCompletionChar(false);
-
+
context.commitDocument();
PsiAnnotationParameterList paramList =
PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiAnnotationParameterList.class, false);
@@ -644,7 +644,20 @@ public class JavaCompletionContributor extends CompletionContributor {
if (file instanceof PsiJavaFile) {
if (context.getInvocationCount() > 0) {
autoImport(file, context.getStartOffset() - 1, context.getEditor());
- PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument());
+
+ PsiElement leaf = file.findElementAt(context.getStartOffset() - 1);
+ if (leaf != null) leaf = PsiTreeUtil.prevVisibleLeaf(leaf);
+
+ PsiVariable variable = PsiTreeUtil.getParentOfType(leaf, PsiVariable.class);
+ if (variable != null) {
+ PsiTypeElement typeElement = variable.getTypeElement();
+ if (typeElement != null) {
+ PsiType type = typeElement.getType();
+ if (type instanceof PsiClassType && ((PsiClassType)type).resolve() == null) {
+ autoImportReference(file, context.getEditor(), typeElement.getInnermostComponentReferenceElement());
+ }
+ }
+ }
}
JavaCompletionUtil.initOffsets(file, context.getOffsetMap());
@@ -702,7 +715,13 @@ public class JavaCompletionContributor extends CompletionContributor {
iterator.advance();
}
- if (!iterator.atEnd() && (iterator.getTokenType() == JavaTokenType.LPARENTH || iterator.getTokenType() == JavaTokenType.COLON)) {
+ if (!iterator.atEnd() && (iterator.getTokenType() == JavaTokenType.LPARENTH)) {
+ return true;
+ }
+
+ if (!iterator.atEnd()
+ && (iterator.getTokenType() == JavaTokenType.COLON)
+ && null == PsiTreeUtil.findElementOfClassAtOffset(file, startOffset, PsiConditionalExpression.class, false)) {
return true;
}
@@ -721,7 +740,7 @@ public class JavaCompletionContributor extends CompletionContributor {
return iterator.getTokenType() == JavaTokenType.EQ || iterator.getTokenType() == JavaTokenType.LPARENTH;
}
- private static void autoImport(final PsiFile file, int offset, final Editor editor) {
+ private static void autoImport(@NotNull final PsiFile file, int offset, @NotNull final Editor editor) {
final CharSequence text = editor.getDocument().getCharsSequence();
while (offset > 0 && Character.isJavaIdentifierPart(text.charAt(offset))) offset--;
if (offset <= 0) return;
@@ -734,7 +753,10 @@ public class JavaCompletionContributor extends CompletionContributor {
while (offset > 0 && Character.isWhitespace(text.charAt(offset))) offset--;
if (offset <= 0) return;
- PsiJavaCodeReferenceElement element = extractReference(PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiExpression.class, false));
+ autoImportReference(file, editor, extractReference(PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiExpression.class, false)));
+ }
+
+ private static void autoImportReference(@NotNull PsiFile file, @NotNull Editor editor, @Nullable PsiJavaCodeReferenceElement element) {
if (element == null) return;
while (true) {
@@ -745,6 +767,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
if (!(element.getParent() instanceof PsiMethodCallExpression) && element.multiResolve(true).length == 0) {
new ImportClassFix(element).doFix(editor, false, false);
+ PsiDocumentManager.getInstance(file.getProject()).commitDocument(editor.getDocument());
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java
index b409014c1fe8..661d0abfcaac 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java
@@ -18,11 +18,14 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.psi.PsiMethod;
-import com.intellij.psi.ResolveResult;
+import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import static com.intellij.util.ObjectUtils.assertNotNull;
+
/**
* @author peter
*/
@@ -38,13 +41,9 @@ public class JavaMethodMergingContributor extends CompletionContributor {
final LookupElement[] items = context.getItems();
if (items.length > 1) {
String commonName = null;
- LookupElement best = null;
final ArrayList<PsiMethod> allMethods = new ArrayList<PsiMethod>();
for (LookupElement item : items) {
- Object o = item.getObject();
- if (o instanceof ResolveResult) {
- o = ((ResolveResult)o).getElement();
- }
+ Object o = item.getPsiElement();
if (item.getUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) != null || !(o instanceof PsiMethod)) {
return AutoCompletionDecision.SHOW_LOOKUP;
}
@@ -56,19 +55,37 @@ public class JavaMethodMergingContributor extends CompletionContributor {
return AutoCompletionDecision.SHOW_LOOKUP;
}
- if (best == null && method.getParameterList().getParametersCount() > 0) {
- best = item;
- }
commonName = name;
allMethods.add(method);
item.putUserData(JavaCompletionUtil.ALL_METHODS_ATTRIBUTE, allMethods);
}
- if (best == null) {
- best = items[0];
- }
- return AutoCompletionDecision.insertItem(best);
+
+ return AutoCompletionDecision.insertItem(findBestOverload(items));
}
return super.handleAutoCompletionPossibility(context);
}
+
+ public static LookupElement findBestOverload(LookupElement[] items) {
+ LookupElement best = items[0];
+ for (int i = 1; i < items.length; i++) {
+ LookupElement item = items[i];
+ if (getPriority(best) < getPriority(item)) {
+ best = item;
+ }
+ }
+ return best;
+ }
+
+ private static int getPriority(LookupElement element) {
+ PsiMethod method = assertNotNull(getItemMethod(element));
+ return (method.getReturnType() == PsiType.VOID ? 0 : 1) +
+ (method.getParameterList().getParametersCount() > 0 ? 2 : 0);
+ }
+
+ @Nullable
+ private static PsiMethod getItemMethod(LookupElement item) {
+ Object o = item.getPsiElement();
+ return o instanceof PsiMethod ? (PsiMethod)o : null;
+ }
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
index f36f567199a0..ceebdecdf8c3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -41,7 +42,6 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement;
* @author peter
*/
public class JavaNoVariantsDelegator extends CompletionContributor {
-
@Override
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAbstractMethodFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAbstractMethodFromUsageFix.java
index abcff2238c68..5edd1973cfd8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAbstractMethodFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAbstractMethodFromUsageFix.java
@@ -51,7 +51,7 @@ public class CreateAbstractMethodFromUsageFix extends CreateMethodFromUsageFix {
}
@Override
- protected boolean shouldBeAbstract(PsiClass targetClass) {
+ protected boolean shouldBeAbstract(PsiReferenceExpression expression, PsiClass targetClass) {
return true;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
index 939b8b6f8a13..1e9d1a88cb99 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
@@ -28,6 +28,9 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* @author Mike
*/
@@ -45,6 +48,19 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
return false;
}
+ @NotNull
+ @Override
+ protected List<PsiClass> getTargetClasses(PsiElement element) {
+ final List<PsiClass> targetClasses = new ArrayList<PsiClass>();
+ for (PsiClass psiClass : super.getTargetClasses(element)) {
+ if (psiClass.getManager().isInProject(psiClass) &&
+ (!psiClass.isInterface() && !psiClass.isAnnotationType() || shouldCreateStaticMember(myReferenceExpression, psiClass))) {
+ targetClasses.add(psiClass);
+ }
+ }
+ return targetClasses;
+ }
+
@Override
protected boolean canBeTargetClass(PsiClass psiClass) {
return psiClass.getManager().isInProject(psiClass) && !psiClass.isInterface() && !psiClass.isAnnotationType();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java
index c12fbe8d7711..09b83e2a489f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java
@@ -168,6 +168,9 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
list.deleteChildRange(list.getFirstChild(), list.getLastChild());
return;
}
+ if (targetClass.isInterface()) {
+ return;
+ }
final String visibility = getVisibility(parentClass, targetClass);
if (VisibilityUtil.ESCALATE_VISIBILITY.equals(visibility)) {
list.setModifierProperty(PsiModifier.PRIVATE, true);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
index b7cd8af73084..8e93a6a0c817 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
@@ -120,7 +120,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
PsiMethodCallExpression call = getMethodCall();
if (call == null) return Collections.emptyList();
for (PsiClass target : targets) {
- if (target.isInterface() && shouldCreateStaticMember(call.getMethodExpression(), target)) continue;
+ if (target.isInterface() && shouldCreateStaticMember(call.getMethodExpression(), target) && !PsiUtil.isLanguageLevel8OrHigher(target)) continue;
if (!isMethodSignatureExists(call, target)) {
result.add(target);
}
@@ -155,7 +155,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
PsiCodeBlock body = method.getBody();
assert body != null;
- if (shouldBeAbstract(targetClass)) {
+ final boolean shouldBeAbstract = shouldBeAbstract(expression.getMethodExpression(), targetClass);
+ if (shouldBeAbstract) {
body.delete();
if (!targetClass.isInterface()) {
method.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, true);
@@ -167,14 +168,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
expression = getMethodCall();
LOG.assertTrue(expression.isValid());
- if (!targetClass.isInterface() && shouldCreateStaticMember(expression.getMethodExpression(), targetClass) && !shouldBeAbstract(targetClass)) {
+ if ((!targetClass.isInterface() || PsiUtil.isLanguageLevel8OrHigher(targetClass)) && shouldCreateStaticMember(expression.getMethodExpression(), targetClass) && !shouldBeAbstract) {
PsiUtil.setModifierProperty(method, PsiModifier.STATIC, true);
}
final PsiElement context = PsiTreeUtil.getParentOfType(expression, PsiClass.class, PsiMethod.class);
PsiExpression[] arguments = expression.getArgumentList().getExpressions();
- doCreate(targetClass, method, shouldBeAbstract(targetClass),
+ doCreate(targetClass, method, shouldBeAbstract,
ContainerUtil.map2List(arguments, Pair.<PsiExpression, PsiType>createFunction(null)),
getTargetSubstitutor(expression),
CreateFromUsageUtils.guessExpectedTypes(expression, true),
@@ -213,7 +214,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
public static void doCreate(PsiClass targetClass, PsiMethod method, List<Pair<PsiExpression, PsiType>> arguments, PsiSubstitutor substitutor,
ExpectedTypeInfo[] expectedTypes, @Nullable PsiElement context) {
- doCreate(targetClass, method, shouldBeAbstractImpl(targetClass), arguments, substitutor, expectedTypes, context);
+ doCreate(targetClass, method, shouldBeAbstractImpl(null, targetClass), arguments, substitutor, expectedTypes, context);
}
public static void doCreate(PsiClass targetClass,
@@ -340,12 +341,12 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
return false;
}
- protected boolean shouldBeAbstract(PsiClass targetClass) {
- return shouldBeAbstractImpl(targetClass);
+ protected boolean shouldBeAbstract(PsiReferenceExpression expression, PsiClass targetClass) {
+ return shouldBeAbstractImpl(expression, targetClass);
}
- private static boolean shouldBeAbstractImpl(PsiClass targetClass) {
- return targetClass.isInterface();
+ private static boolean shouldBeAbstractImpl(PsiReferenceExpression expression, PsiClass targetClass) {
+ return targetClass.isInterface() && (expression == null || !shouldCreateStaticMember(expression, targetClass));
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
index b5de7b73e318..fec3efd161ba 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
@@ -30,6 +30,7 @@ import com.intellij.psi.*;
import com.intellij.psi.util.ClassUtil;
import org.jetbrains.annotations.NotNull;
+import java.util.Collections;
import java.util.List;
public class ImportClassFix extends ImportClassFixBase<PsiJavaCodeReferenceElement, PsiJavaCodeReferenceElement> {
@@ -107,9 +108,22 @@ public class ImportClassFix extends ImportClassFixBase<PsiJavaCodeReferenceEleme
return super.getRequiredMemberName(reference);
}
+ @Override
+ protected boolean canReferenceClass(PsiJavaCodeReferenceElement ref) {
+ if (ref instanceof PsiReferenceExpression) {
+ PsiElement parent = ref.getParent();
+ return parent instanceof PsiReferenceExpression || parent instanceof PsiExpressionStatement;
+ }
+ return true;
+ }
+
@NotNull
@Override
protected List<PsiClass> filterByContext(@NotNull List<PsiClass> candidates, @NotNull PsiJavaCodeReferenceElement ref) {
+ if (ref instanceof PsiReferenceExpression) {
+ return Collections.emptyList();
+ }
+
PsiElement typeElement = ref.getParent();
if (typeElement instanceof PsiTypeElement) {
PsiElement var = typeElement.getParent();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
index 8047486d93ba..2fbe85bc7b25 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
@@ -102,14 +102,19 @@ public abstract class ImportClassFixBase<T extends PsiElement, R extends PsiRefe
// can happen when e.g. class name happened to be in a method position
if (element instanceof PsiClass && result.isValidResult()) return Collections.emptyList();
}
- PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myElement.getProject());
+
String name = getReferenceName(myRef);
GlobalSearchScope scope = myElement.getResolveScope();
if (name == null) {
return Collections.emptyList();
}
+
+ if (!canReferenceClass(myRef)) {
+ return Collections.emptyList();
+ }
+
boolean referenceHasTypeParameters = hasTypeParameters(myRef);
- PsiClass[] classes = cache.getClassesByName(name, scope);
+ PsiClass[] classes = PsiShortNamesCache.getInstance(myElement.getProject()).getClassesByName(name, scope);
if (classes.length == 0) return Collections.emptyList();
List<PsiClass> classList = new ArrayList<PsiClass>(classes.length);
boolean isAnnotationReference = myElement.getParent() instanceof PsiAnnotation;
@@ -140,6 +145,10 @@ public abstract class ImportClassFixBase<T extends PsiElement, R extends PsiRefe
return classList;
}
+ protected boolean canReferenceClass(R ref) {
+ return true;
+ }
+
private List<PsiClass> filterByRequiredMemberName(List<PsiClass> classList) {
final String memberName = getRequiredMemberName(myElement);
if (memberName != null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java
index cea07113fe24..90c26bc6073b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java
@@ -47,7 +47,21 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.editorActions.smartEnter.JavaSmartEnterProcessor");
private static final Fixer[] ourFixers;
- private static final EnterProcessor[] ourEnterProcessors;
+ private static final EnterProcessor[] ourEnterProcessors = {
+ new CommentBreakerEnterProcessor(),
+ new AfterSemicolonEnterProcessor(),
+ new LeaveCodeBlockEnterProcessor(),
+ new PlainEnterProcessor()
+ };
+ private static final EnterProcessor[] ourAfterCompletionEnterProcessors = {
+ new AfterSemicolonEnterProcessor(),
+ new EnterProcessor() {
+ @Override
+ public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) {
+ return PlainEnterProcessor.expandCodeBlock(editor, psiElement);
+ }
+ }
+ };
static {
final List<Fixer> fixers = new ArrayList<Fixer>();
@@ -78,15 +92,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
fixers.add(new MissingArrayInitializerBraceFixer());
fixers.add(new MissingArrayConstructorBracketFixer());
fixers.add(new EnumFieldFixer());
- //ourFixers.add(new CompletionFixer());
ourFixers = fixers.toArray(new Fixer[fixers.size()]);
-
- List<EnterProcessor> processors = new ArrayList<EnterProcessor>();
- processors.add(new CommentBreakerEnterProcessor());
- processors.add(new AfterSemicolonEnterProcessor());
- processors.add(new LeaveCodeBlockEnterProcessor());
- processors.add(new PlainEnterProcessor());
- ourEnterProcessors = processors.toArray(new EnterProcessor[processors.size()]);
}
private int myFirstErrorOffset = Integer.MAX_VALUE;
@@ -102,13 +108,22 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
public boolean process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile) {
FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.complete.statement");
+ return invokeProcessor(editor, psiFile, false);
+ }
+
+ @Override
+ public boolean processAfterCompletion(@NotNull Editor editor, @NotNull PsiFile psiFile) {
+ return invokeProcessor(editor, psiFile, true);
+ }
+
+ private boolean invokeProcessor(Editor editor, PsiFile psiFile, boolean afterCompletion) {
final Document document = editor.getDocument();
- final String textForRollback = document.getText();
+ final CharSequence textForRollback = document.getImmutableCharSequence();
try {
editor.putUserData(SMART_ENTER_TIMESTAMP, editor.getDocument().getModificationStamp());
myFirstErrorOffset = Integer.MAX_VALUE;
mySkipEnter = false;
- process(project, editor, psiFile, 0);
+ process(editor, psiFile, 0, afterCompletion);
}
catch (TooManyAttemptsException e) {
document.replaceString(0, document.getTextLength(), textForRollback);
@@ -118,8 +133,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
return true;
}
-
- private void process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file, final int attempt) throws TooManyAttemptsException {
+ private void process(@NotNull final Editor editor, @NotNull final PsiFile file, final int attempt, boolean afterCompletion) throws TooManyAttemptsException {
if (attempt > MAX_ATTEMPTS) throw new TooManyAttemptsException();
try {
@@ -148,18 +162,18 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
for (PsiElement psiElement : queue) {
for (Fixer fixer : ourFixers) {
fixer.apply(editor, this, psiElement);
- if (LookupManager.getInstance(project).getActiveLookup() != null) {
+ if (LookupManager.getInstance(file.getProject()).getActiveLookup() != null) {
return;
}
- if (isUncommited(project) || !psiElement.isValid()) {
+ if (isUncommited(file.getProject()) || !psiElement.isValid()) {
moveCaretInsideBracesIfAny(editor, file);
- process(project, editor, file, attempt + 1);
+ process(editor, file, attempt + 1, afterCompletion);
return;
}
}
}
- doEnter(atCaret, editor);
+ doEnter(atCaret, editor, afterCompletion);
}
catch (IncorrectOperationException e) {
LOG.error(e);
@@ -187,7 +201,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
}
- private void doEnter(PsiElement atCaret, Editor editor) throws IncorrectOperationException {
+ private void doEnter(PsiElement atCaret, Editor editor, boolean afterCompletion) throws IncorrectOperationException {
final PsiFile psiFile = atCaret.getContainingFile();
final RangeMarker rangeMarker = createRangeMarker(atCaret);
@@ -205,7 +219,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
}
atCaret = CodeInsightUtil.findElementInRange(psiFile, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), atCaret.getClass());
- for (EnterProcessor processor : ourEnterProcessors) {
+ for (EnterProcessor processor : afterCompletion ? ourAfterCompletionEnterProcessors : ourEnterProcessors) {
if(atCaret == null){
// Can't restore element at caret after enter processor execution!
break;
@@ -214,7 +228,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
if (processor.doEnter(editor, atCaret, isModified(editor))) return;
}
- if (!isModified(editor)) {
+ if (!isModified(editor) && !afterCompletion) {
plainEnter(editor);
} else {
if (myFirstErrorOffset == Integer.MAX_VALUE) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java
index 0fe58925d884..6bafcc00d983 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java
@@ -42,29 +42,37 @@ import org.jetbrains.annotations.Nullable;
public class PlainEnterProcessor implements EnterProcessor {
@Override
public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) {
+ if (expandCodeBlock(editor, psiElement)) return true;
+
+ getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE).execute(editor, ((EditorEx)editor).getDataContext());
+ return true;
+ }
+
+ static boolean expandCodeBlock(Editor editor, PsiElement psiElement) {
PsiCodeBlock block = getControlStatementBlock(editor.getCaretModel().getOffset(), psiElement);
if (processExistingBlankLine(editor, block, psiElement)) {
return true;
}
- EditorActionHandler enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE);
- if (block != null) {
- PsiElement firstElement = block.getFirstBodyElement();
- if (firstElement == null) {
- firstElement = block.getRBrace();
- // Plain enter processor inserts enter after the end of line, hence, we don't want to use it here because the line ends with
- // the empty braces block. So, we get the following in case of default handler usage:
- // Before:
- // if (condition[caret]) {}
- // After:
- // if (condition) {}
- // [caret]
- enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_ENTER);
- }
- editor.getCaretModel().moveToOffset(firstElement != null ?
- firstElement.getTextRange().getStartOffset() :
- block.getTextRange().getEndOffset());
+ if (block == null) {
+ return false;
}
+ EditorActionHandler enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE);
+ PsiElement firstElement = block.getFirstBodyElement();
+ if (firstElement == null) {
+ firstElement = block.getRBrace();
+ // Plain enter processor inserts enter after the end of line, hence, we don't want to use it here because the line ends with
+ // the empty braces block. So, we get the following in case of default handler usage:
+ // Before:
+ // if (condition[caret]) {}
+ // After:
+ // if (condition) {}
+ // [caret]
+ enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_ENTER);
+ }
+ editor.getCaretModel().moveToOffset(firstElement != null ?
+ firstElement.getTextRange().getStartOffset() :
+ block.getTextRange().getEndOffset());
enterHandler.execute(editor, ((EditorEx)editor).getDataContext());
return true;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java
index 8646805b3a2f..5d948f326930 100644
--- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.folding.impl;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
+import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -27,7 +28,7 @@ public class JavaFoldingBuilder extends JavaFoldingBuilderBase {
@Override
protected boolean isBelowRightMargin(Project project, int lineLength) {
final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
- return lineLength <= settings.RIGHT_MARGIN;
+ return lineLength <= settings.getRightMargin(JavaLanguage.INSTANCE);
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java
index 4236da3187fc..fe4208deada7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java
@@ -251,11 +251,22 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
final Set<MethodSignature> existingSignatures = new HashSet<MethodSignature>(aClass.getVisibleSignatures());
final Set<PsiMethodMember> selection = new HashSet<PsiMethodMember>();
Map<PsiClass, PsiSubstitutor> superSubstitutors = new HashMap<PsiClass, PsiSubstitutor>();
+
+ final PsiClass containingClass = targetMember.getContainingClass();
JavaPsiFacade facade = JavaPsiFacade.getInstance(target.getProject());
for (PsiMethod method : allMethods) {
final PsiClass superClass = method.getContainingClass();
if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) continue;
if (method.isConstructor()) continue;
+
+ //do not suggest to override final method
+ if (method.hasModifierProperty(PsiModifier.FINAL)) {
+ PsiMethod overridden = containingClass.findMethodBySignature(method, true);
+ if (overridden != null && overridden.getContainingClass() != containingClass) {
+ continue;
+ }
+ }
+
PsiSubstitutor superSubstitutor = superSubstitutors.get(superClass);
if (superSubstitutor == null) {
superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, targetClass, substitutor);
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
index d8df67367790..49e2e43f2ce4 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
@@ -15,10 +15,7 @@
*/
package com.intellij.codeInsight.generation;
-import com.intellij.codeInsight.AnnotationUtil;
-import com.intellij.codeInsight.CodeInsightActionHandler;
-import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.MethodImplementor;
+import com.intellij.codeInsight.*;
import com.intellij.codeInsight.intention.AddAnnotationFix;
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.featureStatistics.FeatureUsageTracker;
@@ -259,6 +256,11 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
for (String annotation : each.getAnnotations(project)) {
if (moduleScope != null && facade.findClass(annotation, moduleScope) == null) continue;
if (AnnotationUtil.isAnnotated(overridden, annotation, false, false) && !AnnotationUtil.isAnnotated(method, annotation, false, false)) {
+ PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotation(overridden, annotation);
+ if (psiAnnotation != null && AnnotationUtil.isInferredAnnotation(psiAnnotation)) {
+ continue;
+ }
+
AddAnnotationPsiFix.removePhysicalAnnotations(method, each.annotationsToRemove(project, annotation));
AddAnnotationPsiFix.addPhysicalAnnotation(annotation, PsiNameValuePair.EMPTY_ARRAY, method.getModifierList());
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
index b33287321535..fd85d1124171 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.parameterInfo.*;
import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.DumbService;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.CompletionParameterTypeInferencePolicy;
import com.intellij.psi.infos.CandidateInfo;
@@ -31,6 +32,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -443,13 +445,18 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
private static void appendModifierList(@NotNull StringBuilder buffer, @NotNull PsiModifierListOwner owner) {
int lastSize = buffer.length();
- for (PsiAnnotation annotation : AnnotationUtil.getAllAnnotations(owner, false, null)) {
+ Set<String> shownAnnotations = ContainerUtil.newHashSet();
+ for (PsiAnnotation annotation : AnnotationUtil.getAllAnnotations(owner, false, null, !DumbService.isDumb(owner.getProject()))) {
final PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement();
if (element != null) {
final PsiElement resolved = element.resolve();
if (resolved instanceof PsiClass && !AnnotationUtil.isAnnotated((PsiClass)resolved, "java.lang.annotation.Documented", false)) continue;
+
+ String referenceName = element.getReferenceName();
+ if (!shownAnnotations.add(referenceName)) continue;
+
if (lastSize != buffer.length()) buffer.append(" ");
- buffer.append("@").append(element.getReferenceName());
+ buffer.append("@").append(referenceName);
}
}
if (lastSize != buffer.length()) buffer.append(" ");
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/impl/ShortenToStaticImportProcessor.java b/java/java-impl/src/com/intellij/codeInsight/template/impl/ShortenToStaticImportProcessor.java
index 41424cf2b526..fbb6786c4972 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/impl/ShortenToStaticImportProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/impl/ShortenToStaticImportProcessor.java
@@ -27,11 +27,11 @@ import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
@@ -63,7 +63,7 @@ public class ShortenToStaticImportProcessor implements TemplateOptionalProcessor
for (
PsiElement element = PsiUtilCore.getElementAtOffset(file, templateRange.getStartOffset());
element != null && element.getTextRange().getStartOffset() < templateRange.getEndOffset();
- element = getNext(element))
+ element = PsiTreeUtil.nextLeaf(element))
{
for (StaticImporter importer : IMPORTERS) {
if (importer.canPerform(element)) {
@@ -81,15 +81,6 @@ public class ShortenToStaticImportProcessor implements TemplateOptionalProcessor
}
}
- @Nullable
- private static PsiElement getNext(@NotNull PsiElement element) {
- PsiElement result = element.getNextSibling();
- for (PsiElement current = element; current != null && result == null; current = current.getParent()) {
- result = current.getNextSibling();
- }
- return result;
- }
-
@Nls
@Override
public String getOptionName() {
diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java
index ec771e43c073..1c1957bcf472 100644
--- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java
+++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java
@@ -29,15 +29,23 @@ public class JavaMethodParameterUnwrapper extends JavaUnwrapper {
super("");
}
+ private static PsiElement adjustElementToTheLeft(PsiElement element) {
+ if (element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == JavaTokenType.RPARENTH) {
+ return element.getPrevSibling();
+ }
+ return element;
+ }
+
@Override
public String getDescription(PsiElement e) {
- String text = e.getText();
+ String text = adjustElementToTheLeft(e).getText();
if (text.length() > 20) text = text.substring(0, 17) + "...";
return CodeInsightBundle.message("unwrap.with.placeholder", text);
}
@Override
public boolean isApplicableTo(PsiElement e) {
+ e = adjustElementToTheLeft(e);
final PsiElement parent = e.getParent();
if (e instanceof PsiExpression){
if (parent instanceof PsiExpressionList) {
@@ -62,6 +70,7 @@ public class JavaMethodParameterUnwrapper extends JavaUnwrapper {
@Override
public PsiElement collectAffectedElements(PsiElement e, List<PsiElement> toExtract) {
+ e = adjustElementToTheLeft(e);
super.collectAffectedElements(e, toExtract);
return isTopLevelCall(e) ? e.getParent() : e.getParent().getParent();
}
@@ -73,6 +82,7 @@ public class JavaMethodParameterUnwrapper extends JavaUnwrapper {
@Override
protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException {
+ element = adjustElementToTheLeft(element);
PsiElement methodCall = isTopLevelCall(element) ? element.getParent() : element.getParent().getParent();
final PsiElement extractedElement = isTopLevelCall(element) ? getArg(element) : element;
context.extractElement(extractedElement, methodCall);