use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project intellij-community by JetBrains.
the class GroovyTypeCheckVisitorHelper method getExpressionArgumentsOfCall.
@Nullable
public static List<GrExpression> getExpressionArgumentsOfCall(@NotNull GrArgumentList argumentList) {
final ArrayList<GrExpression> args = ContainerUtil.newArrayList();
for (GroovyPsiElement arg : argumentList.getAllArguments()) {
if (arg instanceof GrSpreadArgument) {
GrExpression spreaded = ((GrSpreadArgument) arg).getArgument();
if (spreaded instanceof GrListOrMap && !((GrListOrMap) spreaded).isMap()) {
Collections.addAll(args, ((GrListOrMap) spreaded).getInitializers());
} else {
return null;
}
} else if (arg instanceof GrExpression) {
args.add((GrExpression) arg);
} else if (arg instanceof GrNamedArgument) {
args.add(((GrNamedArgument) arg).getExpression());
}
}
final PsiElement parent = argumentList.getParent();
if (parent instanceof GrIndexProperty && PsiUtil.isLValue((GroovyPsiElement) parent)) {
args.add(TypeInferenceHelper.getInitializerFor((GrExpression) parent));
} else if (parent instanceof GrMethodCallExpression) {
ContainerUtil.addAll(args, ((GrMethodCallExpression) parent).getClosureArguments());
}
return args;
}
use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project intellij-community by JetBrains.
the class ControlFlowBuilder method addPendingEdge.
//add edge when instruction.getElement() is not contained in scopeWhenAdded
private void addPendingEdge(@Nullable GroovyPsiElement scopeWhenAdded, InstructionImpl instruction) {
if (instruction == null)
return;
int i = 0;
if (scopeWhenAdded != null) {
for (; i < myPending.size(); i++) {
Pair<InstructionImpl, GroovyPsiElement> pair = myPending.get(i);
final GroovyPsiElement currScope = pair.getSecond();
if (currScope == null)
continue;
if (!PsiTreeUtil.isAncestor(currScope, scopeWhenAdded, true))
break;
}
}
myPending.add(i, Pair.create(instruction, scopeWhenAdded));
}
use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project intellij-community by JetBrains.
the class ControlFlowBuilder method processForLoopInitializer.
private void processForLoopInitializer(@Nullable GrForClause clause) {
GroovyPsiElement initializer = clause instanceof GrTraditionalForClause ? ((GrTraditionalForClause) clause).getInitialization() : clause instanceof GrForInClause ? ((GrForInClause) clause).getIteratedExpression() : null;
acceptNullable(initializer);
}
use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project intellij-community by JetBrains.
the class ControlFlowBuilder method visitTryStatement.
@Override
public void visitTryStatement(@NotNull GrTryCatchStatement tryCatchStatement) {
final GrOpenBlock tryBlock = tryCatchStatement.getTryBlock();
final GrCatchClause[] catchClauses = tryCatchStatement.getCatchClauses();
final GrFinallyClause finallyClause = tryCatchStatement.getFinallyClause();
for (int i = catchClauses.length - 1; i >= 0; i--) {
myCaughtExceptionInfos.push(new ExceptionInfo(catchClauses[i]));
}
if (finallyClause != null)
myFinallyCount++;
List<Pair<InstructionImpl, GroovyPsiElement>> oldPending = null;
if (finallyClause != null) {
oldPending = myPending;
myPending = new ArrayList<>();
}
InstructionImpl tryBegin = startNode(tryBlock);
tryBlock.accept(this);
InstructionImpl tryEnd = myHead;
finishNode(tryBegin);
Set<Pair<InstructionImpl, GroovyPsiElement>> pendingAfterTry = new LinkedHashSet<>(myPending);
@SuppressWarnings("unchecked") List<InstructionImpl>[] throwers = new List[catchClauses.length];
for (int i = 0; i < catchClauses.length; i++) {
throwers[i] = myCaughtExceptionInfos.pop().myThrowers;
}
InstructionImpl[] catches = new InstructionImpl[catchClauses.length];
for (int i = 0; i < catchClauses.length; i++) {
interruptFlow();
final InstructionImpl catchBeg = startNode(catchClauses[i]);
for (InstructionImpl thrower : throwers[i]) {
addEdge(thrower, catchBeg);
}
final GrParameter parameter = catchClauses[i].getParameter();
if (parameter != null && myPolicy.isVariableInitialized(parameter)) {
addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, ReadWriteVariableInstruction.WRITE));
}
catchClauses[i].accept(this);
catches[i] = myHead;
finishNode(catchBeg);
}
pendingAfterTry.addAll(myPending);
myPending = new ArrayList<>(pendingAfterTry);
if (finallyClause != null) {
myFinallyCount--;
interruptFlow();
final InstructionImpl finallyInstruction = startNode(finallyClause, false);
Set<AfterCallInstruction> postCalls = new LinkedHashSet<>();
final List<Pair<InstructionImpl, GroovyPsiElement>> copy = myPending;
myPending = new ArrayList<>();
for (Pair<InstructionImpl, GroovyPsiElement> pair : copy) {
postCalls.add(addCallNode(finallyInstruction, pair.getSecond(), pair.getFirst()));
}
if (tryEnd != null) {
postCalls.add(addCallNode(finallyInstruction, tryCatchStatement, tryEnd));
}
for (InstructionImpl catchEnd : catches) {
if (catchEnd != null) {
postCalls.add(addCallNode(finallyInstruction, tryCatchStatement, catchEnd));
}
}
//save added postcalls into separate list because we don't want returnInstruction grabbed their pending edges
List<Pair<InstructionImpl, GroovyPsiElement>> pendingPostCalls = myPending;
myPending = new ArrayList<>();
myHead = finallyInstruction;
finallyClause.accept(this);
final ReturnInstruction returnInstruction = new ReturnInstruction(finallyClause);
for (AfterCallInstruction postCall : postCalls) {
postCall.setReturnInstruction(returnInstruction);
addEdge(returnInstruction, postCall);
}
addNodeAndCheckPending(returnInstruction);
interruptFlow();
finishNode(finallyInstruction);
if (oldPending == null) {
error();
}
oldPending.addAll(pendingPostCalls);
myPending = oldPending;
} else {
if (tryEnd != null) {
addPendingEdge(tryCatchStatement, tryEnd);
}
for (InstructionImpl catchEnd : catches) {
addPendingEdge(tryBlock, catchEnd);
}
}
}
use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project intellij-community by JetBrains.
the class GroovyExpectedTypesProvider method calculateTypeConstraints.
public static TypeConstraint[] calculateTypeConstraints(@NotNull final GrExpression expression) {
return TypeInferenceHelper.getCurrentContext().getCachedValue(expression, () -> {
MyCalculator calculator = new MyCalculator(expression);
final PsiElement parent = expression.getParent();
if (parent instanceof GroovyPsiElement) {
((GroovyPsiElement) parent).accept(calculator);
} else {
parent.accept(new GroovyPsiElementVisitor(calculator));
}
final TypeConstraint[] result = calculator.getResult();
List<TypeConstraint> custom = ContainerUtil.newArrayList();
for (GroovyExpectedTypesContributor contributor : GroovyExpectedTypesContributor.EP_NAME.getExtensions()) {
custom.addAll(contributor.calculateTypeConstraints(expression));
}
if (!custom.isEmpty()) {
custom.addAll(0, Arrays.asList(result));
return custom.toArray(new TypeConstraint[custom.size()]);
}
return result;
});
}
Aggregations