// This is kinda duplicated in CodeBlockAnalyzer.GetAssignmentStatus private void CheckExpressionForNull(ISymbol symbol, ExpressionSyntax expression, MethodFlowAnalysis analysis = null) { var expressionValueType = expression.GetTypeOfValue(context.SemanticModel); if (expressionValueType == ValueType.NotNull) { // Argument cannot be null, so move to the next return; } if (expressionValueType == ValueType.Null) { context.ReportDiagnostic(MainAnalyzer.CreateReturnNull(expression.GetLocation(), symbol.ToString())); return; } if (analysis == null) { context.ReportDiagnostic(MainAnalyzer.CreateReturnNull(expression.GetLocation(), symbol.ToString())); return; } ExpressionStatus status = analysis.IsAlwaysAssigned(expression, expression); if (!status.IsAssigned()) { context.ReportDiagnostic(MainAnalyzer.CreateReturnNull(expression.GetLocation(), symbol.ToString())); } if (status == ExpressionStatus.AssignedWithUnneededConstraint) { context.ReportDiagnostic(MainAnalyzer.CreateUnneededConstraint(expression.GetLocation(), symbol.ToString())); } }
private void ReportIssue(ExpressionStatus status, Location location, string errorContext) { switch (status) { case ExpressionStatus.NotAssigned: context.ReportDiagnostic(MainAnalyzer.CreateNullAssignmentError(location, errorContext)); break; case ExpressionStatus.ReassignedAfterCondition: context.ReportDiagnostic(MainAnalyzer.CreateAssignmentAfterCondition(location, errorContext)); break; case ExpressionStatus.AssignedWithUnneededConstraint: context.ReportDiagnostic(MainAnalyzer.CreateUnneededConstraint(location, errorContext)); break; } }
public static bool IsAssigned(this ExpressionStatus status) { return(status == ExpressionStatus.Assigned || status == ExpressionStatus.AssignedWithUnneededConstraint); }
/// <summary>Set the last token and check for expression consistency using the saved status.</summary> /// <param name="token">An generic object used to get info about the token.</param> /// <param name="op">the operator value to pushed.</param> private bool setLast(object token, Operator op) { if (op == Operator.Operand || op == Operator.Parenthese) { if (this.status_ != ExpressionStatus.Start && this.status_ != ExpressionStatus.BinaryOperator && this.status_ != ExpressionStatus.UnaryOperatorLeftRight) return error("Unexpected operand"); this.status_ = op == Operator.Operand ? ExpressionStatus.Operand : ExpressionStatus.Start; } else if (op < Operator.__Binary) { if (this.status_ == ExpressionStatus.Operand) return error("Unexpected prefix operator"); this.status_ = ExpressionStatus.UnaryOperatorLeftRight; } else { if (this.status_ != ExpressionStatus.Operand) return error("Unexpected operator"); this.status_ = ExpressionStatus.BinaryOperator; } this.last_ = token; return true; }
/// <summary>Set the expression in error and keep track of an error message.</summary> /// <param name="msg">An error message.</param> /// <returns>Always return false to be return by the calling function.</returns> private bool error(string msg) { if (this.status_ == ExpressionStatus.Error) return false; this.status_ = ExpressionStatus.Error; if (last_ != null) this.errMsg_ = msg + " after " + last_.ToString() + "."; else this.errMsg_ = msg + " to begin."; return false; }
public void Reset() { postFixStack_ = new Stack<Operand>(); inFixStack_ = new Stack<Operand>(); errMsg_ = null; status_ = ExpressionStatus.Start; last_ = null; }
public bool CloseParenthese(object token) { if (this.status_ != ExpressionStatus.Operand) return error("unexpected parenthese"); this.last_ = token; this.status_ = ExpressionStatus.Operand; Operand node = inFixStack_.Pop(); while (node.Operator != Operator.Parenthese) { addPostFixOperator(node); if (inFixStack_.Count == 0) return error("closing parenthese without openning"); node = inFixStack_.Pop(); } return true; }