private IEnumerable <SolutionStyleError> InspectIfStatement(IfStatementSyntax ifStatementSyntax) { var childNodes = ifStatementSyntax .ChildNodes() .ToList(); if (childNodes.Count <= 2) { yield break; } var correspondingElseClause = childNodes[2]; var statementUnderIf = childNodes[1]; switch (statementUnderIf) { case ReturnStatementSyntax _: case ThrowStatementSyntax _: var elseChildNodes = correspondingElseClause .ChildNodes() .ToList(); if (elseChildNodes.Count > 0 && elseChildNodes[0] is BlockSyntax) { yield return(new SolutionStyleError(StyleErrorType.RedundantElse01, correspondingElseClause)); } break; } }
private IfStatementSyntax SeparateIfConditions(IfStatementSyntax node) { if (node.Condition.IsKind(SK.InvocationExpression)) { return(node); } else { var conditionChilds = node.Condition.ChildNodes().ToArray(); if (conditionChilds.Length == 2) { IfStatementSyntax aStatement, bStatement; ExpressionSyntax aCondition, bCondition = null; BlockSyntax elseBlock = null; ElseClauseSyntax elseClause = null; aCondition = (ExpressionSyntax)conditionChilds[0]; bCondition = (ExpressionSyntax)conditionChilds[1]; var ifBlock = GetStatementAsBlock(node.ChildNodes().OfType <StatementSyntax>().First()); if (node.Else != null) { elseBlock = GetStatementAsBlock(node.Else.ChildNodes().OfType <StatementSyntax>().First()); elseClause = elseBlock != null?SF.ElseClause(elseBlock) : null; } switch (node.Condition.Kind()) { case SK.LogicalAndExpression: bStatement = SF.IfStatement(bCondition, ifBlock, elseClause); aStatement = SF.IfStatement(aCondition, SF.Block(bStatement), elseClause); node = aStatement; break; case SK.LogicalOrExpression: bStatement = SF.IfStatement(bCondition, ifBlock, elseClause); aStatement = SF.IfStatement(aCondition, ifBlock, SF.ElseClause(SF.Block(bStatement))); node = aStatement; break; default: return(SF.IfStatement(node.Condition, ifBlock, elseClause)); } } if (node.Condition.ChildNodes().ToArray().Length == 2) { return(SeparateIfConditions(node)); } return(node); } }
private SyntaxNode normalizeBlockedCode(SyntaxNode node) { IfStatementSyntax ifStatement = node as IfStatementSyntax; if (ifStatement != null) { return(ifStatement.ChildNodes().First()); } ForStatementSyntax forStatement = node as ForStatementSyntax; if (forStatement != null) { return(forStatement.ChildNodes().First()); } WhileStatementSyntax whileStatement = node as WhileStatementSyntax; if (whileStatement != null) { return(whileStatement.ChildNodes().First()); } return(node); }
public override SyntaxNode VisitIfStatement(IfStatementSyntax node) { var timer = new Stopwatch(); var successLogPath = ""; var failureLogPath = ""; BlockSyntax successChildBlock; BlockSyntax failureChildBlock; StatementSyntax successStatement = null; StatementSyntax failureStatement = null; // Separate multi-component conditions node = SeparateIfConditions(node); var condition = VisitExpression(node.Condition); // If - success path SuccessConditions.Add(condition); foreach (var c in SuccessConditions) { if (c.IsKind(SK.LogicalNotExpression)) { successLogPath += $"{c} && "; } else { successLogPath += $"({c}) && "; } } successLogPath = successLogPath.TrimEnd(' ', '&'); string[] successModel = null; var timeout = false; try { timer.Restart(); successModel = GetModel(Parameters, SuccessConditions); timer.Stop(); } catch (TimeoutException) { timeout = true; } // TODO: verify creation of a child block successChildBlock = SF.Block(GetStatementsFromBlock(node.ChildNodes().OfType <StatementSyntax>())); if (successModel != null) { // Check if end of path var ifTrueChild = GetStatementAsBlock(node.Statement).ChildNodes(); if (ifTrueChild.OfType <ReturnStatementSyntax>().ToArray().Length != 0 || ifTrueChild.OfType <ThrowStatementSyntax>().ToArray().Length != 0) { results.Add(successModel); logger?.Info($"SUCCESS PATH: {successLogPath} [{timer.Elapsed.ToString(timeFormat)}]"); } successStatement = (StatementSyntax)RewriterTrue.Visit(successChildBlock); } else { var status = "UNSATISFIABLE"; if (timeout) { status = "TIMEOUT"; } logger?.Trace($"{status}: {successLogPath} [{timer.Elapsed.ToString(timeFormat)}]"); // Do not visit unsatisfiable paths if (VisitUnsatPaths || (timeout && VisitTimeoutPaths)) { successStatement = (StatementSyntax)RewriterTrue.Visit(successChildBlock); } else { successStatement = successChildBlock; } } // Else - failure path var negatedCondition = SF.PrefixUnaryExpression(SK.LogicalNotExpression, SF.ParenthesizedExpression(condition)); FailureConditions.Add(negatedCondition); foreach (var c in FailureConditions) { if (c.IsKind(SK.LogicalNotExpression)) { failureLogPath += $"{c} && "; } else { failureLogPath += $"({c}) && "; } } failureLogPath = failureLogPath.TrimEnd(' ', '&'); string[] failureModel = null; timeout = false; try { timer.Restart(); failureModel = GetModel(Parameters, FailureConditions); timer.Stop(); } catch (TimeoutException) { timeout = true; } if (failureModel != null) { if (node.Else != null) { // Check if end of path var ifFalseChild = GetStatementAsBlock(node.Else.Statement).ChildNodes(); if (ifFalseChild.OfType <ReturnStatementSyntax>().ToArray().Length != 0 || ifFalseChild.OfType <ThrowStatementSyntax>().ToArray().Length != 0) { results.Add(failureModel); logger?.Info($"FAILURE PATH: {failureLogPath} [{timer.Elapsed.ToString(timeFormat)}]"); } failureChildBlock = SF.Block(GetStatementsFromBlock(node.Else.ChildNodes().OfType <StatementSyntax>())); failureStatement = (StatementSyntax)RewriterFalse.Visit(failureChildBlock); } else { // End of path and nothing to return } } else { var status = "UNSATISFIABLE"; if (timeout) { status = "TIMEOUT"; } logger?.Trace($"{status}: {failureLogPath} [{ timer.Elapsed.ToString(timeFormat)}]"); if (node.Else != null) { failureChildBlock = SF.Block(GetStatementsFromBlock(node.Else.ChildNodes().OfType <StatementSyntax>())); // Do not visit unsatisfiable paths if (VisitUnsatPaths || (timeout && VisitTimeoutPaths)) { failureStatement = (StatementSyntax)RewriterFalse.Visit(failureChildBlock); } else { failureStatement = failureChildBlock; } } else { // TODO: needs verification // End of path and nothing to return //return node; } } if (failureStatement != null) { return(SF.IfStatement(node.Condition, successStatement, SF.ElseClause(failureStatement))); } return(SF.IfStatement(node.Condition, successStatement)); }
internal SyntaxNode CheckIfStatementNotEmpty(IfStatementSyntax firstIfStatement) { if (reportedIssue) { return null; } var ifAppliedNode = firstIfStatement.ChildNodes().Where(node => node as BlockSyntax != null).FirstOrDefault(); if (ifAppliedNode == null) { ReportIssue( "empty if block"); } return ifAppliedNode; }
private Decisions TraverseIfStatements(IfStatementSyntax iss, ref int exitPoints, bool nested = false) { Decisions retDecision = new Decisions(); IfStatement ifStm = new IfStatement(); if (iss.HasLeadingTrivia) { SetOuterComments(ifStm, iss.GetLeadingTrivia().ToFullString()); } if (iss.HasTrailingTrivia) { SetInnerComments(ifStm, iss.GetTrailingTrivia().ToFullString()); } ifStm.IsNested = nested; //public int ExpressionListEndLn { get; set; } //public int ExpressionListStartLn { get; set; } //public bool IsNested { get; set; } ExpressionSyntax es = iss.Condition; var binaryExpressions = from aBinaryExpression in iss.Condition.DescendantNodesAndSelf().OfType<BinaryExpressionSyntax>() select aBinaryExpression; ifStm.ConditionCount = binaryExpressions.Count(); //This area is for the conditions i.e. the stuff in the () of if () foreach (BinaryExpressionSyntax bes in binaryExpressions) { Method tempMethod = TraverseBinaryExpression(bes); ifStm.AccessedVars.AddRange(tempMethod.AccessedVariables); ifStm.InvokedMethods.AddRange(tempMethod.InvokedMethods); } //TODO handle catches (if there are even catches inside if statements) var catches = from aCatch in iss.ChildNodes().OfType<CatchClauseSyntax>() select aCatch; foreach (CatchClauseSyntax ccs in catches) { Decisions tempCatch = TraverseCatchClauses(ccs, ref exitPoints, true); ifStm.Nested.AddRange(tempCatch.Catches); } //TODO need to handle else clauses var elses = from aElse in iss.ChildNodes().OfType<ElseClauseSyntax>() select aElse; foreach (ElseClauseSyntax ecs in elses) { //TODO //Traverse ElseClauseSyntax Decisions tempElse = TraverseElseClauses(ecs, ref exitPoints, true); ifStm.Nested.AddRange(tempElse.ElseStatements); #region old code with method return //ifStm.InvokedMethods.AddRange(tempElse.InvokedMethods); //ifStm.AccessedVars.AddRange(tempElse.AccessedVars); //ifStm.Nested.Add(tempElse); //foreach (BaseDecisions bd in ifStm.Nested) //{ // bd.IsNested = true; //} #endregion } //TODO need to find a way to return both nested //and invoked methods / accessedvars to the parent method var statements = from aStatement in iss.Statement.ChildNodes().OfType<StatementSyntax>() select aStatement; List<BaseDecisions> retBd = new List<BaseDecisions>(); List<InvokedMethod> retIm = new List<InvokedMethod>(); #region Nested and Invoked Methods and accessed vars foreach (StatementSyntax ss in statements) { //if (ss is BreakStatementSyntax) //{ //} //else if (ss is CheckedStatementSyntax) //{ //} //else if (ss is ContinueStatementSyntax) //{ //} if (ss is DoStatementSyntax) { Decisions dwl = TraverseDoStatements(ss as DoStatementSyntax, ref exitPoints, true); ifStm.Nested.AddRange(dwl.DoWhileLoops); //dwl.IsNested = true; //ifStm.Nested.Add(dwl); } //else if (ss is EmptyStatementSyntax) //{ //} else if (ss is ExpressionStatementSyntax) { Method tempMethod = TraverseExpressionStatementSyntax(ss as ExpressionStatementSyntax); ifStm.AccessedVars.AddRange(tempMethod.AccessedVariables); ifStm.InvokedMethods.AddRange(tempMethod.InvokedMethods); } //else if (ss is FixedStatementSyntax) //{ //} else if (ss is ForEachStatementSyntax) { Decisions fes = TraverseForEachStatements(ss as ForEachStatementSyntax, ref exitPoints, true); ifStm.Nested.AddRange(fes.ForEachStatements); //fes.IsNested = true; //ifStm.Nested.Add(fes); } else if (ss is ForStatementSyntax) { Decisions fs = TraverseForStatements(ss as ForStatementSyntax, ref exitPoints, true); ifStm.Nested.AddRange(fs.ForStatements); //fs.IsNested = true; //ifStm.Nested.Add(fs); } //else if (ss is GotoStatementSyntax) //{ //} else if (ss is IfStatementSyntax) { Decisions decision = TraverseIfStatements(ss as IfStatementSyntax, ref exitPoints, true); ifStm.Nested.AddRange(decision.IfStatements); } //else if (ss is LabeledStatementSyntax) //{ // BaseDecisions bd = new BaseDecisions(); // bd.IsNested = true; // bd.Nested.Add(TraverseLabelStatements(ss as LabeledStatementSyntax)); // retIf.Nested.Add(bd); //} else if (ss is LocalDeclarationStatementSyntax) { Model.Type tempType = new Model.Type(); LocalDeclarationStatementSyntax ldss = ss as LocalDeclarationStatementSyntax; if (ldss.Declaration != null) { VariableDeclarationSyntax vds = ldss.Declaration; tempType.Name = vds.Type.ToString(); tempType.IsKnownType = true; tempType.IsNotUserDefined = true; } Method tempMethod = TransverseAccessVars(ss as LocalDeclarationStatementSyntax); //NOT SURE if this will work but here goes tempMethod.AccessedVariables[0].Type = tempType; ifStm.AccessedVars.AddRange(tempMethod.AccessedVariables); ifStm.InvokedMethods.AddRange(tempMethod.InvokedMethods); } //else if (ss is LockStatementSyntax) //{ //} else if (ss is ReturnStatementSyntax) { exitPoints++; } else if (ss is SwitchStatementSyntax) { Decisions switchStm = TraverseSwitchStatements(ss as SwitchStatementSyntax, ref exitPoints, true); ifStm.Nested.AddRange(switchStm.SwitchStatements); //switchStm.IsNested = true; //ifStm.Nested.Add(switchStm); } //else if (ss is ThrowStatementSyntax) //{ //} //else if (ss is TryStatementSyntax) //{ //} //else if (ss is UnsafeStatementSyntax) //{ //} //else if (ss is UsingStatementSyntax) //{ // //using list? //} else if (ss is WhileStatementSyntax) { Decisions wl = TraverseWhileLoops(ss as WhileStatementSyntax, ref exitPoints, true); ifStm.Nested.AddRange(wl.WhileLoops); //wl.IsNested = true; //ifStm.Nested.Add(wl); } //else if (ss is YieldStatementSyntax) //{ //} } #endregion retDecision.IfStatements.Add(ifStm); return retDecision; }