Search in sources :

Example 1 with PsiDocMethodOrFieldRef

use of com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef in project intellij-community by JetBrains.

the class JavaSafeDeleteDelegateImpl method createUsageInfoForParameter.

@Override
public void createUsageInfoForParameter(final PsiReference reference, final List<UsageInfo> usages, final PsiParameter parameter, final PsiMethod method) {
    int index = method.getParameterList().getParameterIndex(parameter);
    final PsiElement element = reference.getElement();
    PsiCall call = null;
    if (element instanceof PsiCall) {
        call = (PsiCall) element;
    } else {
        final PsiElement parent = element.getParent();
        if (parent instanceof PsiCall) {
            call = (PsiCall) parent;
        } else if (parent instanceof PsiAnonymousClass) {
            call = (PsiNewExpression) parent.getParent();
        }
    }
    if (call != null) {
        final PsiExpressionList argList = call.getArgumentList();
        if (argList != null) {
            final PsiExpression[] args = argList.getExpressions();
            if (index < args.length) {
                if (!parameter.isVarArgs()) {
                    usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(args[index], parameter));
                } else {
                    for (int i = index; i < args.length; i++) {
                        usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(args[i], parameter));
                    }
                }
            }
        }
    } else if (element instanceof PsiDocMethodOrFieldRef) {
        if (((PsiDocMethodOrFieldRef) element).getSignature() != null) {
            @NonNls final StringBuffer newText = new StringBuffer();
            newText.append("/** @see #").append(method.getName()).append('(');
            final List<PsiParameter> parameters = new ArrayList<>(Arrays.asList(method.getParameterList().getParameters()));
            parameters.remove(parameter);
            newText.append(StringUtil.join(parameters, psiParameter -> psiParameter.getType().getCanonicalText(), ","));
            newText.append(")*/");
            usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(element, parameter, true) {

                public void deleteElement() throws IncorrectOperationException {
                    final PsiDocMethodOrFieldRef.MyReference javadocMethodReference = (PsiDocMethodOrFieldRef.MyReference) element.getReference();
                    if (javadocMethodReference != null) {
                        javadocMethodReference.bindToText(method.getContainingClass(), newText);
                    }
                }
            });
        }
    } else if (element instanceof PsiMethodReferenceExpression) {
        usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(element, parameter, true) {

            public void deleteElement() throws IncorrectOperationException {
                final PsiExpression callExpression = LambdaRefactoringUtil.convertToMethodCallInLambdaBody((PsiMethodReferenceExpression) element);
                if (callExpression instanceof PsiCallExpression) {
                    final PsiExpressionList expressionList = ((PsiCallExpression) callExpression).getArgumentList();
                    if (expressionList != null) {
                        final PsiExpression[] args = expressionList.getExpressions();
                        if (index < args.length) {
                            args[index].delete();
                        }
                    }
                }
            }
        });
    }
}
Also used : SafeDeleteReferenceJavaDeleteUsageInfo(com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceJavaDeleteUsageInfo) PsiDocMethodOrFieldRef(com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef) ArrayList(java.util.ArrayList) List(java.util.List) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Example 2 with PsiDocMethodOrFieldRef

use of com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef in project intellij-community by JetBrains.

the class InlineConstantFieldProcessor method preprocessUsages.

