src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Async/AsyncChecker.py

branch
eric7
changeset 11150
73d80859079c
parent 11145
d328a7b74fd8
equal deleted inserted replaced
11149:fc45672fae42 11150:73d80859079c
5 5
6 """ 6 """
7 Module implementing a checker for "async" related issues. 7 Module implementing a checker for "async" related issues.
8 """ 8 """
9 9
10
11 import copy 10 import copy
12 11
12 from CodeStyleTopicChecker import CodeStyleTopicChecker
13 13
14 class AsyncChecker: 14
15 class AsyncChecker(CodeStyleTopicChecker):
15 """ 16 """
16 Class implementing a checker for "async" related issues. 17 Class implementing a checker for "async" related issues.
17 """ 18 """
18 19
19 Codes = [ 20 Codes = [
20 "ASY100", 21 "ASY-100",
21 "ASY101", 22 "ASY-101",
22 "ASY102", 23 "ASY-102",
23 "ASY103", 24 "ASY-103",
24 "ASY104", 25 "ASY-104",
25 "ASY105", 26 "ASY-105",
26 ] 27 ]
27 Prefix = "ASY" 28 Category = "ASY"
28 29
29 def __init__(self, source, filename, tree, select, ignore, expected, repeat, args): 30 def __init__(self, source, filename, tree, select, ignore, expected, repeat, args):
30 """ 31 """
31 Constructor 32 Constructor
32 33
45 @param repeat flag indicating to report each occurrence of a code 46 @param repeat flag indicating to report each occurrence of a code
46 @type bool 47 @type bool
47 @param args dictionary of arguments for the various checks 48 @param args dictionary of arguments for the various checks
48 @type dict 49 @type dict
49 """ 50 """
50 self.__select = tuple(x for x in select if x.startswith(AsyncChecker.Prefix)) 51 super().__init__(
51 self.__ignore = tuple(x for x in ignore if x.startswith(AsyncChecker.Prefix)) 52 AsyncChecker.Category,
52 self.__expected = expected[:] 53 source,
53 self.__repeat = repeat 54 filename,
54 self.__filename = filename 55 tree,
55 self.__source = source[:] 56 select,
56 self.__tree = copy.deepcopy(tree) 57 ignore,
57 self.__args = args 58 expected,
58 59 repeat,
59 # statistics counters 60 args,
60 self.counters = {} 61 )
61
62 # collection of detected errors
63 self.errors = []
64 62
65 checkersWithCodes = [ 63 checkersWithCodes = [
66 ( 64 (
67 self.__checkSyncUses, 65 self.__checkSyncUses,
68 ("ASY100", "ASY101", "ASY102", "ASY103", "ASY104", "ASY105"), 66 ("ASY-100", "ASY-101", "ASY-102", "ASY-103", "ASY-104", "ASY-105"),
69 ), 67 ),
70 ] 68 ]
71 69 self._initializeCheckers(checkersWithCodes)
72 self.__checkers = []
73 for checker, codes in checkersWithCodes:
74 if any(not (code and self.__ignoreCode(code)) for code in codes):
75 self.__checkers.append(checker)
76
77 def __ignoreCode(self, code):
78 """
79 Private method to check if the message code should be ignored.
80
81 @param code message code to check for
82 @type str
83 @return flag indicating to ignore the given code
84 @rtype bool
85 """
86 return code in self.__ignore or (
87 code.startswith(self.__ignore) and not code.startswith(self.__select)
88 )
89
90 def __error(self, lineNumber, offset, code, *args):
91 """
92 Private method to record an issue.
93
94 @param lineNumber line number of the issue
95 @type int
96 @param offset position within line of the issue
97 @type int
98 @param code message code
99 @type str
100 @param args arguments for the message
101 @type list
102 """
103 if self.__ignoreCode(code):
104 return
105
106 if code in self.counters:
107 self.counters[code] += 1
108 else:
109 self.counters[code] = 1
110
111 # Don't care about expected codes
112 if code in self.__expected:
113 return
114
115 if code and (self.counters[code] == 1 or self.__repeat):
116 # record the issue with one based line number
117 self.errors.append(
118 {
119 "file": self.__filename,
120 "line": lineNumber + 1,
121 "offset": offset,
122 "code": code,
123 "args": args,
124 }
125 )
126
127 def run(self):
128 """
129 Public method to check the given source against miscellaneous
130 conditions.
131 """
132 if not self.__filename:
133 # don't do anything, if essential data is missing
134 return
135
136 if not self.__checkers:
137 # don't do anything, if no codes were selected
138 return
139
140 for check in self.__checkers:
141 check()
142 70
143 def __checkSyncUses(self): 71 def __checkSyncUses(self):
144 """ 72 """
145 Private method to check for use of synchroneous functions in async methods. 73 Private method to check for use of synchroneous functions in async methods.
146 """ 74 """
147 from .AsyncVisitor import AsyncVisitor 75 from .AsyncVisitor import AsyncVisitor
148 76
149 visitor = AsyncVisitor(self.__args, self) 77 visitor = AsyncVisitor(self.args, self)
150 visitor.visit(copy.deepcopy(self.__tree)) 78 visitor.visit(copy.deepcopy(self.tree))
151 for violation in visitor.violations: 79 for violation in visitor.violations:
152 if not self.__ignoreCode(violation[1]): 80 self.addErrorFromNode(violation[0], violation[1])
153 node = violation[0]
154 reason = violation[1]
155 self.__error(node.lineno - 1, node.col_offset, reason)

eric ide

mercurial