use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock 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.blocks.GrClosableBlock in project intellij-community by JetBrains.
the class GrIntroduceHandlerBase method expressionIsIncorrect.
public static boolean expressionIsIncorrect(@Nullable GrExpression expression, boolean acceptVoidCalls) {
if (expression instanceof GrParenthesizedExpression)
return true;
if (PsiUtil.isSuperReference(expression))
return true;
if (expression instanceof GrAssignmentExpression)
return true;
if (expression instanceof GrReferenceExpression && expression.getParent() instanceof GrCall) {
final GroovyResolveResult resolveResult = ((GrReferenceExpression) expression).advancedResolve();
final PsiElement resolved = resolveResult.getElement();
return resolved instanceof PsiMethod && !resolveResult.isInvokedOnProperty() || resolved instanceof PsiClass;
}
if (expression instanceof GrReferenceExpression && expression.getParent() instanceof GrReferenceExpression) {
return !PsiUtil.isThisReference(expression) && ((GrReferenceExpression) expression).resolve() instanceof PsiClass;
}
if (expression instanceof GrClosableBlock && expression.getParent() instanceof GrStringInjection)
return true;
if (!acceptVoidCalls && expression instanceof GrMethodCall && PsiType.VOID.equals(expression.getType()))
return true;
return false;
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock 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.blocks.GrClosableBlock in project intellij-community by JetBrains.
the class AnonymousFromMapGenerator method writeAnonymousMap.
static void writeAnonymousMap(GrListOrMap operand, GrTypeElement typeElement, final StringBuilder builder, ExpressionContext context) {
final PsiType type = typeElement.getType();
final PsiClass psiClass;
final PsiSubstitutor substitutor;
if (type instanceof PsiClassType) {
final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType) type).resolveGenerics();
psiClass = resolveResult.getElement();
substitutor = resolveResult.getSubstitutor();
} else {
psiClass = null;
substitutor = PsiSubstitutor.EMPTY;
}
builder.append("new ");
TypeWriter.writeTypeForNew(builder, type, operand);
builder.append("() {\n");
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(operand.getProject());
final GrExpression caller = factory.createExpressionFromText("this");
for (GrNamedArgument arg : operand.getNamedArguments()) {
final String name = arg.getLabelName();
final GrExpression expression = arg.getExpression();
if (name == null || expression == null || !(expression instanceof GrClosableBlock))
continue;
final GrClosableBlock closure = (GrClosableBlock) expression;
final GrParameter[] allParameters = closure.getAllParameters();
List<GrParameter> actual = new ArrayList<>(Arrays.asList(allParameters));
final PsiType clReturnType = context.typeProvider.getReturnType(closure);
GrExpression[] args = new GrExpression[allParameters.length];
for (int i = 0; i < allParameters.length; i++) {
args[i] = factory.createExpressionFromText(allParameters[i].getName());
}
for (int param = allParameters.length; param >= 0; param--) {
if (param < allParameters.length && !actual.get(param).isOptional())
continue;
if (param < allParameters.length) {
final GrParameter opt = actual.remove(param);
args[param] = opt.getInitializerGroovy();
}
final GrParameter[] parameters = actual.toArray(new GrParameter[actual.size()]);
final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(parameters, clReturnType);
final GrMethod pattern = factory.createMethodFromSignature(name, signature);
PsiMethod found = null;
if (psiClass != null) {
found = psiClass.findMethodBySignature(pattern, true);
}
if (found != null) {
ModifierListGenerator.writeModifiers(builder, found.getModifierList(), ModifierListGenerator.JAVA_MODIFIERS_WITHOUT_ABSTRACT);
} else {
builder.append("public ");
}
PsiType returnType;
if (found != null) {
returnType = substitutor.substitute(context.typeProvider.getReturnType(found));
} else {
returnType = signature.getReturnType();
}
TypeWriter.writeType(builder, returnType, operand);
builder.append(' ').append(name);
GenerationUtil.writeParameterList(builder, parameters, new GeneratorClassNameProvider(), context);
final ExpressionContext extended = context.extend();
extended.setInAnonymousContext(true);
if (param == allParameters.length) {
new CodeBlockGenerator(builder, extended).generateCodeBlock(allParameters, closure, false);
} else {
builder.append("{\n");
final ExpressionGenerator expressionGenerator = new ExpressionGenerator(builder, extended);
GenerationUtil.invokeMethodByName(caller, name, args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, expressionGenerator, arg);
builder.append(";\n}\n");
}
}
}
builder.append("}");
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.
the class ExpressionGenerator method generateMethodCall.
private void generateMethodCall(GrMethodCall methodCallExpression) {
final GrExpression invoked = methodCallExpression.getInvokedExpression();
final GrExpression[] exprs = methodCallExpression.getExpressionArguments();
final GrNamedArgument[] namedArgs = methodCallExpression.getNamedArguments();
final GrClosableBlock[] clArgs = methodCallExpression.getClosureArguments();
if (invoked instanceof GrReferenceExpression) {
final GroovyResolveResult resolveResult = ((GrReferenceExpression) invoked).advancedResolve();
final PsiElement resolved = resolveResult.getElement();
if (resolved instanceof PsiMethod) {
//todo replace null-qualifier with this-reference
final GrExpression qualifier = ((GrReferenceExpression) invoked).getQualifier();
invokeMethodOn(((PsiMethod) resolved), qualifier, exprs, namedArgs, clArgs, resolveResult.getSubstitutor(), methodCallExpression);
return;
} else if (resolved == null) {
final GrExpression qualifier = ((GrReferenceExpression) invoked).getQualifier();
final GrExpression[] args = generateArgsForInvokeMethod(((GrReferenceExpression) invoked).getReferenceName(), exprs, namedArgs, clArgs, methodCallExpression);
GenerationUtil.invokeMethodByName(qualifier, "invokeMethod", args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, this, methodCallExpression);
return;
}
}
GenerationUtil.invokeMethodByName(invoked, "call", exprs, namedArgs, clArgs, this, methodCallExpression);
}
Aggregations