@Override
protected boolean preprocessUsages(@NotNull Ref<UsageInfo[]> refUsages) {
    UsageInfo[] usagesIn = refUsages.get();
    MultiMap<PsiElement, String> conflicts = new MultiMap<>();
    ReferencedElementsCollector collector = new ReferencedElementsCollector();
    PsiExpression initializer = InlineConstantFieldHandler.getInitializer(myField);
    LOG.assertTrue(initializer != null);
    initializer.accept(collector);
    HashSet<PsiMember> referencedWithVisibility = collector.myReferencedMembers;
    PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(myField.getProject()).getResolveHelper();
    for (UsageInfo info : usagesIn) {
        PsiElement element = info.getElement();
        if (element instanceof PsiExpression && (!myField.hasModifierProperty(PsiModifier.FINAL) || myInlineThisOnly) && isAccessedForWriting((PsiExpression) element)) {
            String message = RefactoringBundle.message("0.is.used.for.writing.in.1", RefactoringUIUtil.getDescription(myField, true), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true));
            conflicts.putValue(element, message);
        }
        for (PsiMember member : referencedWithVisibility) {
            if (!resolveHelper.isAccessible(member, element, null)) {
                String message = RefactoringBundle.message("0.will.not.be.accessible.from.1.after.inlining", RefactoringUIUtil.getDescription(member, true), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true));
                conflicts.putValue(member, message);
            }
        }
    }
    if (!myInlineThisOnly) {
        for (UsageInfo info : usagesIn) {
            if (info instanceof UsageFromJavaDoc) {
                final PsiElement element = info.getElement();
                if (element instanceof PsiDocMethodOrFieldRef && !PsiTreeUtil.isAncestor(myField, element, false)) {
                    conflicts.putValue(element, "Inlined method is used in javadoc");
                }
            }
        }
    }
    return showConflicts(conflicts, usagesIn);
}
Also used : MultiMap(com.intellij.util.containers.MultiMap) PsiDocMethodOrFieldRef(com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef) UsageInfo(com.intellij.usageView.UsageInfo)

Example 3 with PsiDocMethodOrFieldRef

use of com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef in project intellij-community by JetBrains.

the class HighlightVisitorImpl method visitDocTagValue.

@Override
public void visitDocTagValue(PsiDocTagValue value) {
    PsiReference reference = value.getReference();
    if (reference != null) {
        PsiElement element = reference.resolve();
        final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
        if (element instanceof PsiMethod) {
            PsiElement nameElement = ((PsiDocMethodOrFieldRef) value).getNameElement();
            if (nameElement != null) {
                myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod) element, nameElement, false, colorsScheme));
            }
        } else if (element instanceof PsiParameter) {
            myHolder.add(HighlightNamesUtil.highlightVariableName((PsiVariable) element, value.getNavigationElement(), colorsScheme));
        }
    }
}
Also used : PsiDocMethodOrFieldRef(com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef) TextAttributesScheme(com.intellij.openapi.editor.colors.TextAttributesScheme) LocalQuickFixAndIntentionActionOnPsiElement(com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement)

Example 4 with PsiDocMethodOrFieldRef

use of com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef in project intellij-community by JetBrains.

the class InlineMethodProcessor method doRefactoring.

