From 1e5c28f36b0fd2d5ac1683c88d48e3d7c243e993 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 22:18:22 +0200 Subject: Adding upstream version 0.1.28. Signed-off-by: Daniel Baumann --- .../d_7764373ba25ba45b_lint_util_py.html | 318 +++++++++++++++++++++ 1 file changed, 318 insertions(+) create mode 100644 coverage-report/d_7764373ba25ba45b_lint_util_py.html (limited to 'coverage-report/d_7764373ba25ba45b_lint_util_py.html') diff --git a/coverage-report/d_7764373ba25ba45b_lint_util_py.html b/coverage-report/d_7764373ba25ba45b_lint_util_py.html new file mode 100644 index 0000000..7bcc47e --- /dev/null +++ b/coverage-report/d_7764373ba25ba45b_lint_util_py.html @@ -0,0 +1,318 @@ + + + + + Coverage for src/debputy/linting/lint_util.py: 42% + + + + + +
+
+

+ Coverage for src/debputy/linting/lint_util.py: + 42% +

+ +

+ 117 statements   + + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.2.7, + created at 2024-04-07 12:14 +0200 +

+ +
+
+
+

1import dataclasses 

+

2import os 

+

3from typing import List, Optional, Callable, Counter, TYPE_CHECKING 

+

4 

+

5from lsprotocol.types import Position, Range, Diagnostic, DiagnosticSeverity 

+

6 

+

7from debputy.commands.debputy_cmd.output import OutputStylingBase 

+

8from debputy.plugin.api.feature_set import PluginProvidedFeatureSet 

+

9from debputy.util import _DEFAULT_LOGGER, _warn 

+

10 

+

11if TYPE_CHECKING: 

+

12 from debputy.lsp.text_util import LintCapablePositionCodec 

+

13 

+

14 

+

15LinterImpl = Callable[["LintState"], Optional[List[Diagnostic]]] 

+

16 

+

17 

+

18class LintState: 

+

19 

+

20 @property 

+

21 def plugin_feature_set(self) -> PluginProvidedFeatureSet: 

+

22 raise NotImplementedError 

+

23 

+

24 @property 

+

25 def doc_uri(self) -> str: 

+

26 raise NotImplementedError 

+

27 

+

28 @property 

+

29 def path(self) -> str: 

+

30 raise NotImplementedError 

+

31 

+

32 @property 

+

33 def lines(self) -> List[str]: 

+

34 raise NotImplementedError 

+

35 

+

36 @property 

+

37 def position_codec(self) -> "LintCapablePositionCodec": 

+

38 raise NotImplementedError 

+

39 

+

40 

+

41@dataclasses.dataclass(slots=True) 

+

42class LintStateImpl(LintState): 

+

43 plugin_feature_set: PluginProvidedFeatureSet 

+

44 path: str 

+

45 lines: List[str] 

+

46 

+

47 @property 

+

48 def doc_uri(self) -> str: 

+

49 path = self.path 

+

50 abs_path = os.path.join(os.path.curdir, path) 

+

51 return f"file://{abs_path}" 

+

52 

+

53 @property 

+

54 def position_codec(self) -> "LintCapablePositionCodec": 

+

55 return LINTER_POSITION_CODEC 

+

56 

+

57 

+

58@dataclasses.dataclass(slots=True) 

+

59class LintReport: 

+

60 diagnostics_count: Counter[DiagnosticSeverity] = dataclasses.field( 

+

61 default_factory=Counter 

+

62 ) 

+

63 diagnostics_without_severity: int = 0 

+

64 diagnostic_errors: int = 0 

+

65 fixed: int = 0 

+

66 fixable: int = 0 

+

67 

+

68 

+

69class LinterPositionCodec: 

+

70 

+

71 def client_num_units(self, chars: str): 

+

72 return len(chars) 

+

73 

+

74 def position_from_client_units( 

+

75 self, lines: List[str], position: Position 

+

76 ) -> Position: 

+

77 

+

78 if len(lines) == 0: 

+

79 return Position(0, 0) 

+

80 if position.line >= len(lines): 

+

81 return Position(len(lines) - 1, self.client_num_units(lines[-1])) 

+

82 return position 

+

83 

+

84 def position_to_client_units( 

+

85 self, _lines: List[str], position: Position 

+

86 ) -> Position: 

+

87 return position 

+

88 

+

89 def range_from_client_units(self, _lines: List[str], range: Range) -> Range: 

+

90 return range 

+

91 

+

92 def range_to_client_units(self, _lines: List[str], range: Range) -> Range: 

+

93 return range 

+

94 

+

95 

+

96LINTER_POSITION_CODEC = LinterPositionCodec() 

+

97 

+

98 

+

