public void visitClosure(GrClosableBlock closure) { // do not go inside closures except gstring injections if (closure.getParent() instanceof GrStringInjection) { for (GrParameter parameter : closure.getAllParameters()) { if (myPolicy.isVariableInitialized(parameter)) { addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE)); } } addNode(new ReadWriteVariableInstruction("owner", closure.getLBrace(), WRITE)); super.visitClosure(closure); return; } ReadWriteVariableInstruction[] reads = ControlFlowBuilderUtil.getReadsWithoutPriorWrites(closure.getControlFlow(), false); for (ReadWriteVariableInstruction read : reads) { PsiElement element = read.getElement(); if (!(element instanceof GrReferenceExpression) || myPolicy.isReferenceAccepted((GrReferenceExpression) element)) { addNodeAndCheckPending( new ReadWriteVariableInstruction(read.getVariableName(), closure, READ)); } } addNodeAndCheckPending(new InstructionImpl(closure)); }
public void visitReferenceExpression(GrReferenceExpression refExpr) { super.visitReferenceExpression(refExpr); if (myPolicy.isReferenceAccepted(refExpr)) { String name = refExpr.getReferenceName(); if (name == null) return; if (ControlFlowUtils.isIncOrDecOperand(refExpr)) { final InstructionImpl i = new ReadWriteVariableInstruction(name, refExpr, READ); addNodeAndCheckPending(i); addNode(new ReadWriteVariableInstruction(name, refExpr, WRITE)); } else { final int type = PsiUtil.isLValue(refExpr) ? WRITE : READ; addNodeAndCheckPending(new ReadWriteVariableInstruction(name, refExpr, type)); if (refExpr.getParent() instanceof GrArgumentList && refExpr.getParent().getParent() instanceof GrCall) { addNodeAndCheckPending(new ArgumentInstruction(refExpr)); } } } if (refExpr.isQualified() && !(refExpr.getParent() instanceof GrCall)) { visitCall(refExpr); } }
private void flushForeachLoopVariable(@Nullable GrForClause clause) { if (clause instanceof GrForInClause) { GrVariable variable = clause.getDeclaredVariable(); if (variable != null && myPolicy.isVariableInitialized(variable)) { addNodeAndCheckPending( new ReadWriteVariableInstruction(variable.getName(), variable, WRITE)); } } }
public void visitVariable(GrVariable variable) { super.visitVariable(variable); if (myPolicy.isVariableInitialized(variable)) { ReadWriteVariableInstruction writeInst = new ReadWriteVariableInstruction(variable.getName(), variable, WRITE); addNodeAndCheckPending(writeInst); } }
public void visitTypeDefinition(final GrTypeDefinition typeDefinition) { if (!(typeDefinition instanceof GrAnonymousClassDefinition)) return; final Set<ReadWriteVariableInstruction> vars = collectUsedVariableWithoutInitialization(typeDefinition); for (ReadWriteVariableInstruction var : vars) { PsiElement element = var.getElement(); if (!(element instanceof GrReferenceExpression) || myPolicy.isReferenceAccepted((GrReferenceExpression) element)) { addNodeAndCheckPending( new ReadWriteVariableInstruction(var.getVariableName(), typeDefinition, READ)); } } addNodeAndCheckPending(new InstructionImpl(typeDefinition)); }
public void visitAssignmentExpression(GrAssignmentExpression expression) { GrExpression lValue = expression.getLValue(); if (expression.getOperationTokenType() != mASSIGN) { if (lValue instanceof GrReferenceExpression && myPolicy.isReferenceAccepted((GrReferenceExpression) lValue)) { String referenceName = ((GrReferenceExpression) lValue).getReferenceName(); if (referenceName != null) { addNodeAndCheckPending(new ReadWriteVariableInstruction(referenceName, lValue, READ)); } } } GrExpression rValue = expression.getRValue(); if (rValue != null) { rValue.accept(this); lValue.accept(this); } }
public void visitOpenBlock(GrOpenBlock block) { final PsiElement parent = block.getParent(); final PsiElement lbrace = block.getLBrace(); if (lbrace != null && parent instanceof GrMethod) { for (GrParameter parameter : ((GrMethod) parent).getParameters()) { if (myPolicy.isVariableInitialized(parameter)) { addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE)); } } } super.visitOpenBlock(block); if (!(block.getParent() instanceof GrBlockStatement && block.getParent().getParent() instanceof GrLoopStatement)) { final GrStatement[] statements = block.getStatements(); if (statements.length > 0) { handlePossibleReturn(statements[statements.length - 1]); } } }
private void buildFlowForClosure(final GrClosableBlock closure) { for (GrParameter parameter : closure.getAllParameters()) { if (myPolicy.isVariableInitialized(parameter)) { addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE)); } } addNode(new ReadWriteVariableInstruction("owner", closure.getLBrace(), WRITE)); PsiElement child = closure.getFirstChild(); while (child != null) { if (child instanceof GroovyPsiElement) { ((GroovyPsiElement) child).accept(this); } child = child.getNextSibling(); } final GrStatement[] statements = closure.getStatements(); if (statements.length > 0) { handlePossibleReturn(statements[statements.length - 1]); } }
public void visitTryStatement(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<Pair<InstructionImpl, GroovyPsiElement>>(); } InstructionImpl tryBegin = startNode(tryBlock); tryBlock.accept(this); InstructionImpl tryEnd = myHead; finishNode(tryBegin); Set<Pair<InstructionImpl, GroovyPsiElement>> pendingAfterTry = new LinkedHashSet<Pair<InstructionImpl, GroovyPsiElement>>(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, WRITE)); } catchClauses[i].accept(this); catches[i] = myHead; finishNode(catchBeg); } pendingAfterTry.addAll(myPending); myPending = new ArrayList<Pair<InstructionImpl, GroovyPsiElement>>(pendingAfterTry); if (finallyClause != null) { myFinallyCount--; interruptFlow(); final InstructionImpl finallyInstruction = startNode(finallyClause, false); Set<AfterCallInstruction> postCalls = new LinkedHashSet<AfterCallInstruction>(); final List<Pair<InstructionImpl, GroovyPsiElement>> copy = myPending; myPending = new ArrayList<Pair<InstructionImpl, GroovyPsiElement>>(); 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<Pair<InstructionImpl, GroovyPsiElement>>(); 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); } } }