public OperationResult WithinOperationDelegate()

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);
        }