99_SEVERITY2TAG = { 99 ↛ exitline 99 didn't jump to the function exit

+

100 DiagnosticSeverity.Error: lambda fo: fo.colored( 

+

101 "error", 

+

102 fg="red", 

+

103 bg="black", 

+

104 style="bold", 

+

105 ), 

+

106 DiagnosticSeverity.Warning: lambda fo: fo.colored( 

+

107 "warning", 

+

108 fg="yellow", 

+

109 bg="black", 

+

110 style="bold", 

+

111 ), 

+

112 DiagnosticSeverity.Information: lambda fo: fo.colored( 

+

113 "informational", 

+

114 fg="blue", 

+

115 bg="black", 

+

116 style="bold", 

+

117 ), 

+

118 DiagnosticSeverity.Hint: lambda fo: fo.colored( 

+

119 "pedantic", 

+

120 fg="green", 

+

121 bg="black", 

+

122 style="bold", 

+

123 ), 

+

124} 

+

125 

+

126 

+

127def _lines_to_print(range_: Range) -> int: 

+

128 count = range_.end.line - range_.start.line 

+

129 if range_.end.character > 0: 

+

130 count += 1 

+

131 return count 

+

132 

+

133 

+

134def _highlight_range( 

+

135 fo: OutputStylingBase, line: str, line_no: int, range_: Range 

+

136) -> str: 

+

137 line_wo_nl = line.rstrip("\r\n") 

+

138 start_pos = 0 

+

139 prefix = "" 

+

140 suffix = "" 

+

141 if line_no == range_.start.line: 

+

142 start_pos = range_.start.character 

+

143 prefix = line_wo_nl[0:start_pos] 

+

144 if line_no == range_.end.line: 

+

145 end_pos = range_.end.character 

+

146 suffix = line_wo_nl[end_pos:] 

+

147 else: 

+

148 end_pos = len(line_wo_nl) 

+

149 

+

150 marked_part = fo.colored(line_wo_nl[start_pos:end_pos], fg="red", style="bold") 

+

151 

+

152 return prefix + marked_part + suffix 

+

153 

+

154 

+

155def report_diagnostic( 

+

156 fo: OutputStylingBase, 

+

157 filename: str, 

+

158 diagnostic: Diagnostic, 

+

159 lines: List[str], 

+

160 auto_fixable: bool, 

+

161 auto_fixed: bool, 

+

162 lint_report: LintReport, 

+

163) -> None: 

+

164 logger = _DEFAULT_LOGGER 

+

165 assert logger is not None 

+

166 severity = diagnostic.severity 

+

167 missing_severity = False 

+

168 if severity is None: 

+

169 severity = DiagnosticSeverity.Warning 

+

170 missing_severity = True 

+

171 if not auto_fixed: 

+

172 tag_unresolved = _SEVERITY2TAG.get(severity) 

+

173 if tag_unresolved is None: 

+

174 tag_unresolved = _SEVERITY2TAG[DiagnosticSeverity.Warning] 

+

175 lint_report.diagnostics_without_severity += 1 

+

176 else: 

+

177 lint_report.diagnostics_count[severity] += 1 

+

178 tag = tag_unresolved(fo) 

+

179 else: 

+

180 tag = fo.colored( 

+

181 "auto-fixing", 

+

182 fg="magenta", 

+

183 bg="black", 

+

184 style="bold", 

+

185 ) 

+

186 start_line = diagnostic.range.start.line 

+

187 start_position = diagnostic.range.start.character 

+

188 end_line = diagnostic.range.end.line 

+

189 end_position = diagnostic.range.end.character 

+

190 has_fixit = "" 

+

191 line_no_width = len(str(len(lines))) 

+

192 if not auto_fixed and auto_fixable: 

+

193 has_fixit = " [Correctable via --auto-fix]" 

+

194 lint_report.fixable += 1 

+

195 print( 

+

196 f"{tag}: File: {filename}:{start_line+1}:{start_position}:{end_line+1}:{end_position}: {diagnostic.message}{has_fixit}", 

+

197 ) 

+

198 if missing_severity: 

+

199 _warn( 

+

200 " This warning did not have an explicit severity; Used Warning as a fallback!" 

+

201 ) 

+

202 if auto_fixed: 

+

203 # If it is fixed, there is no reason to show additional context. 

+

204 lint_report.fixed += 1 

+

205 return 

+

206 lines_to_print = _lines_to_print(diagnostic.range) 

+

207 if diagnostic.range.end.line > len(lines) or diagnostic.range.start.line < 0: 

+

208 lint_report.diagnostic_errors += 1 

+

209 _warn( 

+

210 "Bug in the underlying linter: The line numbers of the warning does not fit in the file..." 

+

211 ) 

+

212 return 

+

213 if lines_to_print == 1: 

+

214 line = _highlight_range(fo, lines[start_line], start_line, diagnostic.range) 

+

215 print(f" {start_line+1:{line_no_width}}: {line}") 

+

216 else: 

+

217 for line_no in range(start_line, end_line): 

+

218 line = _highlight_range(fo, lines[line_no], line_no, diagnostic.range) 

+

219 print(f" {line_no+1:{line_no_width}}: {line}") 

+
+ + + -- cgit v1.2.3