RangeMarker (@NotNull GrCallExpression call, @NotNull GrMethod method, boolean resultOfCallExplicitlyUsed, boolean isTailMethodCall, @Nullable Editor editor) { try { GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject()); final Project project = call.getProject(); // Variable declaration for qualifier expression GrVariableDeclaration qualifierDeclaration = null; GrReferenceExpression innerQualifier = null; GrExpression qualifier = null; if (call instanceof GrMethodCallExpression methodCall) { GrExpression invoked = methodCall.getInvokedExpression(); if (invoked instanceof GrReferenceExpression ref && ref.getQualifierExpression() != null) { qualifier = ref.getQualifierExpression(); if (PsiUtil.isSuperReference(qualifier)) { qualifier = null; } else if (!GroovyInlineMethodUtil.isSimpleReference(qualifier)) { String qualName = generateQualifierName(call, method, project, qualifier); qualifier = (GrExpression)PsiUtil.skipParentheses(qualifier, false); qualifierDeclaration = factory.createVariableDeclaration(ArrayUtilRt.EMPTY_STRING_ARRAY, qualifier, null, qualName); innerQualifier = (GrReferenceExpression)factory.createExpressionFromText(qualName); } else { innerQualifier = (GrReferenceExpression)qualifier; } } } GrMethod _method = prepareNewMethod(call, method, qualifier); GrExpression result = getAloneResultExpression(_method); if (result != null) { GrExpression expression = call.replaceWithExpression(result, false); TextRange range = expression.getTextRange(); return editor != null ? editor.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true) : null; } GrMethod newMethod = prepareNewMethod(call, method, innerQualifier); String resultName = InlineMethodConflictSolver.suggestNewName("result", newMethod, call); // Add variable for method result Collection<GrStatement> returnStatements = ControlFlowUtils.collectReturns(newMethod.getBlock()); final int returnCount = returnStatements.size(); PsiType methodType = method.getInferredReturnType(); GrOpenBlock body = newMethod.getBlock(); assert body != null; GrExpression replaced; if (resultOfCallExplicitlyUsed && !isTailMethodCall) { GrExpression resultExpr = null; if (PsiTypes.voidType().equals(methodType)) { resultExpr = factory.createExpressionFromText("null"); } else if (returnCount == 1) { final GrExpression returnExpression = ControlFlowUtils.extractReturnExpression(returnStatements.iterator().next()); if (returnExpression != null) { resultExpr = factory.createExpressionFromText(returnExpression.getText()); } } else if (returnCount > 1) { resultExpr = factory.createExpressionFromText(resultName); } if (resultExpr == null) { resultExpr = factory.createExpressionFromText("null"); } replaced = call.replaceWithExpression(resultExpr, false); } else { replaced = call; } // Calculate anchor to insert before GrExpression enclosingExpr = GroovyRefactoringUtil.addBlockIntoParent(replaced); GrVariableDeclarationOwner owner = PsiTreeUtil.getParentOfType(enclosingExpr, GrVariableDeclarationOwner.class); assert owner != null; PsiElement element = enclosingExpr; while (element != null && element.getParent() != owner) { element = element.getParent(); } assert element instanceof GrStatement; GrStatement anchor = (GrStatement) element; if (!resultOfCallExplicitlyUsed) { assert anchor == enclosingExpr; } // add qualifier reference declaration if (qualifierDeclaration != null) { owner.addVariableDeclarationBefore(qualifierDeclaration, anchor); } // Process method return statements if (returnCount > 1 && !PsiTypes.voidType().equals(methodType) && !isTailMethodCall) { PsiType type = methodType != null && methodType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) ? null : methodType; GrVariableDeclaration resultDecl = factory.createVariableDeclaration(ArrayUtilRt.EMPTY_STRING_ARRAY, "", type, resultName); GrStatement statement = ((GrStatementOwner) owner).addStatementBefore(resultDecl, anchor); JavaCodeStyleManager.getInstance(statement.getProject()).shortenClassReferences(statement); // Replace all return statements with assignments to 'result' variable for (GrStatement returnStatement : returnStatements) { GrExpression value = ControlFlowUtils.extractReturnExpression(returnStatement); if (value != null) { GrExpression assignment = factory.createExpressionFromText(resultName + " = " + value.getText()); returnStatement.replaceWithStatement(assignment); } else { returnStatement.replaceWithStatement(factory.createExpressionFromText(resultName + " = null")); } } } if (!isTailMethodCall && resultOfCallExplicitlyUsed && returnCount == 1) { returnStatements.iterator().next().removeStatement(); } else if (!isTailMethodCall && (PsiTypes.voidType().equals(methodType) || returnCount == 1)) { for (GrStatement returnStatement : returnStatements) { if (returnStatement instanceof GrReturnStatement) { final GrExpression returnValue = ((GrReturnStatement)returnStatement).getReturnValue(); if (returnValue != null && GroovyRefactoringUtil.hasSideEffect(returnValue)) { returnStatement.replaceWithStatement(returnValue); continue; } } else if (GroovyRefactoringUtil.hasSideEffect(returnStatement)) { continue; } returnStatement.removeStatement(); } } // Add all method statements GrStatement[] statements = body.getStatements(); for (GrStatement statement : statements) { ((GrStatementOwner) owner).addStatementBefore(statement, anchor); } if (resultOfCallExplicitlyUsed && !isTailMethodCall) { TextRange range = replaced.getTextRange(); RangeMarker marker = editor != null ? editor.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true) : null; reformatOwner(owner); return marker; } else { GrStatement stmt; if (isTailMethodCall && enclosingExpr.getParent() instanceof GrReturnStatement) { stmt = (GrReturnStatement) enclosingExpr.getParent(); } else { stmt = enclosingExpr; } stmt.removeStatement(); reformatOwner(owner); return null; } } catch (IncorrectOperationException e) { LOG.error(e); } return null; }