in DevSkim-DotNet/Microsoft.DevSkim/WithinOperation.cs [22:111]
public OperationResult WithinOperationDelegate(Clause c, object? state1, object? _, IEnumerable<ClauseCapture>? captures)
{
if (c is WithinClause wc && state1 is TextContainer tc)
{
var regexOpts = RegexOptions.Compiled;
if (wc.Arguments.Contains("i"))
{
regexOpts |= RegexOptions.IgnoreCase;
}
if (wc.Arguments.Contains("m"))
{
regexOpts |= RegexOptions.Multiline;
}
var passed = new List<Boundary>();
foreach (var captureHolder in captures ?? Array.Empty<ClauseCapture>())
{
if (captureHolder is TypedClauseCapture<List<Boundary>> tcc)
{
foreach (var capture in tcc.Result)
{
if (wc.FindingOnly)
{
passed.AddRange(ProcessLambda(tc.GetBoundaryText(capture), capture));
}
else if (wc.SameLineOnly)
{
var start = tc.LineStarts[tc.GetLocation(capture.Index).Line];
var end = tc.LineEnds[tc.GetLocation(start + capture.Length).Line];
passed.AddRange(ProcessLambda(tc.FullContent[start..end], capture));
}
else if (wc.SameFile)
{
var start = tc.LineStarts[0];
var end = tc.LineEnds[^1];
passed.AddRange(ProcessLambda(tc.FullContent[start..end], capture));
}
else if (wc.OnlyBefore)
{
var start = tc.LineStarts[0];
var end = capture.Index;
passed.AddRange(ProcessLambda(tc.FullContent[start..end], capture));
}
else if (wc.OnlyAfter)
{
var start = capture.Index + capture.Length;
var end = tc.LineEnds[^1];
passed.AddRange(ProcessLambda(tc.FullContent[start..end], capture));
}
else
{
var startLine = tc.GetLocation(capture.Index).Line;
// Before is already a negative number
var start = tc.LineEnds[Math.Max(0, startLine + wc.Before)];
var end = tc.LineEnds[Math.Min(tc.LineEnds.Count - 1, startLine + wc.After)];
passed.AddRange(ProcessLambda(tc.FullContent[start..end], capture));
}
}
}
}
return new OperationResult(passed.Any() ^ wc.Invert, passed.Any() ? new TypedClauseCapture<List<Boundary>>(wc, passed) : null);
IEnumerable<Boundary> ProcessLambda(string target, Boundary targetBoundary)
{
foreach (var pattern in wc.Data.Select(x => regexEngine.StringToRegex(x, regexOpts)))
{
if (pattern is Regex r)
{
var matches = r.Matches(target);
foreach (var match in matches)
{
if (match is Match m)
{
Boundary translatedBoundary = new Boundary()
{
Length = m.Length,
Index = targetBoundary.Index + m.Index
};
// Should return only scoped matches
if (tc.ScopeMatch(wc.Scopes, translatedBoundary))
{
yield return translatedBoundary;
}
}
}
}
}
}
}
return new OperationResult(false, null);
}