private void doRefactoring(UsageInfo[] usages) {
    try {
        if (myInlineThisOnly) {
            if (myMethod.isConstructor() && InlineMethodHandler.isChainingConstructor(myMethod)) {
                if (myReference instanceof PsiMethodReferenceExpression) {
                    inlineMethodReference((PsiMethodReferenceExpression) myReference);
                } else {
                    PsiCall constructorCall = RefactoringUtil.getEnclosingConstructorCall(myReference);
                    if (constructorCall != null) {
                        inlineConstructorCall(constructorCall);
                    }
                }
            } else {
                myReference = addBracesWhenNeeded(new PsiReferenceExpression[] { (PsiReferenceExpression) myReference })[0];
                if (myReference instanceof PsiMethodReferenceExpression) {
                    inlineMethodReference((PsiMethodReferenceExpression) myReference);
                } else {
                    inlineMethodCall((PsiReferenceExpression) myReference);
                }
            }
        } else {
            CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usages);
            if (myMethod.isConstructor()) {
                for (UsageInfo usage : usages) {
                    PsiElement element = usage.getElement();
                    if (element instanceof PsiMethodReferenceExpression) {
                        inlineMethodReference((PsiMethodReferenceExpression) element);
                    } else if (element instanceof PsiJavaCodeReferenceElement) {
                        PsiCall constructorCall = RefactoringUtil.getEnclosingConstructorCall((PsiJavaCodeReferenceElement) element);
                        if (constructorCall != null) {
                            inlineConstructorCall(constructorCall);
                        }
                    } else if (element instanceof PsiEnumConstant) {
                        inlineConstructorCall((PsiEnumConstant) element);
                    } else if (!(element instanceof PsiDocMethodOrFieldRef)) {
                        GenericInlineHandler.inlineReference(usage, myMethod, myInliners);
                    }
                }
            } else {
                List<PsiReferenceExpression> refExprList = new ArrayList<>();
                final List<PsiElement> imports2Delete = new ArrayList<>();
                for (final UsageInfo usage : usages) {
                    final PsiElement element = usage.getElement();
                    if (element instanceof PsiReferenceExpression) {
                        refExprList.add((PsiReferenceExpression) element);
                    } else if (element instanceof PsiImportStaticReferenceElement) {
                        final JavaResolveResult[] resolveResults = ((PsiImportStaticReferenceElement) element).multiResolve(false);
                        if (resolveResults.length < 2) {
                            //no overloads available: ensure broken import are deleted and
                            //unused overloaded imports are deleted by optimize imports helper
                            imports2Delete.add(PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class));
                        }
                    } else if (element instanceof PsiMethod) {
                        PsiAnnotation annotation = AnnotationUtil.findAnnotation((PsiMethod) element, false, Override.class.getName());
                        if (annotation != null) {
                            annotation.delete();
                        }
                    } else if (JavaLanguage.INSTANCE != element.getLanguage()) {
                        GenericInlineHandler.inlineReference(usage, myMethod, myInliners);
                    }
                }
                PsiReferenceExpression[] refs = refExprList.toArray(new PsiReferenceExpression[refExprList.size()]);
                refs = addBracesWhenNeeded(refs);
                for (PsiReferenceExpression ref : refs) {
                    if (ref instanceof PsiMethodReferenceExpression) {
                        inlineMethodReference((PsiMethodReferenceExpression) ref);
                    } else {
                        inlineMethodCall(ref);
                    }
                }
                for (PsiElement psiElement : imports2Delete) {
                    if (psiElement != null && psiElement.isValid()) {
                        psiElement.delete();
                    }
                }
            }
            if (myMethod.isWritable() && myDeleteTheDeclaration)
                myMethod.delete();
        }
        removeAddedBracesWhenPossible();
    } catch (IncorrectOperationException e) {
        LOG.error(e);
    }
}
Also used : PsiDocMethodOrFieldRef(com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef) IncorrectOperationException(com.intellij.util.IncorrectOperationException) UsageInfo(com.intellij.usageView.UsageInfo)

Example 5 with PsiDocMethodOrFieldRef

use of com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef in project intellij-community by JetBrains.

the class InlineMethodProcessor method preprocessUsages.

