Coverage for sources / vibelinter / rules / context.py: 62%
22 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-04 00:00 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-04 00:00 +0000
1# vim: set filetype=python fileencoding=utf-8:
2# -*- coding: utf-8 -*-
4#============================================================================#
5# #
6# Licensed under the Apache License, Version 2.0 (the "License"); #
7# you may not use this file except in compliance with the License. #
8# You may obtain a copy of the License at #
9# #
10# http://www.apache.org/licenses/LICENSE-2.0 #
11# #
12# Unless required by applicable law or agreed to in writing, software #
13# distributed under the License is distributed on an "AS IS" BASIS, #
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15# See the License for the specific language governing permissions and #
16# limitations under the License. #
17# #
18#============================================================================#
21''' Context extraction utilities for enhanced violation reporting. '''
24from . import __
25from . import violations as _violations
28class ContextExtractor:
29 ''' Extracts source code context around violations. '''
31 def __init__(
32 self,
33 source_lines: __.typx.Annotated[
34 tuple[ str, ... ],
35 __.ddoc.Doc( 'Source file lines for context extraction.' ) ]
36 ) -> None:
37 self.source_lines = source_lines
39 def extract_violation_context(
40 self,
41 violation: __.typx.Annotated[
42 _violations.Violation,
43 __.ddoc.Doc( 'Violation to extract context for.' ) ],
44 context_size: __.typx.Annotated[
45 int,
46 __.ddoc.Doc(
47 'Number of lines to show before and after violation.'
48 ) ] = 2,
49 ) -> __.typx.Annotated[
50 _violations.ViolationContext,
51 __.ddoc.Doc( 'Violation with surrounding source context.' ) ]:
52 ''' Extracts source code context around a violation. '''
53 line = violation.line
54 start_line = max( 1, line - context_size )
55 end_line = min( len( self.source_lines ), line + context_size )
56 # Extract context lines (convert to 0-indexed for array access)
57 context_lines = tuple(
58 self.source_lines[ i ]
59 for i in range( start_line - 1, end_line )
60 )
61 return _violations.ViolationContext(
62 violation = violation,
63 context_lines = context_lines,
64 context_start_line = start_line,
65 )
67 def format_context_display(
68 self,
69 context: __.typx.Annotated[
70 _violations.ViolationContext,
71 __.ddoc.Doc( 'Violation context to format for display.' ) ],
72 highlight_line: __.typx.Annotated[
73 bool,
74 __.ddoc.Doc( 'Whether to highlight the violation line.' ) ] = (
75 True ),
76 ) -> __.typx.Annotated[
77 tuple[ str, ... ],
78 __.ddoc.Doc(
79 'Formatted context lines with line numbers and highlighting.'
80 ) ]:
81 ''' Formats violation context for display. '''
82 formatted_lines: list[ str ] = [ ]
83 violation_line = context.violation.line
84 for i, line in enumerate( context.context_lines ):
85 line_number = context.context_start_line + i
86 prefix = (
87 '→ ' if highlight_line and line_number == violation_line
88 else ' ' )
89 formatted_lines.append( f'{line_number:4d}{prefix}{line}' )
90 return tuple( formatted_lines )
93def extract_contexts_for_violations(
94 violations: __.typx.Annotated[
95 _violations.ViolationSequence,
96 __.ddoc.Doc( 'Sequence of violations to extract contexts for.' ) ],
97 source_lines: __.typx.Annotated[
98 __.cabc.Sequence[ str ],
99 __.ddoc.Doc( 'Source file lines for context extraction.' ) ],
100 context_size: __.typx.Annotated[
101 int,
102 __.ddoc.Doc(
103 'Number of lines to show before and after each violation.'
104 ) ] = 2,
105) -> tuple[ _violations.ViolationContext, ... ]:
106 ''' Extracts contexts for multiple violations efficiently. '''
107 extractor = ContextExtractor( tuple( source_lines ) )
108 return tuple(
109 extractor.extract_violation_context( violation, context_size )
110 for violation in violations
111 )