boolean (PsiExpression expression) { expression = PsiUtil.skipParenthesizedExprDown(expression); if (expression == null) { return true; } if (PsiUtil.isConstantExpression(expression) || ExpressionUtils.isNullLiteral(expression)) { return true; } if (expression instanceof PsiArrayInitializerExpression arrayInitializerExpression) { for (PsiExpression initializer : arrayInitializerExpression.getInitializers()) { if (!isMovable(initializer)) { return false; } } return true; } if (expression instanceof PsiNewExpression newExpression) { final PsiExpression[] arrayDimensions = newExpression.getArrayDimensions(); if (arrayDimensions.length > 0) { for (PsiExpression arrayDimension : arrayDimensions) { if (!isMovable(arrayDimension)) { return false; } } return true; } final PsiArrayInitializerExpression arrayInitializer = newExpression.getArrayInitializer(); if (arrayInitializer != null) { final PsiExpression[] initializers = arrayInitializer.getInitializers(); for (final PsiExpression initializerExpression : initializers) { if (!isMovable(initializerExpression)) { return false; } } return true; } final PsiType type = newExpression.getType(); if (type == null) { return false; } else if (!m_allowConstructorAsInitializer) { if (!isAllowedType(type)) { return false; } } final PsiExpressionList argumentList = newExpression.getArgumentList(); if (argumentList == null) { return false; } final PsiExpression[] expressions = argumentList.getExpressions(); for (final PsiExpression argumentExpression : expressions) { if (!isMovable(argumentExpression)) { return false; } } return true; } if (expression instanceof PsiReferenceExpression referenceExpression) { final PsiExpression qualifier = referenceExpression.getQualifierExpression(); if (!isMovable(qualifier)) { return false; } final PsiElement target = referenceExpression.resolve(); if (target instanceof PsiClass) { return true; } if (!(target instanceof PsiVariable variable)) { return false; } if (!ClassUtils.isImmutable(variable.getType()) && !CollectionUtils.isEmptyArray(variable)) { return false; } if (variable.hasModifierProperty(PsiModifier.FINAL)) { return true; } final PsiElement context = PsiUtil.getVariableCodeBlock(variable, referenceExpression); return context != null && !(variable instanceof PsiField) && HighlightControlFlowUtil.isEffectivelyFinal(variable, context, referenceExpression); } if (expression instanceof PsiPolyadicExpression polyadicExpression) { for (PsiExpression operand : polyadicExpression.getOperands()) { if (!isMovable(operand)) { return false; } } return true; } if (expression instanceof PsiMethodCallExpression methodCallExpression) { if (!isAllowedType(expression.getType())) { return false; } final PsiMethod method = methodCallExpression.resolveMethod(); if (!isAllowedMethod(method)) { return false; } final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); if (qualifierExpression != null) { if (!isMovable(qualifierExpression)) { return false; } } else { if (method.getContainingFile() != expression.getContainingFile()) { return false; } final PsiClass aClass = method.getContainingClass(); if (aClass == null || !ClassUtils.isImmutableClass(aClass)) { return false; } } final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); for (PsiExpression argument : argumentList.getExpressions()) { if (!isMovable(argument)) { return false; } } return true; } return false; }