use of org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement in project intellij-community by JetBrains.
the class GroovyMethodInliner method isOnExpressionOrReturnPlace.
/*
Method call is used as expression in some enclosing expression or
is method return result
*/
private static boolean isOnExpressionOrReturnPlace(@NotNull GrCallExpression call) {
PsiElement parent = call.getParent();
if (!(parent instanceof GrVariableDeclarationOwner)) {
return true;
}
// tail calls in methods and closures
GrVariableDeclarationOwner owner = (GrVariableDeclarationOwner) parent;
if (owner instanceof GrClosableBlock || owner instanceof GrOpenBlock && owner.getParent() instanceof GrMethod) {
GrStatement[] statements = ((GrCodeBlock) owner).getStatements();
assert statements.length > 0;
GrStatement last = statements[statements.length - 1];
if (last == call)
return true;
if (last instanceof GrReturnStatement && call == ((GrReturnStatement) last).getReturnValue()) {
return true;
}
}
return false;
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement in project intellij-community by JetBrains.
the class GroovyInlineMethodUtil method isTailMethodCall.
/**
* Checks whether given method call is tail call of other method or closure
*
* @param call [tail?] Method call
* @return
*/
static boolean isTailMethodCall(GrCallExpression call) {
GrStatement stmt = call;
PsiElement parent = call.getParent();
// return statement
if (parent instanceof GrReturnStatement) {
stmt = ((GrReturnStatement) parent);
parent = parent.getParent();
}
// method body result
if (parent instanceof GrOpenBlock) {
if (parent.getParent() instanceof GrMethod) {
GrStatement[] statements = ((GrOpenBlock) parent).getStatements();
return statements.length > 0 && stmt == statements[statements.length - 1];
}
}
// closure result
if (parent instanceof GrClosableBlock) {
GrStatement[] statements = ((GrClosableBlock) parent).getStatements();
return statements.length > 0 && stmt == statements[statements.length - 1];
}
// todo test me!
if (stmt instanceof GrReturnStatement) {
GrMethod method = PsiTreeUtil.getParentOfType(stmt, GrMethod.class);
if (method != null) {
Collection<GrStatement> returnStatements = ControlFlowUtils.collectReturns(method.getBlock());
return returnStatements.contains(stmt) && !hasBadReturns(method);
}
}
return false;
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement in project intellij-community by JetBrains.
the class GroovyInlineMethodUtil method replaceAllOccurrencesWithExpression.
private static void replaceAllOccurrencesWithExpression(GrMethod method, GrCallExpression call, GrExpression oldExpression, GrParameter parameter) {
Collection<PsiReference> refs = ReferencesSearch.search(parameter, new LocalSearchScope(method), false).findAll();
final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(call.getProject());
GrExpression expression = elementFactory.createExpressionFromText(oldExpression.getText());
if (GroovyRefactoringUtil.hasSideEffect(expression) && refs.size() > 1 || !hasUnresolvableWriteAccess(refs, oldExpression)) {
final String oldName = parameter.getName();
final String newName = InlineMethodConflictSolver.suggestNewName(oldName, method, call);
expression = elementFactory.createExpressionFromText(newName);
final GrOpenBlock body = method.getBlock();
final GrStatement[] statements = body.getStatements();
GrStatement anchor = null;
if (statements.length > 0) {
anchor = statements[0];
}
body.addStatementBefore(elementFactory.createStatementFromText(createVariableDefinitionText(parameter, oldExpression, newName)), anchor);
}
for (PsiReference ref : refs) {
PsiElement element = ref.getElement();
if (element instanceof GrReferenceExpression) {
((GrReferenceExpression) element).replaceWithExpression(expression, true);
}
}
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement in project intellij-community by JetBrains.
the class GroovyInlineMethodUtil method checkTailOpenBlock.
private static boolean checkTailOpenBlock(GrOpenBlock block, Collection<GrStatement> returnStatements) {
if (block == null)
return false;
GrStatement[] statements = block.getStatements();
if (statements.length == 0)
return false;
GrStatement last = statements[statements.length - 1];
if (returnStatements.contains(last)) {
returnStatements.remove(last);
return true;
}
if (last instanceof GrIfStatement) {
return checkTailIfStatement(((GrIfStatement) last), returnStatements);
}
return false;
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement in project intellij-community by JetBrains.
the class GroovyInlineMethodUtil method checkTailIfStatement.
public static boolean checkTailIfStatement(GrIfStatement ifStatement, Collection<GrStatement> returnStatements) {
GrStatement thenBranch = ifStatement.getThenBranch();
GrStatement elseBranch = ifStatement.getElseBranch();
if (elseBranch == null)
return false;
boolean tb = false;
boolean eb = false;
if (thenBranch instanceof GrReturnStatement) {
tb = returnStatements.remove(thenBranch);
} else if (thenBranch instanceof GrBlockStatement) {
tb = checkTailOpenBlock(((GrBlockStatement) thenBranch).getBlock(), returnStatements);
}
if (elseBranch instanceof GrReturnStatement) {
eb = returnStatements.remove(elseBranch);
} else if (elseBranch instanceof GrBlockStatement) {
eb = checkTailOpenBlock(((GrBlockStatement) elseBranch).getBlock(), returnStatements);
}
return tb && eb;
}
Aggregations