diff options
Diffstat (limited to 'java/java-impl/src')
44 files changed, 405 insertions, 376 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); diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageUtil.java b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageUtil.java index e9e999b7b149..bcb4b3d20319 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageUtil.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageUtil.java @@ -21,8 +21,6 @@ import com.intellij.ide.util.treeView.TreeViewUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; -import com.intellij.openapi.roots.impl.DirectoryIndex; -import com.intellij.openapi.roots.impl.DirectoryInfo; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaDirectoryService; @@ -230,20 +228,16 @@ public class PackageUtil { } private static class ProjectLibrariesSearchScope extends GlobalSearchScope { - private final DirectoryIndex myDirectoryIndex; + private final ProjectFileIndex myFileIndex; public ProjectLibrariesSearchScope(@NotNull Project project) { super(project); - myDirectoryIndex = DirectoryIndex.getInstance(project); + myFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); } @Override public boolean contains(@NotNull VirtualFile file) { - VirtualFile dir = file.isDirectory() ? file : file.getParent(); - if (dir == null) return false; - - DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(dir); - return info != null && info.hasLibraryClassRoot(); + return myFileIndex.isInLibraryClasses(file); } @Override diff --git a/java/java-impl/src/com/intellij/ide/util/PackageUtil.java b/java/java-impl/src/com/intellij/ide/util/PackageUtil.java index be9405ee4754..0530f34e653a 100644 --- a/java/java-impl/src/com/intellij/ide/util/PackageUtil.java +++ b/java/java-impl/src/com/intellij/ide/util/PackageUtil.java @@ -24,14 +24,12 @@ import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.impl.ProjectRootUtil; -import com.intellij.openapi.roots.ModulePackageIndex; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.ui.configuration.CommonContentEntriesEditor; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -52,13 +50,29 @@ public class PackageUtil { @Nullable public static PsiDirectory findPossiblePackageDirectoryInModule(Module module, String packageName) { + return findPossiblePackageDirectoryInModule(module, packageName, true); + } + @Nullable + public static PsiDirectory findPossiblePackageDirectoryInModule(Module module, String packageName, boolean preferNonGeneratedRoots) { + final Project project = module.getProject(); PsiDirectory psiDirectory = null; - if (!"".equals(packageName)) { - PsiPackage rootPackage = findLongestExistingPackage(module.getProject(), packageName); + if (!StringUtil.isEmptyOrSpaces(packageName)) { + PsiPackage rootPackage = findLongestExistingPackage(project, packageName); if (rootPackage != null) { final PsiDirectory[] psiDirectories = getPackageDirectoriesInModule(rootPackage, module); if (psiDirectories.length > 0) { psiDirectory = psiDirectories[0]; + + // If we prefer to find a non-generated PsiDirectory for the given package name, search through all + // the directories for the first dir not marked as generated and use that one instead + if (preferNonGeneratedRoots && psiDirectories.length > 1) { + for (PsiDirectory dir : psiDirectories) { + if (!GeneratedSourcesFilter.isGeneratedSourceByAnyFilter(dir.getVirtualFile(), project)) { + psiDirectory = dir; + break; + } + } + } } } } @@ -66,7 +80,7 @@ public class PackageUtil { if (checkSourceRootsConfigured(module)) { final List<VirtualFile> sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots(JavaModuleSourceRootTypes.SOURCES); for (VirtualFile sourceRoot : sourceRoots) { - final PsiDirectory directory = PsiManager.getInstance(module.getProject()).findDirectory(sourceRoot); + final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(sourceRoot); if (directory != null) { psiDirectory = directory; break; diff --git a/java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java b/java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java index d933576fc697..a4e7b64241f3 100644 --- a/java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java +++ b/java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java @@ -86,7 +86,7 @@ public class JavaLanguageLevelPusher implements FilePropertyPusher<LanguageLevel private static final FileAttribute PERSISTENCE = new FileAttribute("language_level_persistence", 3, true); @Override - public void persistAttribute(@NotNull VirtualFile fileOrDir, @NotNull LanguageLevel level) throws IOException { + public void persistAttribute(@NotNull Project project, @NotNull VirtualFile fileOrDir, @NotNull LanguageLevel level) throws IOException { final DataInputStream iStream = PERSISTENCE.readAttribute(fileOrDir); if (iStream != null) { try { @@ -104,7 +104,7 @@ public class JavaLanguageLevelPusher implements FilePropertyPusher<LanguageLevel for (VirtualFile child : fileOrDir.getChildren()) { if (!child.isDirectory() && StdFileTypes.JAVA.equals(child.getFileType())) { - PushedFilePropertiesUpdater.filePropertiesChanged(child); + PushedFilePropertiesUpdater.getInstance(project).filePropertiesChanged(child); } } } diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index b76aeaa4b3fd..28748028c246 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -44,6 +44,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.java.IJavaElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.ConcurrentHashMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -229,7 +230,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { new TextRange(dependanceStart, myChild1.getTextRange().getEndOffset()), keepOneLine, true); } - else if (myRole1 == ChildRole.LBRACE) { + else if (myRole1 == ChildRole.LBRACE || isEndOfLineCommentAfterLBrace(myChild1)) { if (aClass.isEnum()) { createParenthSpace(true, false); } @@ -275,6 +276,19 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { } } + private boolean isEndOfLineCommentAfterLBrace(@NotNull ASTNode node) { + if (node.getPsi() instanceof PsiComment) { + PsiElement ws = node.getPsi().getPrevSibling(); + if (ws instanceof PsiWhiteSpace && !ws.textContains('\n')) { + PsiElement beforeWs = ws.getPrevSibling(); + if (beforeWs instanceof PsiJavaToken && ((PsiJavaToken)beforeWs).getTokenType() == JavaTokenType.LBRACE) { + return true; + } + } + } + return false; + } + private static boolean isTheOnlyClassMember(final ASTNode node) { ASTNode next = node.getTreeNext(); if (next == null || !(next.getElementType() == JavaTokenType.RBRACE)) return false; diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java index 18be9cd12246..314f55c2f7fe 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java @@ -16,6 +16,7 @@ package com.intellij.psi.impl; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.psi.*; import com.intellij.psi.impl.source.jsp.jspXml.JspDirective; import com.intellij.psi.util.PsiModificationTracker; @@ -90,7 +91,8 @@ public class JavaCodeBlockModificationListener implements PsiTreeChangePreproces } private static boolean isSourceDir(PsiElement element) { - return element instanceof PsiDirectory && JavaDirectoryService.getInstance().getPackage((PsiDirectory)element) != null; + return element instanceof PsiDirectory && + ProjectFileIndex.SERVICE.getInstance(element.getProject()).isInSource(((PsiDirectory)element).getVirtualFile()); } private static boolean isClassOwner(final PsiElement element) { diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaDirectoryIconProvider.java b/java/java-impl/src/com/intellij/psi/impl/JavaDirectoryIconProvider.java index 795e66e01ed4..e87e95f79086 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaDirectoryIconProvider.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaDirectoryIconProvider.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl; +import com.intellij.icons.AllIcons; import com.intellij.ide.IconProvider; import com.intellij.ide.projectView.impl.ProjectRootsUtil; import com.intellij.openapi.module.Module; @@ -24,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.SourceFolder; import com.intellij.openapi.roots.ui.configuration.SourceRootPresentation; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaDirectoryService; @@ -68,6 +70,9 @@ public class JavaDirectoryIconProvider extends IconProvider implements DumbAware else if (JavaDirectoryService.getInstance().getPackage(psiDirectory) != null) { symbolIcon = PlatformIcons.PACKAGE_ICON; } + else if (!Registry.is("ide.hide.excluded.files") && ProjectRootManager.getInstance(project).getFileIndex().isExcluded(vFile)) { + symbolIcon = AllIcons.Modules.ExcludeRoot; + } else { symbolIcon = PlatformIcons.DIRECTORY_CLOSED_ICON; } diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaPsiImplementationHelperImpl.java b/java/java-impl/src/com/intellij/psi/impl/JavaPsiImplementationHelperImpl.java index 8ea592fd99aa..dce55fd952b5 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaPsiImplementationHelperImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaPsiImplementationHelperImpl.java @@ -178,7 +178,7 @@ public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper } List<OrderEntry> orderEntries = index.getOrderEntriesForFile(virtualFile); if (orderEntries.isEmpty()) { - LOG.error("Inconsistent: " + DirectoryIndex.getInstance(myProject).getInfoForDirectory(folder).toString()); + LOG.error("Inconsistent: " + DirectoryIndex.getInstance(myProject).getInfoForFile(folder).toString()); } final VirtualFile[] files = orderEntries.get(0).getFiles(OrderRootType.CLASSES); for (VirtualFile rootFile : files) { diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java index b424af918851..f6dc9b9697f2 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl.source.codeStyle.javadoc; +import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; @@ -469,20 +470,21 @@ public class JDParser { boolean firstLineShorter, int firstLinePrefixLength) { + int rightMargin = mySettings.getRightMargin(JavaLanguage.INSTANCE); StringBuilder sb = new StringBuilder(); List<String> list; //If wrap comments selected, comments should be wrapped by the right margin if (mySettings.WRAP_COMMENTS) { - list = toArrayWrapping(str, mySettings.RIGHT_MARGIN - prefix.length()); + list = toArrayWrapping(str, rightMargin - prefix.length()); if (firstLineShorter && list != null && !list.isEmpty() - && list.get(0).length() > mySettings.RIGHT_MARGIN - firstLinePrefixLength) + && list.get(0).length() > rightMargin - firstLinePrefixLength) { list = new ArrayList<String>(); //want the first line to be shorter, according to it's prefix - String firstLine = toArrayWrapping(str, mySettings.RIGHT_MARGIN - firstLinePrefixLength).get(0); + String firstLine = toArrayWrapping(str, rightMargin - firstLinePrefixLength).get(0); //so now first line is exactly same width we need list.add(firstLine); str = str.substring(firstLine.length()); @@ -493,7 +495,7 @@ public class JDParser { } //getting all another lines according to their prefix - List<String> subList = toArrayWrapping(str, mySettings.RIGHT_MARGIN - prefix.length()); + List<String> subList = toArrayWrapping(str, rightMargin - prefix.length()); //removing pre tag if (unclosedPreTag && subList != null && !subList.isEmpty()) { diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaCharsetReferenceContributor.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaCharsetReferenceContributor.java deleted file mode 100644 index db1a385d5137..000000000000 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaCharsetReferenceContributor.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.psi.impl.source.resolve.reference.impl; - -import com.intellij.codeInsight.daemon.impl.analysis.encoding.EncodingReference; -import com.intellij.psi.*; -import com.intellij.psi.impl.source.resolve.reference.impl.manipulators.StringLiteralManipulator; -import com.intellij.util.ProcessingContext; -import org.jetbrains.annotations.NotNull; - -import java.nio.charset.Charset; - -import static com.intellij.patterns.PsiJavaPatterns.literalExpression; -import static com.intellij.patterns.PsiJavaPatterns.psiMethod; -import static com.intellij.patterns.StandardPatterns.string; - -/** - * @author peter - */ -public class JavaCharsetReferenceContributor extends PsiReferenceContributor { - @Override - public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { - registrar.registerReferenceProvider( - literalExpression().methodCallParameter( - 0, psiMethod().withName(string().oneOf("forName", "isSupported")).inClass(Charset.class.getName())), - new PsiReferenceProvider() { - @NotNull - @Override - public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { - PsiLiteralExpression literal = (PsiLiteralExpression)element; - Object value = literal.getValue(); - if (value instanceof String) { - return new PsiReference[]{new EncodingReference(element, (String)value, StringLiteralManipulator.getValueRange(literal))}; - } - return PsiReference.EMPTY_ARRAY; - } - }); - } -} diff --git a/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java b/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java index ffb122b1ca61..511d41f58986 100644 --- a/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java +++ b/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java @@ -20,14 +20,26 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.util.ProximityLocation; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Set; + +import static com.intellij.psi.CommonClassNames.*; + /** * @author peter */ public class KnownElementWeigher extends ProximityWeigher { + private static final Set<String> POPULAR_JDK_CLASSES = ContainerUtil.newHashSet( + JAVA_LANG_STRING, + JAVA_LANG_CLASS, + System.class.getName(), JAVA_LANG_RUNNABLE, + JAVA_LANG_EXCEPTION, JAVA_LANG_THROWABLE, JAVA_LANG_RUNTIME_EXCEPTION, + JAVA_UTIL_ARRAY_LIST, JAVA_UTIL_HASH_MAP, JAVA_UTIL_HASH_SET + ); @Override public Comparable weigh(@NotNull final PsiElement element, @NotNull final ProximityLocation location) { @@ -50,7 +62,7 @@ public class KnownElementWeigher extends ProximityWeigher { if (containingClass != null) { String methodName = method.getName(); if ("finalize".equals(methodName) || "registerNatives".equals(methodName) || methodName.startsWith("wait") || methodName.startsWith("notify")) { - if (CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { + if (JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { return -1; } } @@ -58,11 +70,11 @@ public class KnownElementWeigher extends ProximityWeigher { return -1; } if ("subSequence".equals(methodName)) { - if (CommonClassNames.JAVA_LANG_STRING.equals(containingClass.getQualifiedName())) { + if (JAVA_LANG_STRING.equals(containingClass.getQualifiedName())) { return -1; } } - if (CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { + if (JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { return 0; } return getJdkClassProximity(method.getContainingClass()); @@ -86,8 +98,8 @@ public class KnownElementWeigher extends ProximityWeigher { @NonNls final String qname = element.getQualifiedName(); if (qname != null) { String pkg = StringUtil.getPackageName(qname); - if (qname.equals(CommonClassNames.JAVA_LANG_OBJECT)) return 5; - if (isPopularJdkClass(qname)) return 8; + if (qname.equals(JAVA_LANG_OBJECT)) return 5; + if (POPULAR_JDK_CLASSES.contains(qname)) return 8; if (pkg.equals("java.lang")) return 6; if (pkg.equals("java.util")) return 7; @@ -103,13 +115,4 @@ public class KnownElementWeigher extends ProximityWeigher { return 0; } - private static boolean isPopularJdkClass(String qname) { - return qname.equals(CommonClassNames.JAVA_LANG_STRING) || - qname.equals(System.class.getName()) || - qname.equals(CommonClassNames.JAVA_LANG_EXCEPTION) || - qname.equals(CommonClassNames.JAVA_LANG_THROWABLE) || - qname.equals(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION) || - qname.equals(CommonClassNames.JAVA_LANG_RUNNABLE) || - qname.equals(CommonClassNames.JAVA_LANG_CLASS); - } }
\ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index 8a9eca38a529..6a44f2529284 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -15,7 +15,9 @@ */ package com.intellij.refactoring.changeSignature; +import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.codeInsight.InferredAnnotationsManager; import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil; import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer; import com.intellij.lang.StdLanguages; @@ -943,7 +945,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } private static void checkContract(MultiMap<PsiElement, String> conflictDescriptions, PsiMethod method) { - if (ControlFlowAnalyzer.findContractAnnotation(method) != null) { + PsiAnnotation contract = ControlFlowAnalyzer.findContractAnnotation(method); + if (contract != null && !AnnotationUtil.isInferredAnnotation(contract)) { conflictDescriptions.putValue(method, "@Contract annotation will have to be changed manually"); } } diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodUtil.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodUtil.java deleted file mode 100644 index f20ff1ca9ded..000000000000 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodUtil.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.refactoring.extractMethod; - -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Key; -import com.intellij.psi.*; -import com.intellij.psi.search.SearchScope; -import com.intellij.psi.search.searches.ClassInheritorsSearch; -import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.RedundantCastUtil; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.Processor; -import com.intellij.util.containers.HashMap; - -import java.util.Map; - -/** - * @author ven - */ -public class ExtractMethodUtil { - private static final Key<PsiMethod> RESOLVE_TARGET_KEY = Key.create("RESOLVE_TARGET_KEY"); - private static final Logger LOG = Logger.getInstance("com.intellij.refactoring.extractMethod.ExtractMethodUtil"); - - private ExtractMethodUtil() { } - - static Map<PsiMethodCallExpression, PsiMethod> encodeOverloadTargets(final PsiClass targetClass, - final SearchScope processConflictsScope, - final String overloadName, - final PsiElement extractedFragment) { - final Map<PsiMethodCallExpression, PsiMethod> ret = new HashMap<PsiMethodCallExpression, PsiMethod>(); - encodeInClass(targetClass, overloadName, extractedFragment, ret); - - ClassInheritorsSearch.search(targetClass, processConflictsScope, true).forEach(new Processor<PsiClass>() { - public boolean process(PsiClass inheritor) { - encodeInClass(inheritor, overloadName, extractedFragment, ret); - return true; - } - }); - - return ret; - } - - private static void encodeInClass(final PsiClass aClass, - final String overloadName, - final PsiElement extractedFragment, - final Map<PsiMethodCallExpression, PsiMethod> ret) { - final PsiMethod[] overloads = aClass.findMethodsByName(overloadName, false); - for (final PsiMethod overload : overloads) { - for (final PsiReference ref : ReferencesSearch.search(overload)) { - final PsiElement element = ref.getElement(); - final PsiElement parent = element.getParent(); - if (parent instanceof PsiMethodCallExpression) { - final PsiMethodCallExpression call = (PsiMethodCallExpression)parent; - if (PsiTreeUtil.isAncestor(extractedFragment, element, false)) { - call.putCopyableUserData(RESOLVE_TARGET_KEY, overload); - } else { - //we assume element won't be invalidated as a result of extraction - ret.put(call, overload); - } - } - } - } - } - - public static void decodeOverloadTargets(Map<PsiMethodCallExpression, PsiMethod> oldResolves, final PsiMethod extracted, - final PsiElement oldFragment) { - final PsiCodeBlock body = extracted.getBody(); - assert body != null; - final JavaRecursiveElementVisitor visitor = new JavaRecursiveElementVisitor() { - - @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { - super.visitMethodCallExpression(expression); - final PsiMethod target = expression.getCopyableUserData(RESOLVE_TARGET_KEY); - if (target != null) { - expression.putCopyableUserData(RESOLVE_TARGET_KEY, null); - try { - assertSameResolveTarget(target, expression, extracted); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - } - } - }; - body.accept(visitor); - oldFragment.accept(visitor); - - for (final Map.Entry<PsiMethodCallExpression, PsiMethod> entry : oldResolves.entrySet()) { - try { - assertSameResolveTarget(entry.getValue(), entry.getKey(), extracted); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - } - } - - private static void assertSameResolveTarget(final PsiMethod oldTarget, final PsiMethodCallExpression call, final PsiMethod extracted) - throws IncorrectOperationException { - final PsiMethod newTarget = call.resolveMethod(); - final PsiManager manager = extracted.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - if (!manager.areElementsEquivalent(oldTarget, newTarget)) { - final PsiParameter[] oldParameters = oldTarget.getParameterList().getParameters(); - if (oldParameters.length > 0) { - final PsiMethodCallExpression copy = (PsiMethodCallExpression)call.copy(); - final PsiExpression[] args = copy.getArgumentList().getExpressions(); - for (int i = 0; i < args.length; i++) { - PsiExpression arg = args[i]; - PsiType paramType = i < oldParameters.length ? oldParameters[i].getType() : oldParameters[oldParameters.length - 1].getType(); - final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(a)b", null); - final PsiTypeElement typeElement = cast.getCastType(); - assert typeElement != null; - typeElement.replace(factory.createTypeElement(paramType)); - final PsiExpression operand = cast.getOperand(); - assert operand != null; - operand.replace(arg); - arg.replace(cast); - } - - for (int i = 0; i < copy.getArgumentList().getExpressions().length; i++) { - PsiExpression oldarg = call.getArgumentList().getExpressions()[i]; - PsiTypeCastExpression cast = (PsiTypeCastExpression)copy.getArgumentList().getExpressions()[i]; - if (!RedundantCastUtil.isCastRedundant(cast)) { - oldarg.replace(cast); - } - } - } - } - } -} diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java index 7b68e338aa63..b29d02fad178 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java @@ -791,7 +791,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor { String[] names = myJavaCodeStyle.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, thisType) .names; String thisVarName = names[0]; - thisVarName = myJavaCodeStyle.suggestUniqueVariableName(thisVarName, block.getFirstChild(), true); + thisVarName = myJavaCodeStyle.suggestUniqueVariableName(thisVarName, myMethod.getFirstChild(), true); PsiExpression initializer = myFactory.createExpressionFromText("null", null); PsiDeclarationStatement declaration = myFactory.createVariableDeclarationStatement(thisVarName, thisType, initializer); declaration = (PsiDeclarationStatement)block.addAfter(declaration, null); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java index 731daff180c9..a751acea42df 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -405,7 +405,8 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); try { PsiField field = factory.createFieldFromText(pattern.toString(), null); - field.getTypeElement().replace(factory.createTypeElement(type)); + final PsiTypeElement typeElement = factory.createTypeElement(type); + field.getTypeElement().replace(typeElement); field = (PsiField)CodeStyleManager.getInstance(psiManager.getProject()).reformat(field); if (includeInitializer) { field.getInitializer().replace(initializerExpr); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java index 4238c2181f0b..ceae8aed2e44 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java @@ -224,6 +224,11 @@ public class InplaceIntroduceConstantPopup extends AbstractInplaceIntroduceField } @Override + protected String getRefactoringId() { + return "refactoring.extractConstant"; + } + + @Override protected boolean startsOnTheSameElement(RefactoringActionHandler handler, PsiElement element) { return super.startsOnTheSameElement(handler, element) && handler instanceof IntroduceConstantHandler; } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java index 4c1de5e39551..3998a93d1b54 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java @@ -148,6 +148,11 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop } } + @Override + protected String getRefactoringId() { + return "refactoring.extractField"; + } + public void setVisibility(String visibility) { myIntroduceFieldPanel.setVisibility(visibility); } @@ -203,6 +208,8 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop protected void performIntroduce() { ourLastInitializerPlace = myIntroduceFieldPanel.getInitializerPlace(); + final PsiType forcedType = getType(); + LOG.assertTrue(forcedType == null || forcedType.isValid(), forcedType); final BaseExpressionToFieldHandler.Settings settings = new BaseExpressionToFieldHandler.Settings(getInputName(), getExpr(), @@ -211,7 +218,7 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop myIntroduceFieldPanel.isDeclareFinal(), myIntroduceFieldPanel.getInitializerPlace(), myIntroduceFieldPanel.getFieldVisibility(), (PsiLocalVariable)getLocalVariable(), - getType(), + forcedType, myIntroduceFieldPanel.isDeleteVariable(), myParentClass, false, false); new WriteCommandAction(myProject, getCommandName(), getCommandName()){ diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java index dc1f1668d744..152172597d6e 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java @@ -348,6 +348,15 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem return data; } + @Nullable + @Override + protected RefactoringEventData getAfterData(UsageInfo[] usages) { + final PsiParameter parameter = JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethodToReplaceIn); + final RefactoringEventData afterData = new RefactoringEventData(); + afterData.addElement(parameter); + return afterData; + } + protected void performRefactoring(UsageInfo[] usages) { try { PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 0e513d4d39d0..16fc097bc612 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -61,6 +61,8 @@ import com.intellij.refactoring.*; import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer; import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; import com.intellij.refactoring.introduceField.ElementToWorkOn; +import com.intellij.refactoring.listeners.RefactoringEventData; +import com.intellij.refactoring.listeners.RefactoringEventListener; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.FieldConflictsResolver; @@ -85,7 +87,8 @@ import java.util.*; public abstract class IntroduceVariableBase extends IntroduceHandlerBase { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceVariable.IntroduceVariableBase"); @NonNls private static final String PREFER_STATEMENTS_OPTION = "introduce.variable.prefer.statements"; - + @NonNls private static final String REFACTORING_ID = "refactoring.extractVariable"; + protected static final String REFACTORING_NAME = RefactoringBundle.message("introduce.variable.title"); public static final Key<Boolean> NEED_PARENTHESIS = Key.create("NEED_PARENTHESIS"); @@ -677,13 +680,27 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { occurrenceMarkers.add(topLevelEditor.getDocument().createRangeMarker(occurrence.getTextRange())); } } + final RefactoringEventData beforeData = new RefactoringEventData(); + beforeData.addElement(expr); + project.getMessageBus() + .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(REFACTORING_ID, beforeData); final String expressionText = expr.getText(); final Runnable runnable = introduce(project, expr, topLevelEditor, chosenAnchor, occurrences, settings, variable); CommandProcessor.getInstance().executeCommand( project, new Runnable() { public void run() { - ApplicationManager.getApplication().runWriteAction(runnable); + try { + ApplicationManager.getApplication().runWriteAction(runnable); + } + finally { + final RefactoringEventData afterData = new RefactoringEventData(); + final SmartPsiElementPointer<PsiVariable> pointer = variable.get(); + afterData.addElement(pointer != null ? pointer.getElement() : null); + project.getMessageBus() + .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(REFACTORING_ID, afterData); + } + if (isInplaceAvailableOnDataContext) { final PsiVariable elementToRename = variable.get().getElement(); if (elementToRename != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelper.java index 39913cdf2a60..ab86ee853b3b 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelper.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelper.java @@ -219,7 +219,10 @@ public class JavaPullUpHelper implements PullUpHelper<MemberInfo> { } } PsiMethod methodCopy = (PsiMethod)method.copy(); - if (method.findSuperMethods(myTargetSuperClass).length == 0) { + Language language = myTargetSuperClass.getLanguage(); + final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false); + if (superClassMethod != null && superClassMethod.findDeepestSuperMethods().length == 0 || + method.findSuperMethods(myTargetSuperClass).length == 0) { deleteOverrideAnnotationIfFound(methodCopy); } boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT); @@ -238,7 +241,14 @@ public class JavaPullUpHelper implements PullUpHelper<MemberInfo> { myJavaDocPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract); - final PsiMember movedElement = anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy); + final PsiMember movedElement; + if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + movedElement = (PsiMember)superClassMethod.replace(convertMethodToLanguage(methodCopy, language)); + } + else { + movedElement = + anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy); + } CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject()); if (styleSettings.INSERT_OVERRIDE_ANNOTATION) { if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myIsTargetInterface || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) { @@ -265,8 +275,6 @@ public class JavaPullUpHelper implements PullUpHelper<MemberInfo> { RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); fixReferencesToStatic(methodCopy); - Language language = myTargetSuperClass.getLanguage(); - final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false); if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { superClassMethod.replace(convertMethodToLanguage(methodCopy, language)); } diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java index b92c5f52bfa9..3fd4e334a01f 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java @@ -196,7 +196,7 @@ public class PullUpDialog extends PullUpDialogBase<MemberInfoStorage, MemberInfo final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(currentSuperClass, myClass, PsiSubstitutor.EMPTY); final MethodSignature signature = ((PsiMethod) element).getSignature(superSubstitutor); final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false); - if (superClassMethod != null) return false; + if (superClassMethod != null && !PsiUtil.isLanguageLevel8OrHigher(currentSuperClass)) return false; return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC) || PsiUtil.isLanguageLevel8OrHigher(currentSuperClass); } return true; diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java index c1bc3bf60038..ce19d6bacaa5 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java @@ -102,6 +102,6 @@ public class AutocreatingSingleSourceRootMoveDestination extends AutocreatingMov if (myTargetDirectory == null) { myTargetDirectory = RefactoringUtil.createPackageDirectoryInSourceRoot(myPackage, mySourceRoot); } - return RefactoringUtil.createPackageDirectoryInSourceRoot(myPackage, mySourceRoot); + return myTargetDirectory; } } diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java index 895334d12abe..5e5b620bcd31 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java @@ -131,7 +131,7 @@ public class DuplicatesImpl { } HighlightManager.getInstance(project).removeSegmentHighlighter(editor, highlighters.get(0)); - new WriteCommandAction(project, MethodDuplicatesHandler.REFACTORING_NAME) { + new WriteCommandAction(project, MethodDuplicatesHandler.REFACTORING_NAME, MethodDuplicatesHandler.REFACTORING_NAME) { @Override protected void run(Result result) throws Throwable { try { diff --git a/java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java b/java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java index 2eade6903cd2..5d10f0714eda 100644 --- a/java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java +++ b/java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package com.intellij.spellchecker; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.PsiLiteralExpression; import com.intellij.psi.PsiModifierListOwner; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; @@ -37,12 +36,10 @@ import java.util.Collections; public class LiteralExpressionTokenizer extends Tokenizer<PsiLiteralExpression> { @Override public void tokenize(@NotNull PsiLiteralExpression element, TokenConsumer consumer) { - PsiLiteralExpressionImpl literalExpression = (PsiLiteralExpressionImpl) element; - if (literalExpression.getLiteralElementType() != JavaTokenType.STRING_LITERAL) { - return; // not a string literal - } + PsiLiteralExpressionImpl literalExpression = (PsiLiteralExpressionImpl)element; + if (literalExpression.getLiteralElementType() != JavaTokenType.STRING_LITERAL) return; // not a string literal - if (InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)element)) return; + if (InjectedLanguageUtil.hasInjections(literalExpression)) return; final PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class); if (listOwner != null && AnnotationUtil.isAnnotated(listOwner, Collections.singleton(AnnotationUtil.NON_NLS), false, false)) { diff --git a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java index 40a97cf93981..6d82acdbdf8e 100644 --- a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java +++ b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java @@ -24,9 +24,10 @@ import com.intellij.codeInsight.generation.actions.BaseGenerateAction; import com.intellij.codeInsight.hint.HintManager; import com.intellij.ide.fileTemplates.FileTemplateDescriptor; import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable; -import com.intellij.ide.util.EditSourceUtil; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -40,7 +41,6 @@ import com.intellij.ui.components.JBList; import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -100,7 +100,7 @@ public class BaseGenerateTestSupportMethodAction extends BaseGenerateAction { private static PsiClass findTargetClass(@NotNull Editor editor, @NotNull PsiFile file) { int offset = editor.getCaretModel().getOffset(); PsiElement element = file.findElementAt(offset); - return element == null ? null : TestIntegrationUtils.findOuterClass(element); + return PsiTreeUtil.getParentOfType(element, PsiClass.class, false) == null ? null : TestIntegrationUtils.findOuterClass(element); } @Override |