CountingLoop (PsiForStatement forStatement) { // check that initialization is for(int/long i = <initial_value>;...;...) PsiDeclarationStatement initialization = tryCast(forStatement.getInitialization(), PsiDeclarationStatement.class); if (initialization == null) return null; PsiElement[] declaredElements = initialization.getDeclaredElements(); if (declaredElements.length != 1) return null; PsiLocalVariable counter = tryCast(declaredElements[0], PsiLocalVariable.class); if(counter == null) return null; PsiType counterType = counter.getType(); if(!counterType.equals(PsiTypes.intType()) && !counterType.equals(PsiTypes.longType())) return null; PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(counter.getInitializer()); if(initializer == null) return null; // check that increment is like for(...;...;i++) LoopDirection loopDirection = LoopDirection.evaluateLoopDirection(counter, forStatement.getUpdate()); if (loopDirection == null) return null; // check that condition is like for(...;i<bound;...) or for(...;i<=bound;...) PsiBinaryExpression condition = tryCast(PsiUtil.skipParenthesizedExprDown(forStatement.getCondition()), PsiBinaryExpression.class); if(condition == null) return null; IElementType type = condition.getOperationTokenType(); boolean closed = false; RelationType relationType = DfaPsiUtil.getRelationByToken(type); if (relationType == null || !relationType.isInequality()) return null; if (relationType.isSubRelation(RelationType.EQ)) { closed = true; } if (loopDirection == LoopDirection.DESCENDING) { relationType = relationType.getFlipped(); assert relationType != null; } PsiExpression bound = ExpressionUtils.getOtherOperand(condition, counter); if (bound == null) return null; if (bound == condition.getLOperand()) { relationType = relationType.getFlipped(); assert relationType != null; } if (!relationType.isSubRelation(RelationType.LT)) return null; if(!TypeConversionUtil.areTypesAssignmentCompatible(counterType, bound)) return null; if(VariableAccessUtils.variableIsAssigned(counter, forStatement.getBody())) return null; return new CountingLoop(forStatement, counter, initializer, bound, closed, loopDirection, relationType == RelationType.NE); }