protected boolean preprocessUsages(@NotNull Ref<UsageInfo[]> refUsages) {
    if (!myInlineThisOnly && checkReadOnly()) {
        if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, myMethod))
            return false;
    }
    final UsageInfo[] usagesIn = refUsages.get();
    final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
    if (!myInlineThisOnly) {
        final PsiMethod[] superMethods = myMethod.findSuperMethods();
        for (PsiMethod method : superMethods) {
            final String message = method.hasModifierProperty(PsiModifier.ABSTRACT) ? RefactoringBundle.message("inlined.method.implements.method.from.0", method.getContainingClass().getQualifiedName()) : RefactoringBundle.message("inlined.method.overrides.method.from.0", method.getContainingClass().getQualifiedName());
            conflicts.putValue(method, message);
        }
        for (UsageInfo info : usagesIn) {
            final PsiElement element = info.getElement();
            if (element instanceof PsiDocMethodOrFieldRef && !PsiTreeUtil.isAncestor(myMethod, element, false)) {
                conflicts.putValue(element, "Inlined method is used in javadoc");
            }
            if (element instanceof PsiMethodReferenceExpression) {
                final PsiExpression qualifierExpression = ((PsiMethodReferenceExpression) element).getQualifierExpression();
                if (qualifierExpression != null) {
                    final List<PsiElement> sideEffects = new ArrayList<>();
                    SideEffectChecker.checkSideEffects(qualifierExpression, sideEffects);
                    if (!sideEffects.isEmpty()) {
                        conflicts.putValue(element, "Inlined method is used in method reference with side effects in qualifier");
                    }
                }
            }
            final String errorMessage = checkCalledInSuperOrThisExpr(myMethod.getBody(), element);
            if (errorMessage != null) {
                conflicts.putValue(element, errorMessage);
            }
        }
    }
    ArrayList<PsiReference> refs = convertUsagesToRefs(usagesIn);
    myInliners = GenericInlineHandler.initializeInliners(myMethod, new InlineHandler.Settings() {

        @Override
        public boolean isOnlyOneReferenceToInline() {
            return myInlineThisOnly;
        }
    }, refs);
    //hack to prevent conflicts 'Cannot inline reference from Java'
    myInliners.put(JavaLanguage.INSTANCE, new InlineHandler.Inliner() {

        @Nullable
        @Override
        public MultiMap<PsiElement, String> getConflicts(PsiReference reference, PsiElement referenced) {
            return MultiMap.emptyInstance();
        }

        @Override
        public void inlineUsage(@NotNull UsageInfo usage, @NotNull PsiElement referenced) {
            if (usage instanceof NonCodeUsageInfo)
                return;
            throw new UnsupportedOperationException("usage: " + usage.getClass().getName() + ", usage element: " + usage.getElement() + ", referenced: " + referenced.getClass().getName() + ", text: " + referenced.getText());
        }
    });
    for (PsiReference ref : refs) {
        GenericInlineHandler.collectConflicts(ref, myMethod, myInliners, conflicts);
    }
    final PsiReturnStatement[] returnStatements = PsiUtil.findReturnStatements(myMethod);
    for (PsiReturnStatement statement : returnStatements) {
        PsiExpression value = statement.getReturnValue();
        if (value != null && !(value instanceof PsiCallExpression)) {
            for (UsageInfo info : usagesIn) {
                PsiReference reference = info.getReference();
                if (reference != null) {
                    InlineUtil.TailCallType type = InlineUtil.getTailCallType(reference);
                    if (type == InlineUtil.TailCallType.Simple) {
                        conflicts.putValue(statement, "Inlined result would contain parse errors");
                        break;
                    }
                }
            }
        }
    }
    addInaccessibleMemberConflicts(myMethod, usagesIn, new ReferencedElementsCollector(), conflicts);
    addInaccessibleSuperCallsConflicts(usagesIn, conflicts);
    return showConflicts(conflicts, usagesIn);
}
Also used : MultiMap(com.intellij.util.containers.MultiMap) UsageInfo(com.intellij.usageView.UsageInfo) InlineHandler(com.intellij.lang.refactoring.InlineHandler) PsiDocMethodOrFieldRef(com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

PsiDocMethodOrFieldRef (com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef)5 UsageInfo (com.intellij.usageView.UsageInfo)3 IncorrectOperationException (com.intellij.util.IncorrectOperationException)2 MultiMap (com.intellij.util.containers.MultiMap)2 LocalQuickFixAndIntentionActionOnPsiElement (com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement)1 InlineHandler (com.intellij.lang.refactoring.InlineHandler)1 TextAttributesScheme (com.intellij.openapi.editor.colors.TextAttributesScheme)1 SafeDeleteReferenceJavaDeleteUsageInfo (com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceJavaDeleteUsageInfo)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Nullable (org.jetbrains.annotations.Nullable)1