exprLinesFromPolicy returns a set of line numbers within a policy where expressions (variables, conditions, etc.) are defined.
(policy *Policy)
| 583 | // exprLinesFromPolicy returns a set of line numbers within a policy where expressions (variables, |
| 584 | // conditions, etc.) are defined. |
| 585 | func exprLinesFromPolicy(policy *Policy) map[int]bool { |
| 586 | lines := make(map[int]bool) |
| 587 | addExpectedLines := func(vs ValueString) { |
| 588 | if offset, found := policy.SourceInfo().GetOffsetRange(vs.ID); found { |
| 589 | startLoc, foundStart := policy.Source().OffsetLocation(offset.Start) |
| 590 | // Multiline strings can span multiple lines, but the SourceInfo will only contain the start |
| 591 | // position of the expression. So just skip the check if the expression contains a multiline |
| 592 | // string literal. |
| 593 | hasMultiline := strings.Contains(vs.Value, "'''") || strings.Contains(vs.Value, "\"\"\"") |
| 594 | if foundStart && !hasMultiline { |
| 595 | numLines := strings.Count(vs.Value, "\n") |
| 596 | for i := 0; i <= numLines; i++ { |
| 597 | lines[startLoc.Line()+i] = true |
| 598 | } |
| 599 | } |
| 600 | } |
| 601 | } |
| 602 | var traverseRule func(r *Rule) |
| 603 | traverseRule = func(r *Rule) { |
| 604 | for _, v := range r.Variables() { |
| 605 | addExpectedLines(v.Expression()) |
| 606 | } |
| 607 | for _, m := range r.Matches() { |
| 608 | addExpectedLines(m.Condition()) |
| 609 | if m.HasOutput() { |
| 610 | addExpectedLines(m.Output()) |
| 611 | } |
| 612 | if m.HasRule() { |
| 613 | traverseRule(m.Rule()) |
| 614 | } |
| 615 | } |
| 616 | } |
| 617 | traverseRule(policy.Rule()) |
| 618 | return lines |
| 619 | } |
no test coverage detected