PsiElementVisitor (@NotNull ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { @Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) { if (!STRING_REPLACE.test(call)) return; PsiLiteralExpression qualifier = tryCast( PsiUtil.skipParenthesizedExprDown(call.getMethodExpression().getQualifierExpression()), PsiLiteralExpression.class); if (qualifier == null || qualifier.getTextLength() > MAX_QUALIFIER_LENGTH) return; String str = tryCast(qualifier.getValue(), String.class); if (str == null) return; PsiExpression pattern = PsiUtil.skipParenthesizedExprDown(call.getArgumentList().getExpressions()[0]); String name = call.getMethodExpression().getReferenceName(); if (!isRedundant(str, pattern, "replace".equals(name))) return; PsiElement refName = Objects.requireNonNull(call.getMethodExpression().getReferenceNameElement()); holder.registerProblem(call, InspectionGadgetsBundle.message("inspection.replace.on.literal.display.name"), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, TextRange.create(refName.getTextRangeInParent().getStartOffset(), call.getTextLength()), ExpressionUtils.isVoidContext(call) ? LocalQuickFix.EMPTY_ARRAY : new LocalQuickFix[]{new ReplaceOnLiteralWithQualifierFix()}); } private boolean isRedundant(@NotNull String str, PsiExpression pattern, boolean literalMatch) { Object constValue = ExpressionUtils.computeConstantExpression(pattern); if (constValue != null) { return isRedundantLiteralMatch(str, constValue, literalMatch); } if (literalMatch && pattern instanceof PsiPolyadicExpression && ((PsiPolyadicExpression)pattern).getOperationTokenType().equals(JavaTokenType.PLUS)) { PsiExpression[] operands = ((PsiPolyadicExpression)pattern).getOperands(); boolean stringType = false; for (int i = 0; i < operands.length; i++) { PsiExpression operand = operands[i]; stringType = stringType || TypeUtils.isJavaLangString(operand.getType()); if (!stringType && (i > 0 || !TypeUtils.isJavaLangString(operands[1].getType()))) continue; constValue = ExpressionUtils.computeConstantExpression(operand); if (constValue == null) continue; if (isRedundantLiteralMatch(str, constValue, true)) return true; } } return false; } private static boolean isRedundantLiteralMatch(@NotNull String str, Object value, boolean literalMatch) { String patternValue; if (value instanceof String) { patternValue = (String)value; } else if (value instanceof Character) { patternValue = value.toString(); } else { return false; } if (literalMatch) return !str.contains(patternValue); if (patternValue.length() > MAX_PATTERN_LENGTH) return false; Pattern regex; try { regex = Pattern.compile(patternValue); } catch (PatternSyntaxException e) { return false; } return !regex.matcher(str).find(); } }; }