private void fixReferencesToStatic(PsiElement classMember) throws IncorrectOperationException { final StaticReferencesCollector collector = new StaticReferencesCollector(); classMember.accept(collector); ArrayList<PsiJavaCodeReferenceElement> refs = collector.getReferences(); ArrayList<PsiElement> members = collector.getReferees(); ArrayList<PsiClass> classes = collector.getRefereeClasses(); PsiElementFactory factory = JavaPsiFacade.getInstance(classMember.getProject()).getElementFactory(); for (int i = 0; i < refs.size(); i++) { PsiJavaCodeReferenceElement ref = refs.get(i); PsiElement namedElement = members.get(i); PsiClass aClass = classes.get(i); if (namedElement instanceof PsiNamedElement) { PsiReferenceExpression newRef = (PsiReferenceExpression) factory.createExpressionFromText( "a." + ((PsiNamedElement) namedElement).getName(), null); PsiExpression qualifierExpression = newRef.getQualifierExpression(); assert qualifierExpression != null; qualifierExpression = (PsiExpression) qualifierExpression.replace(factory.createReferenceExpression(aClass)); qualifierExpression.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified()); ref.replace(newRef); } } }
private static boolean isParameterUsedRecursively( @NotNull PsiElement element, @NotNull List<PsiReference> array) { if (!(element instanceof PsiParameter)) return false; PsiParameter parameter = (PsiParameter) element; PsiElement scope = parameter.getDeclarationScope(); if (!(scope instanceof PsiMethod)) return false; PsiMethod method = (PsiMethod) scope; int paramIndex = ArrayUtilRt.find(method.getParameterList().getParameters(), parameter); for (PsiReference reference : array) { if (!(reference instanceof PsiElement)) return false; PsiElement argument = (PsiElement) reference; PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) new PsiMatcherImpl(argument) .dot(PsiMatchers.hasClass(PsiReferenceExpression.class)) .parent(PsiMatchers.hasClass(PsiExpressionList.class)) .parent(PsiMatchers.hasClass(PsiMethodCallExpression.class)) .getElement(); if (methodCallExpression == null) return false; PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); if (method != methodExpression.resolve()) return false; PsiExpressionList argumentList = methodCallExpression.getArgumentList(); PsiExpression[] arguments = argumentList.getExpressions(); int argumentIndex = ArrayUtilRt.find(arguments, argument); if (paramIndex != argumentIndex) return false; } return true; }
@Nullable private static PsiType guessElementTypeFromReference( MethodPatternMap methodPatternMap, PsiElement ref, TextRange rangeToIgnore) { PsiElement refParent = ref.getParent(); if (refParent instanceof PsiReferenceExpression) { PsiReferenceExpression parentExpr = (PsiReferenceExpression) refParent; if (ref.equals(parentExpr.getQualifierExpression()) && parentExpr.getParent() instanceof PsiMethodCallExpression) { String methodName = parentExpr.getReferenceName(); PsiMethodCallExpression methodCall = (PsiMethodCallExpression) parentExpr.getParent(); PsiExpression[] args = methodCall.getArgumentList().getExpressions(); MethodPattern pattern = methodPatternMap.findPattern(methodName, args.length); if (pattern != null) { if (pattern.parameterIndex < 0) { // return value if (methodCall.getParent() instanceof PsiTypeCastExpression && (rangeToIgnore == null || !rangeToIgnore.contains(methodCall.getTextRange()))) { return ((PsiTypeCastExpression) methodCall.getParent()).getType(); } } else { return args[pattern.parameterIndex].getType(); } } } } return null; }
@Nullable private static PsiClass getFieldOrMethodAccessedClass( PsiReferenceExpression ref, PsiClass fieldOrMethodClass) { PsiElement[] children = ref.getChildren(); if (children.length > 1 && children[0] instanceof PsiExpression) { PsiExpression expr = (PsiExpression) children[0]; PsiType type = expr.getType(); if (type != null) { if (!(type instanceof PsiClassType)) return null; return PsiUtil.resolveClassInType(type); } else { if (expr instanceof PsiReferenceExpression) { PsiElement refElement = ((PsiReferenceExpression) expr).resolve(); if (refElement instanceof PsiClass) return (PsiClass) refElement; } return null; } } PsiManager manager = ref.getManager(); for (PsiElement parent = ref; parent != null; parent = parent.getParent()) { if (parent instanceof PsiClass && (manager.areElementsEquivalent(parent, fieldOrMethodClass) || ((PsiClass) parent).isInheritor(fieldOrMethodClass, true))) { return (PsiClass) parent; } } return null; }
private void findUsagesForMethod(PsiMethod method, List<FixableUsageInfo> usages) { final PsiManager psiManager = method.getManager(); final Project project = psiManager.getProject(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); final Iterable<PsiReference> calls = ReferencesSearch.search(method, scope); for (PsiReference reference : calls) { final PsiElement referenceElement = reference.getElement(); final PsiElement parent = referenceElement.getParent(); if (parent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression call = (PsiMethodCallExpression) parent; if (isInMovedElement(call)) { continue; } final PsiReferenceExpression methodExpression = call.getMethodExpression(); final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (qualifier == null || qualifier instanceof PsiThisExpression) { usages.add(new ReplaceThisCallWithDelegateCall(call, delegateFieldName)); } delegationRequired = true; } } if (!delegationRequired && MethodInheritanceUtils.hasSiblingMethods(method)) { delegationRequired = true; } if (delegationRequired) { usages.add(new MakeMethodDelegate(method, delegateFieldName)); } else { usages.add(new RemoveMethod(method)); } }
private static void replaceReferences( List<PsiReferenceExpression> references, PsiElement newExpression) throws IncorrectOperationException { for (PsiReferenceExpression reference : references) { reference.replace(newExpression); } }
private PsiField getReferencedField(PsiExpression expression) { if (expression instanceof PsiParenthesizedExpression) { final PsiExpression contents = ((PsiParenthesizedExpression) expression).getExpression(); return getReferencedField(contents); } final PsiReferenceExpression reference = (PsiReferenceExpression) expression; return (PsiField) reference.resolve(); }
@Override public void visitReferenceExpression(PsiReferenceExpression expression) { if (expression.getQualifierExpression() instanceof PsiSuperExpression) { PsiElement resolved = expression.resolve(); if (resolved == null || resolved instanceof PsiMethod && shouldFixSuper((PsiMethod) resolved)) { expression.getQualifierExpression().delete(); } } }
private static void processParameterUsage( PsiReferenceExpression ref, String oldName, String newName) throws IncorrectOperationException { PsiElement last = ref.getReferenceNameElement(); if (last instanceof PsiIdentifier && last.getText().equals(oldName)) { PsiElementFactory factory = JavaPsiFacade.getInstance(ref.getProject()).getElementFactory(); PsiIdentifier newNameIdentifier = factory.createIdentifier(newName); last.replace(newNameIdentifier); } }
@Override public void visitReferenceExpression(final PsiReferenceExpression reference) { if (myLineRange.intersects(reference.getTextRange())) { final PsiElement psiElement = reference.resolve(); if (psiElement instanceof PsiVariable) { final PsiVariable var = (PsiVariable) psiElement; if (var instanceof PsiField) { if (myCollectExpressions && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars( reference, myVisibleLocals)) { /* if (var instanceof PsiEnumConstant && reference.getQualifier() == null) { final PsiClass enumClass = ((PsiEnumConstant)var).getContainingClass(); if (enumClass != null) { final PsiExpression expression = JavaPsiFacade.getInstance(var.getProject()).getParserFacade().createExpressionFromText(enumClass.getName() + "." + var.getName(), var); final PsiReference ref = expression.getReference(); if (ref != null) { ref.bindToElement(var); myExpressions.add(new TextWithImportsImpl(expression)); } } } else { myExpressions.add(new TextWithImportsImpl(reference)); } */ final PsiModifierList modifierList = var.getModifierList(); boolean isConstant = (var instanceof PsiEnumConstant) || (modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC) && modifierList.hasModifierProperty(PsiModifier.FINAL)); if (!isConstant) { myExpressions.add(new TextWithImportsImpl(reference)); } } } else { if (myVisibleLocals.contains(var.getName())) { myVars.add(var.getName()); } else { // fix for variables used in inner classes if (!Comparing.equal( PsiTreeUtil.getParentOfType(reference, PsiClass.class), PsiTreeUtil.getParentOfType(var, PsiClass.class))) { myExpressions.add(new TextWithImportsImpl(reference)); } } } } } super.visitReferenceExpression(reference); }
@Override public void visitReferenceExpression(PsiReferenceExpression expression) { final PsiExpression qualifierExpression = expression.getQualifierExpression(); if (qualifierExpression != null && !(qualifierExpression instanceof PsiThisExpression)) { return; } final PsiElement resolved = expression.resolve(); if (resolved instanceof PsiParameter) { myUsedParameters.add((PsiParameter) resolved); } else if (myMovedFields.contains(resolved)) { myUsedFields.add((PsiField) resolved); } }
public void updateReturnValueTemplate(PsiExpression expression) { if (myReturnValueTemplate == null) return; if (!getSuperMethods().isEmpty()) { for (final RefMethod refMethod : getSuperMethods()) { RefMethodImpl refSuper = (RefMethodImpl) refMethod; refSuper.updateReturnValueTemplate(expression); } } else { String newTemplate = null; final RefJavaUtil refUtil = RefJavaUtil.getInstance(); if (expression instanceof PsiLiteralExpression) { PsiLiteralExpression psiLiteralExpression = (PsiLiteralExpression) expression; newTemplate = psiLiteralExpression.getText(); } else if (expression instanceof PsiReferenceExpression) { PsiReferenceExpression referenceExpression = (PsiReferenceExpression) expression; PsiElement resolved = referenceExpression.resolve(); if (resolved instanceof PsiField) { PsiField psiField = (PsiField) resolved; if (psiField.hasModifierProperty(PsiModifier.STATIC) && psiField.hasModifierProperty(PsiModifier.FINAL) && refUtil.compareAccess(refUtil.getAccessModifier(psiField), getAccessModifier()) >= 0) { newTemplate = PsiFormatUtil.formatVariable( psiField, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_FQ_NAME, PsiSubstitutor.EMPTY); } } } else if (refUtil.isCallToSuperMethod(expression, (PsiMethod) getElement())) return; //noinspection StringEquality if (myReturnValueTemplate == RETURN_VALUE_UNDEFINED) { myReturnValueTemplate = newTemplate; } else if (!Comparing.equal(myReturnValueTemplate, newTemplate)) { myReturnValueTemplate = null; } } }
public static boolean insertTail( InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) { TailType toInsert = tailType; LookupItem<?> lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY); if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) { if (!hasTail && item.getObject() instanceof PsiMethod && ((PsiMethod) item.getObject()).getReturnType() == PsiType.VOID) { PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); if (psiElement() .beforeLeaf(psiElement().withText(".")) .accepts(context.getFile().findElementAt(context.getTailOffset() - 1))) { return false; } boolean insertAdditionalSemicolon = true; final PsiReferenceExpression referenceExpression = PsiTreeUtil.getTopmostParentOfType( context.getFile().findElementAt(context.getStartOffset()), PsiReferenceExpression.class); if (referenceExpression instanceof PsiMethodReferenceExpression && LambdaHighlightingUtil.insertSemicolon(referenceExpression.getParent())) { insertAdditionalSemicolon = false; } else if (referenceExpression != null) { PsiElement parent = referenceExpression.getParent(); if (parent instanceof PsiMethodCallExpression) { parent = parent.getParent(); } if (parent instanceof PsiLambdaExpression && !LambdaHighlightingUtil.insertSemicolonAfter((PsiLambdaExpression) parent)) { insertAdditionalSemicolon = false; } } if (insertAdditionalSemicolon) { toInsert = TailType.SEMICOLON; } } } toInsert.processTail(context.getEditor(), context.getTailOffset()); return true; }
@Override public void updateUsage(PsiElement element) { if (element instanceof PsiReferenceExpression) { PsiExpression qualifierExpression = ((PsiReferenceExpression) element).getQualifierExpression(); if (qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression) qualifierExpression).resolve() == mySourceClass) { ((PsiReferenceExpression) qualifierExpression).bindToElement(myTargetSuperClass); } } }
@Nullable public NonCodeUsageSearchInfo findUsages( @NotNull final PsiElement element, @NotNull final PsiElement[] allElementsToDelete, @NotNull final List<UsageInfo> usages) { Condition<PsiElement> insideDeletedCondition = getUsageInsideDeletedFilter(allElementsToDelete); if (element instanceof PsiClass) { findClassUsages((PsiClass) element, allElementsToDelete, usages); if (element instanceof PsiTypeParameter) { findTypeParameterExternalUsages((PsiTypeParameter) element, usages); } } else if (element instanceof PsiMethod) { insideDeletedCondition = findMethodUsages((PsiMethod) element, allElementsToDelete, usages); } else if (element instanceof PsiField) { insideDeletedCondition = findFieldUsages((PsiField) element, usages, allElementsToDelete); } else if (element instanceof PsiParameter) { LOG.assertTrue(((PsiParameter) element).getDeclarationScope() instanceof PsiMethod); findParameterUsages((PsiParameter) element, usages); } else if (element instanceof PsiLocalVariable) { for (PsiReference reference : ReferencesSearch.search(element)) { PsiReferenceExpression referencedElement = (PsiReferenceExpression) reference.getElement(); final PsiStatement statement = PsiTreeUtil.getParentOfType(referencedElement, PsiStatement.class); boolean isSafeToDelete = PsiUtil.isAccessedForWriting(referencedElement); boolean hasSideEffects = false; if (PsiUtil.isOnAssignmentLeftHand(referencedElement)) { hasSideEffects = RemoveUnusedVariableUtil.checkSideEffects( ((PsiAssignmentExpression) referencedElement.getParent()).getRExpression(), ((PsiLocalVariable) element), new ArrayList<>()); } usages.add( new SafeDeleteReferenceJavaDeleteUsageInfo( statement, element, isSafeToDelete && !hasSideEffects)); } } return new NonCodeUsageSearchInfo(insideDeletedCondition, element); }
private void addExprTypesWhenContainerElement(LinkedHashSet<PsiType> set, PsiExpression expr) { if (expr instanceof PsiMethodCallExpression) { PsiMethodCallExpression callExpr = (PsiMethodCallExpression) expr; PsiReferenceExpression methodExpr = callExpr.getMethodExpression(); String methodName = methodExpr.getReferenceName(); MethodPattern pattern = myMethodPatternMap.findPattern( methodName, callExpr.getArgumentList().getExpressions().length); if (pattern != null && pattern.parameterIndex < 0 /* return value */) { PsiExpression qualifier = methodExpr.getQualifierExpression(); if (qualifier != null) { PsiType[] types = guessContainerElementType(qualifier, null); for (PsiType type : types) { if (type instanceof PsiClassType) { if (((PsiClassType) type).resolve() instanceof PsiAnonymousClass) continue; } set.add(type); } } } } }
@Nullable private static PsiType getQualifierCastType( PsiJavaReference javaReference, CompletionParameters parameters) { if (javaReference instanceof PsiReferenceExpression) { final PsiReferenceExpression refExpr = (PsiReferenceExpression) javaReference; final PsiExpression qualifier = refExpr.getQualifierExpression(); if (qualifier != null) { final Project project = qualifier.getProject(); PsiType type = null; final PairFunction<PsiExpression, CompletionParameters, PsiType> evaluator = refExpr.getContainingFile().getCopyableUserData(DYNAMIC_TYPE_EVALUATOR); if (evaluator != null) { type = evaluator.fun(qualifier, parameters); } if (type == null) { type = GuessManager.getInstance(project).getControlFlowExpressionType(qualifier); } return type; } } return null; }
private static boolean containsOnlyPrivates(final PsiClass aClass) { final PsiField[] fields = aClass.getFields(); for (PsiField field : fields) { if (!field.hasModifierProperty(PsiModifier.PRIVATE)) return false; } final PsiMethod[] methods = aClass.getMethods(); for (PsiMethod method : methods) { if (!method.hasModifierProperty(PsiModifier.PRIVATE)) { if (method.isConstructor()) { // skip non-private constructors with call to super only final PsiCodeBlock body = method.getBody(); if (body != null) { final PsiStatement[] statements = body.getStatements(); if (statements.length == 0) continue; if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) { final PsiExpression expression = ((PsiExpressionStatement) statements[0]).getExpression(); if (expression instanceof PsiMethodCallExpression) { PsiReferenceExpression methodExpression = ((PsiMethodCallExpression) expression).getMethodExpression(); if (methodExpression.getText().equals(PsiKeyword.SUPER)) { continue; } } } } } return false; } } final PsiClass[] inners = aClass.getInnerClasses(); for (PsiClass inner : inners) { if (!inner.hasModifierProperty(PsiModifier.PRIVATE)) return false; } return true; }
public static boolean isValidQualifier4InterfaceStaticMethodCall( @NotNull PsiMethod method, @NotNull PsiReferenceExpression methodReferenceExpression, @Nullable PsiElement scope, @NotNull LanguageLevel languageLevel) { if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); final PsiClass containingClass = method.getContainingClass(); if (containingClass != null && containingClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) { return qualifierExpression == null && (scope instanceof PsiImportStaticStatement || PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true)) || qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression) qualifierExpression).resolve() == containingClass; } } return true; }
private static void reportConstantReferenceValues( ProblemsHolder holder, StandardInstructionVisitor visitor, Set<PsiElement> reportedAnchors) { for (Pair<PsiReferenceExpression, DfaConstValue> pair : visitor.getConstantReferenceValues()) { PsiReferenceExpression ref = pair.first; if (ref.getParent() instanceof PsiReferenceExpression || !reportedAnchors.add(ref)) { continue; } final Object value = pair.second.getValue(); PsiVariable constant = pair.second.getConstant(); final String presentableName = constant != null ? constant.getName() : String.valueOf(value); final String exprText = String.valueOf(value); if (presentableName == null || exprText == null) { continue; } holder.registerProblem( ref, "Value <code>#ref</code> #loc is always '" + presentableName + "'", new LocalQuickFix() { @NotNull @Override public String getName() { return "Replace with '" + presentableName + "'"; } @NotNull @Override public String getFamilyName() { return "Replace with constant value"; } @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { if (!FileModificationService.getInstance() .preparePsiElementsForWrite(descriptor.getPsiElement())) { return; } PsiElement problemElement = descriptor.getPsiElement(); if (problemElement == null) return; PsiMethodCallExpression call = problemElement.getParent() instanceof PsiExpressionList && problemElement.getParent().getParent() instanceof PsiMethodCallExpression ? (PsiMethodCallExpression) problemElement.getParent().getParent() : null; PsiMethod targetMethod = call == null ? null : call.resolveMethod(); JavaPsiFacade facade = JavaPsiFacade.getInstance(project); problemElement.replace( facade.getElementFactory().createExpressionFromText(exprText, null)); if (targetMethod != null) { ExtractMethodUtil.addCastsToEnsureResolveTarget(targetMethod, call); } } }); } }
private void correctMethodCall( final PsiMethodCallExpression expression, final boolean isInternalCall) { try { final PsiManager manager = myMethod.getManager(); PsiReferenceExpression methodExpression = expression.getMethodExpression(); if (!methodExpression.isReferenceTo(myMethod)) return; final PsiExpression oldQualifier = methodExpression.getQualifierExpression(); PsiExpression newQualifier = null; final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(methodExpression); if (myTargetVariable instanceof PsiParameter) { final int index = myMethod.getParameterList().getParameterIndex((PsiParameter) myTargetVariable); final PsiExpression[] arguments = expression.getArgumentList().getExpressions(); if (index < arguments.length) { newQualifier = (PsiExpression) arguments[index].copy(); arguments[index].delete(); } } else { VisibilityUtil.escalateVisibility((PsiField) myTargetVariable, expression); String newQualifierName = myTargetVariable.getName(); if (myTargetVariable instanceof PsiField && oldQualifier != null) { final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(oldQualifier.getType()); if (aClass == ((PsiField) myTargetVariable).getContainingClass()) { newQualifierName = oldQualifier.getText() + "." + newQualifierName; } } newQualifier = JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createExpressionFromText(newQualifierName, null); } PsiExpression newArgument = null; if (classReferencedByThis != null) { @NonNls String thisArgumentText = null; if (manager.areElementsEquivalent(myMethod.getContainingClass(), classReferencedByThis)) { if (myOldClassParameterNames.containsKey(myMethod.getContainingClass())) { thisArgumentText = "this"; } } else { thisArgumentText = classReferencedByThis.getName() + ".this"; } if (thisArgumentText != null) { newArgument = JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createExpressionFromText(thisArgumentText, null); } } else { if (!isInternalCall && oldQualifier != null) { final PsiType type = oldQualifier.getType(); if (type instanceof PsiClassType) { final PsiClass resolved = ((PsiClassType) type).resolve(); if (resolved != null && getParameterNameToCreate(resolved) != null) { newArgument = replaceRefsToTargetVariable( oldQualifier); // replace is needed in case old qualifier is e.g. the same as // field as target variable } } } } if (newArgument != null) { expression.getArgumentList().add(newArgument); } if (newQualifier != null) { if (newQualifier instanceof PsiThisExpression && ((PsiThisExpression) newQualifier).getQualifier() == null) { // Remove now redundant 'this' qualifier if (oldQualifier != null) oldQualifier.delete(); } else { final PsiReferenceExpression refExpr = (PsiReferenceExpression) JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createExpressionFromText("q." + myMethod.getName(), null); refExpr.getQualifierExpression().replace(newQualifier); methodExpression.replace(refExpr); } } } catch (IncorrectOperationException e) { LOG.error(e); } }
private static void findParameterUsages( final PsiParameter parameter, final List<UsageInfo> usages) { final PsiMethod method = (PsiMethod) parameter.getDeclarationScope(); final int parameterIndex = method.getParameterList().getParameterIndex(parameter); // search for refs to current method only, do not search for refs to overriding methods, they'll // be searched separately ReferencesSearch.search(method) .forEach( reference -> { PsiElement element = reference.getElement(); if (element != null) { final JavaSafeDeleteDelegate safeDeleteDelegate = JavaSafeDeleteDelegate.EP.forLanguage(element.getLanguage()); if (safeDeleteDelegate != null) { safeDeleteDelegate.createUsageInfoForParameter( reference, usages, parameter, method); } if (!parameter.isVarArgs() && !RefactoringChangeUtil.isSuperMethodCall(element.getParent())) { final PsiParameter paramInCaller = SafeDeleteJavaCallerChooser.isTheOnlyOneParameterUsage( element.getParent(), parameterIndex, method); if (paramInCaller != null) { final PsiMethod callerMethod = (PsiMethod) paramInCaller.getDeclarationScope(); if (ApplicationManager.getApplication().isUnitTestMode()) { usages.add( new SafeDeleteParameterCallHierarchyUsageInfo( callerMethod, paramInCaller, callerMethod)); } else { usages.add( new SafeDeleteParameterCallHierarchyUsageInfo( method, parameter, callerMethod)); } } } } return true; }); ReferencesSearch.search(parameter) .forEach( reference -> { PsiElement element = reference.getElement(); final PsiDocTag docTag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class); if (docTag != null) { usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(docTag, parameter, true)); return true; } boolean isSafeDelete = false; if (element.getParent().getParent() instanceof PsiMethodCallExpression) { PsiMethodCallExpression call = (PsiMethodCallExpression) element.getParent().getParent(); PsiReferenceExpression methodExpression = call.getMethodExpression(); if (methodExpression.getText().equals(PsiKeyword.SUPER)) { isSafeDelete = true; } else if (methodExpression.getQualifierExpression() instanceof PsiSuperExpression) { final PsiMethod superMethod = call.resolveMethod(); if (superMethod != null && MethodSignatureUtil.isSuperMethod(superMethod, method)) { isSafeDelete = true; } } } usages.add( new SafeDeleteReferenceJavaDeleteUsageInfo(element, parameter, isSafeDelete)); return true; }); findFunctionalExpressions(usages, method); }
@Nullable private PsiStatement hasCommonInitializer( PsiStatement commonInitializer, PsiMethod subConstructor, PsiField field, ArrayList<PsiElement> statementsToRemove) { final PsiCodeBlock body = subConstructor.getBody(); if (body == null) return null; final PsiStatement[] statements = body.getStatements(); // Algorithm: there should be only one write usage of field in a subConstructor, // and in that usage field must be a target of top-level assignment, and RHS of assignment // should be the same as commonInitializer if latter is non-null. // // There should be no usages before that initializer, and there should be // no write usages afterwards. PsiStatement commonInitializerCandidate = null; for (PsiStatement statement : statements) { final HashSet<PsiStatement> collectedStatements = new HashSet<PsiStatement>(); collectPsiStatements(statement, collectedStatements); boolean doLookup = true; for (PsiStatement collectedStatement : collectedStatements) { if (collectedStatement instanceof PsiExpressionStatement) { final PsiExpression expression = ((PsiExpressionStatement) collectedStatement).getExpression(); if (expression instanceof PsiAssignmentExpression) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) expression; final PsiExpression lExpression = assignmentExpression.getLExpression(); if (lExpression instanceof PsiReferenceExpression) { final PsiReferenceExpression lRef = (PsiReferenceExpression) lExpression; if (lRef.getQualifierExpression() == null || lRef.getQualifierExpression() instanceof PsiThisExpression) { final PsiElement resolved = lRef.resolve(); if (resolved == field) { doLookup = false; if (commonInitializerCandidate == null) { final PsiExpression initializer = assignmentExpression.getRExpression(); if (initializer == null) return null; if (commonInitializer == null) { final IsMovableInitializerVisitor visitor = new IsMovableInitializerVisitor(); statement.accept(visitor); if (visitor.isMovable()) { ChangeContextUtil.encodeContextInfo(statement, true); PsiStatement statementCopy = (PsiStatement) statement.copy(); ChangeContextUtil.clearContextInfo(statement); statementsToRemove.add(statement); commonInitializerCandidate = statementCopy; } else { return null; } } else { if (PsiEquivalenceUtil.areElementsEquivalent(commonInitializer, statement)) { statementsToRemove.add(statement); commonInitializerCandidate = commonInitializer; } else { return null; } } } else if (!PsiEquivalenceUtil.areElementsEquivalent( commonInitializerCandidate, statement)) { return null; } } } } } } } if (doLookup) { final PsiReference[] references = ReferencesSearch.search(field, new LocalSearchScope(statement), false) .toArray(new PsiReference[0]); if (commonInitializerCandidate == null && references.length > 0) { return null; } for (PsiReference reference : references) { if (RefactoringUtil.isAssignmentLHS(reference.getElement())) return null; } } } return commonInitializerCandidate; }
private NamesByExprInfo suggestVariableNameByExpressionOnly( PsiExpression expr, final VariableKind variableKind, boolean correctKeywords, boolean useAllMethodNames) { if (expr instanceof PsiMethodCallExpression) { PsiReferenceExpression methodExpr = ((PsiMethodCallExpression) expr).getMethodExpression(); String methodName = methodExpr.getReferenceName(); if (methodName != null) { if ("of".equals(methodName) || "ofNullable".equals(methodName)) { if (isJavaUtilMethodCall((PsiMethodCallExpression) expr)) { PsiExpression[] expressions = ((PsiMethodCallExpression) expr).getArgumentList().getExpressions(); if (expressions.length > 0) { return suggestVariableNameByExpressionOnly( expressions[0], variableKind, correctKeywords, useAllMethodNames); } } } if ("map".equals(methodName) || "flatMap".equals(methodName) || "filter".equals(methodName)) { if (isJavaUtilMethodCall((PsiMethodCallExpression) expr)) { return new NamesByExprInfo(null); } } String[] words = NameUtil.nameToWords(methodName); if (words.length > 0) { final String firstWord = words[0]; if (GET_PREFIX.equals(firstWord) || IS_PREFIX.equals(firstWord) || FIND_PREFIX.equals(firstWord) || CREATE_PREFIX.equals(firstWord)) { if (words.length > 1) { final String propertyName = methodName.substring(firstWord.length()); String[] names = getSuggestionsByName(propertyName, variableKind, false, correctKeywords); final PsiExpression qualifierExpression = methodExpr.getQualifierExpression(); if (qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression) qualifierExpression).resolve() instanceof PsiVariable) { names = ArrayUtil.append( names, StringUtil.sanitizeJavaIdentifier( changeIfNotIdentifier( qualifierExpression.getText() + StringUtil.capitalize(propertyName)))); } return new NamesByExprInfo(propertyName, names); } } else if (words.length == 1 || useAllMethodNames) { return new NamesByExprInfo( methodName, getSuggestionsByName(methodName, variableKind, false, correctKeywords)); } } } } else if (expr instanceof PsiReferenceExpression) { String propertyName = ((PsiReferenceExpression) expr).getReferenceName(); PsiElement refElement = ((PsiReferenceExpression) expr).resolve(); if (refElement instanceof PsiVariable) { VariableKind refVariableKind = getVariableKind((PsiVariable) refElement); propertyName = variableNameToPropertyName(propertyName, refVariableKind); } if (refElement != null && propertyName != null) { String[] names = getSuggestionsByName(propertyName, variableKind, false, correctKeywords); return new NamesByExprInfo(propertyName, names); } } else if (expr instanceof PsiArrayAccessExpression) { PsiExpression arrayExpr = ((PsiArrayAccessExpression) expr).getArrayExpression(); if (arrayExpr instanceof PsiReferenceExpression) { String arrayName = ((PsiReferenceExpression) arrayExpr).getReferenceName(); PsiElement refElement = ((PsiReferenceExpression) arrayExpr).resolve(); if (refElement instanceof PsiVariable) { VariableKind refVariableKind = getVariableKind((PsiVariable) refElement); arrayName = variableNameToPropertyName(arrayName, refVariableKind); } if (arrayName != null) { String name = StringUtil.unpluralize(arrayName); if (name != null) { String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords); return new NamesByExprInfo(name, names); } } } } else if (expr instanceof PsiLiteralExpression && variableKind == VariableKind.STATIC_FINAL_FIELD) { final PsiLiteralExpression literalExpression = (PsiLiteralExpression) expr; final Object value = literalExpression.getValue(); if (value instanceof String) { final String stringValue = (String) value; String[] names = getSuggestionsByValue(stringValue); if (names.length > 0) { return new NamesByExprInfo(null, constantValueToConstantName(names)); } } } else if (expr instanceof PsiParenthesizedExpression) { return suggestVariableNameByExpressionOnly( ((PsiParenthesizedExpression) expr).getExpression(), variableKind, correctKeywords, useAllMethodNames); } else if (expr instanceof PsiTypeCastExpression) { return suggestVariableNameByExpressionOnly( ((PsiTypeCastExpression) expr).getOperand(), variableKind, correctKeywords, useAllMethodNames); } else if (expr instanceof PsiLiteralExpression) { final String text = StringUtil.stripQuotesAroundValue(expr.getText()); if (isIdentifier(text)) { return new NamesByExprInfo( text, getSuggestionsByName(text, variableKind, false, correctKeywords)); } } return new NamesByExprInfo(null, ArrayUtil.EMPTY_STRING_ARRAY); }
private void findUsagesForField(PsiField field, List<FixableUsageInfo> usages) { final PsiManager psiManager = field.getManager(); final Project project = psiManager.getProject(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); final String qualifiedName = getQualifiedName(); @NonNls String getter = null; if (myGenerateAccessors) { getter = GenerateMembersUtil.suggestGetterName(field); } else { final PsiMethod fieldGetter = PropertyUtil.findPropertyGetter(sourceClass, field.getName(), false, false); if (fieldGetter != null && isInMovedElement(fieldGetter)) { getter = fieldGetter.getName(); } } @NonNls String setter = null; if (myGenerateAccessors) { setter = GenerateMembersUtil.suggestSetterName(field); } else { final PsiMethod fieldSetter = PropertyUtil.findPropertySetter(sourceClass, field.getName(), false, false); if (fieldSetter != null && isInMovedElement(fieldSetter)) { setter = fieldSetter.getName(); } } final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); for (PsiReference reference : ReferencesSearch.search(field, scope)) { final PsiElement element = reference.getElement(); if (isInMovedElement(element)) { continue; } if (element instanceof PsiReferenceExpression) { final PsiReferenceExpression exp = (PsiReferenceExpression) element; if (RefactoringUtil.isPlusPlusOrMinusMinus(exp.getParent())) { usages.add( isStatic ? new ReplaceStaticVariableIncrementDecrement(exp, qualifiedName) : new ReplaceInstanceVariableIncrementDecrement( exp, delegateFieldName, setter, getter, field.getName())); } else if (RefactoringUtil.isAssignmentLHS(exp)) { usages.add( isStatic ? new ReplaceStaticVariableAssignment(exp, qualifiedName) : new ReplaceInstanceVariableAssignment( PsiTreeUtil.getParentOfType(exp, PsiAssignmentExpression.class), delegateFieldName, setter, getter, field.getName())); } else { usages.add( isStatic ? new ReplaceStaticVariableAccess( exp, qualifiedName, enumConstants.contains(field)) : new ReplaceInstanceVariableAccess( exp, delegateFieldName, getter, field.getName())); } if (!isStatic) { delegationRequired = true; } } else if (element instanceof PsiDocTagValue) { usages.add(new BindJavadocReference(element, qualifiedName, field.getName())); } } }