private string DeriveTypeFromCaseClauses(IParseTreeVisitorResults inspValues, VBAParser.SelectCaseStmtContext selectStmt) { var caseClauseTypeNames = new List <string>(); foreach (var caseClause in selectStmt.caseClause()) { foreach (var range in caseClause.rangeClause()) { if (TryDetectTypeHint(range.GetText(), out string hintTypeName)) { caseClauseTypeNames.Add(hintTypeName); } else { var typeNames = from context in range.children where context is ParserRuleContext && IsResultContext(context) select inspValues.GetValueType(context as ParserRuleContext); caseClauseTypeNames.AddRange(typeNames); caseClauseTypeNames.RemoveAll(tp => !InspectableTypes.Contains(tp)); } } } if (TryGetSelectExpressionTypeNameFromTypes(caseClauseTypeNames, out string evalTypeName)) { return(evalTypeName); } return(string.Empty); }
private void SetSelectExpressionTypeName(ParserRuleContext context, IParseTreeVisitorResults inspValues) { var selectStmt = (VBAParser.SelectCaseStmtContext)context; if (TryDetectTypeHint(selectStmt.selectExpression().GetText(), out string typeName) && InspectableTypes.Contains(typeName)) { SelectExpressionTypeName = typeName; } else if (inspValues.TryGetValue(selectStmt.selectExpression(), out IParseTreeValue result) && InspectableTypes.Contains(result.ValueType)) { _selectExpressionValue = result; SelectExpressionTypeName = result.ValueType; } else { SelectExpressionTypeName = DeriveTypeFromCaseClauses(inspValues, selectStmt); } }
public void InspectForUnreachableCases() { if (!InspectableTypes.Contains(SelectExpressionTypeName)) { return; } var remainingCasesToInspect = new List <VBAParser.CaseClauseContext>(); foreach (var caseClause in _caseClauses) { var containsMismatch = false; var containsOverflow = false; foreach (var range in caseClause.rangeClause()) { var childResults = ParseTreeValueResults.GetChildResults(range); var childValues = childResults.Select(ch => ParseTreeValueResults.GetValue(ch)); if (childValues.Any(chr => chr.IsMismatchExpression)) { containsMismatch = true; } if (childValues.Any(chr => chr.IsOverflowExpression)) { containsOverflow = true; } } if (containsMismatch) { MismatchTypeCases.Add(caseClause); } else if (containsOverflow) { OverflowCases.Add(caseClause); } else { remainingCasesToInspect.Add(caseClause); } } var rangeClauseFilter = BuildRangeClauseFilter(remainingCasesToInspect); if (!(_selectExpressionValue is null) && _selectExpressionValue.ParsesToConstantValue) { rangeClauseFilter.SelectExpressionValue = _selectExpressionValue; } foreach (var caseClause in remainingCasesToInspect) { var rangeClauseExpressions = (from range in caseClause.rangeClause() select GetRangeClauseExpression(range)).ToList(); rangeClauseExpressions.ForEach(expr => rangeClauseFilter.AddExpression(expr)); if (rangeClauseExpressions.Any(expr => expr.IsMismatch)) { MismatchTypeCases.Add(caseClause); } else if (rangeClauseExpressions.Any(expr => expr.IsOverflow)) { OverflowCases.Add(caseClause); } else if (rangeClauseExpressions.All(expr => expr.IsInherentlyUnreachable)) { InherentlyUnreachableCases.Add(caseClause); } else if (rangeClauseExpressions.All(expr => expr.IsUnreachable || expr.IsMismatch || expr.IsOverflow || expr.IsInherentlyUnreachable)) { UnreachableCases.Add(caseClause); } } if (_caseElseContext != null && rangeClauseFilter.FiltersAllValues) { UnreachableCaseElseCases.Add(_caseElseContext); } }