1 | import copy |
||
2 | |||
3 | from coalib.misc.Decorators import ( |
||
4 | enforce_signature, generate_ordering, generate_repr) |
||
5 | from coalib.results.TextPosition import TextPosition |
||
6 | |||
7 | |||
8 | @generate_repr("start", "end") |
||
9 | @generate_ordering("start", "end") |
||
10 | class TextRange: |
||
11 | |||
12 | @enforce_signature |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
![]() |
|||
13 | def __init__(self, start: TextPosition, end: (TextPosition, None)=None): |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
14 | """ |
||
15 | Creates a new TextRange. |
||
16 | |||
17 | :param start: A TextPosition indicating the start of the range. |
||
18 | Can't be ``None``. |
||
19 | :param end: A TextPosition indicating the end of the range. If |
||
20 | ``None`` is given, the start object will be used |
||
21 | here. |
||
22 | :raises TypeError: Raised when |
||
23 | - start is no TextPosition or None. |
||
24 | - end is no TextPosition. |
||
25 | :raises ValueError: Raised when end position is smaller than start |
||
26 | position, because negative ranges are not allowed. |
||
27 | """ |
||
28 | |||
29 | self._start = start |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
30 | self._end = end or copy.deepcopy(start) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
31 | |||
32 | if self._end < start: |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
33 | raise ValueError("End position can't be less than start position.") |
||
34 | |||
35 | @classmethod |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
36 | def from_values(cls, |
||
37 | start_line=None, |
||
38 | start_column=None, |
||
39 | end_line=None, |
||
40 | end_column=None): |
||
41 | """ |
||
42 | Creates a new TextRange. |
||
43 | |||
44 | :param start_line: The line number of the start position. The first |
||
45 | line is 1. |
||
46 | :param start_column: The column number of the start position. The first |
||
47 | column is 1. |
||
48 | :param end_line: The line number of the end position. If this |
||
49 | parameter is ``None``, then the end position is set |
||
50 | the same like start position and end_column gets |
||
51 | ignored. |
||
52 | :param end_column: The column number of the end position. |
||
53 | :return: A TextRange. |
||
54 | """ |
||
55 | start = TextPosition(start_line, start_column) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
56 | if end_line is None: |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
57 | end = None |
||
58 | else: |
||
59 | end = TextPosition(end_line, end_column) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
60 | |||
61 | return cls(start, end) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
62 | |||
63 | @classmethod |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
64 | def join(cls, a, b): |
||
65 | """ |
||
66 | Creates a new TextRange that covers the area of two overlapping ones |
||
67 | |||
68 | :param a: TextRange (needs to overlap b) |
||
69 | :param b: TextRange (needs to overlap a) |
||
70 | :return: A new TextRange covering the union of the Area of a and b |
||
71 | """ |
||
72 | if not isinstance(a, cls) or not isinstance(b, cls): |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
73 | raise TypeError( |
||
74 | "only instances of {} can be joined".format(cls.__name__)) |
||
75 | |||
76 | if not a.overlaps(b): |
||
77 | raise ValueError( |
||
78 | "{}s must overlap to be joined".format(cls.__name__)) |
||
79 | |||
80 | return cls(min(a.start, b.start), max(a.end, b.end)) |
||
81 | |||
82 | @property |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
83 | def start(self): |
||
84 | return self._start |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
85 | |||
86 | @property |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
87 | def end(self): |
||
88 | return self._end |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
89 | |||
90 | def overlaps(self, other): |
||
91 | return self.start <= other.end and self.end >= other.start |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
92 | |||
93 | def expand(self, text_lines): |
||
94 | """ |
||
95 | Passes a new TextRange that covers the same area of a file as this one |
||
96 | would. All values of None get replaced with absolute values. |
||
97 | |||
98 | values of None will be interpreted as follows: |
||
99 | self.start.line is None: -> 1 |
||
100 | self.start.column is None: -> 1 |
||
101 | self.end.line is None: -> last line of file |
||
102 | self.end.column is None: -> last column of self.end.line |
||
103 | |||
104 | :param text_lines: File contents of the applicable file |
||
105 | :return: TextRange with absolute values |
||
106 | """ |
||
107 | start_line = self.start.line or 1 |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
108 | start_column = self.start.column or 1 |
||
109 | end_line = self.end.line or len(text_lines) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
110 | end_column = self.end.column or len(text_lines[end_line - 1]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
111 | |||
112 | return TextRange.from_values(start_line, |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
113 | start_column, |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
114 | end_line, |
||
115 | end_column) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
116 |