def check(self, lineNumber, line): result = re.search(self.patternRegion, line) if not result: return prefix = result.group(1) if prefix == ' ': if self.counter > 0: if not self.firstBeforeNestedLine: self.firstBeforeNestedLine = self.previousRegionLine self.firstBeforeNestedLineNumber = self.previousRegionLineNumber msg = 'nested region (top-most in line:{})'.format( self.firstBeforeNestedLineNumber) self.errors.append( Line(self.path, line.strip('\n\r'), lineNumber, msg)) self.previousRegionLine = line.strip('\n\r') self.previousRegionLineNumber = lineNumber self.counter += 1 elif prefix == ' end': if self.counter == 0: self.errors.append( Line(self.path, line.strip('\n\r'), lineNumber, 'endregion without corresponding region')) self.counter -= 1 else: # if name is invalid report immediatelly self.errorReporter( self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'invalid region "{}"'.format(result.group(0))))
def finalize(self): if not self.gotLicense: self.errorReporter(self.NAME, Line(self.path, '', 0, 'Missing license info')) if not self.gotPragmaOnce: self.errorReporter(self.NAME, Line(self.path, '', 0, 'Missing `#pragma once`')) if self.reportEmptyLineError: self.errorReporter(self.NAME, Line(self.path, '', self.emptyLineNumber, 'Empty line after `#pragma once`'))
def check(self, lineNumber, line): strippedLine = line.strip('\n\r') if re.match(self.patternEnumValue, self.previousLine) and not re.match(self.patternBlankLine, strippedLine): self.errorReporter(self.NAME, Line(self.path, self.previousLine, lineNumber - 1, 'enum value is missing following blank line')) self.previousLine = strippedLine
def check(self, lineNumber, line): if re.match(r'src.catapult.functions.h', self.path): return for k, errorMsg in self.errors.items(): if re.search(k, line): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, errorMsg))
def check(self, lineNumber, line): self.lastLineNumber = lineNumber if lineNumber <= 20: self.hasher.update(bytes(line, 'utf-8')) if lineNumber == 20: if self.expectedHash != self.hasher.digest(): self.errorReporter(self.NAME, Line(self.path, '', 1))
def check(self, lineNumber, line): if self.matchLineNumber and self.matchLineNumber + 1 == lineNumber and line: if not self.match(line, lineNumber): self.errorReporter( self.NAME, Line(self.path, self.lineTestClass, self.matchLineNumber)) self.match(line, lineNumber)
def check(self, lineNumber, line): if re.search(self.patternWhitespaces, line): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'Whitespace at line ending')) if re.match(self.patternSpacesStart, line): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'Spaces at beginning of a line')) if re.match(self.patternTabsStart, line): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'Tabs in empty line')) operatorMatch = re.search(self.patternSpaceOperator, line) if operatorMatch: errorMsg = 'Space after operator >>{}<<'.format(operatorMatch.group(1)) self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, errorMsg)) if re.search(self.patternTabInside, line): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'Tab present inside the text')) if re.search(self.patternSpacesMiddle, line) or re.search(self.patternComma, line): temp = stripCommentsAndStrings(line) if re.search(self.patternSpacesMiddle, temp): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'Spaces in the middle')) gotComma = re.search(self.patternComma, temp) if gotComma and gotComma.group(0) not in [",)"]: self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'Comma should be followed by a space')) if re.search(self.patternCarriageReturn, line): self.carriageReturnCount += 1
def finalize(self): if self.counter > 0: line = self.firstBeforeNestedLine or self.previousRegionLine lineNumber = self.firstBeforeNestedLineNumber or self.previousRegionLineNumber self.errorReporter(self.NAME, Line(self.path, line, lineNumber, 'non-closed region (probable location)')) elif self.errors: for error in self.errors: self.errorReporter(self.NAME, error)
def check(self, lineNumber, line): result = re.search(self.patternReturn, line) if not result: return for pattern in self.skip: if re.search(pattern, line): return self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber))
def check(self, lineNumber, line): strippedLine = stripCommentsAndStrings(line) if not re.match(self.macroCall, strippedLine): return for pattern in self.skip: if re.search(pattern, strippedLine): return self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'macro should not have trailing semicolon'))
def check(self, lineNumber, line): self.recentLines.append(line.strip('\n\r')) self.recentLines.pop(0) # check if line following brace is valid: # 1. preprocessor directive # 2. another closing brace (with optional closing symbols and/or semicolon and/or comma) # 3. namespace statement within forward declarations # 4. break statement within switch # 5. catch statement # 6. closing square bracket (inline JSON) if re.match(self.patternClosingBrace, self.recentLines[1]): if self.recentLines[2] and not re.match(self.patternLineAfterClosingBrace, self.recentLines[2]): self.errorReporter(self.NAME, Line(self.path, self.recentLines[2], lineNumber, 'improper line following closing brace')) # check if line between closing braces is valid: # 1. blank # 2. valid line following brace if re.match(self.patternClosingBrace, self.recentLines[2]) and re.match(self.patternClosingBrace, self.recentLines[0]): if not self.recentLines[1] or not re.match(self.patternLineAfterClosingBrace, self.recentLines[1]): self.errorReporter(self.NAME, Line(self.path, self.recentLines[1], lineNumber - 1, 'improper line between closing braces'))
def finalize(self): report_forwards_error = True for pattern in SKIP_FORWARDS: if re.match(pattern, self.path): report_forwards_error = False break if self.last_namespace_next_line_length and self.last_namespace_line_number > self.last_forward_line_number: self.error_reporter( self.NAME, Line(self.path, '', self.last_namespace_line_number + 1, 'missingEmptyLine')) if report_forwards_error and self.had_forwards: expected_lines = self._format(self.declarations) expected = '\n'.join(expected_lines) current = '\n'.join(self.collected_lines[:len(expected_lines)]) if current != expected: self.error_reporter( self.NAME, Line(self.path, current, (self.match_line_number, self.previous_block_line_number - 1), expected))
def finalize(self): reportForwardsError = True for pattern in SKIP_FORWARDS: if re.match(pattern, self.path): reportForwardsError = False break if self.lastNamespaceNextLineLength and self.lastNamespaceLineNumber > self.lastForwardLineNumber: self.errorReporter( self.NAME, Line(self.path, '', self.lastNamespaceLineNumber + 1, 'missingEmptyLine')) if reportForwardsError and self.hadForwards: expectedLines = self._format(self.declarations) expected = '\n'.join(expectedLines) current = '\n'.join(self.collectedLines[:len(expectedLines)]) if current != expected: self.errorReporter( self.NAME, Line(self.path, current, (self.matchLineNumber, self.previousBlockLineNumber - 1), expected))
def check(self, lineNumber, line): # we want to match things like Foo { # and things like std::set<Foo> { result = re.search(self.patternNameSpaceBrace, line) if not result: return # skip if it matched return if 'return' == result.group(1): return for pattern in self.skip: if re.search(pattern, line): return self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, result.group(1)))
def check(self, lineNumber, line): strippedLine = stripCommentsAndStrings(line) # note that these checks are exclusive if self.checkTestLine(line): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'TEST should use TEST_CLASS')) elif self.checkExplicitOperatorBool(strippedLine): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'Missing explicit before operator bool')) elif self.checkValidationResult(strippedLine): msg = 'ValidationResult should not be last argument or should be called `value`' self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, msg)) elif self.checkExplicitCtor(strippedLine): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'missing explicit before ctor')) elif self.checkEnumClass(strippedLine): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'use enum class instead of enum')) elif self.checkCoerce(strippedLine): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'use const auto* .. = CoercePacket')) elif self.checkDefineTests(strippedLine): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'use MAKE_ for singular TEST')) elif self.checkFileSize(strippedLine): self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'FileSize should be passed by value'))
def _addForward(self, typeType, typeName): if not (self.typeType and self.lastName): return current = self._getPath() if typeName in current['forwards']: self.errorReporter(self.NAME, Line(self.path, typeName, self.lastLineNumber)) current['forwards'][typeName] = { 'type': typeType, 'pre': self.preTypeLines } self.hadForwards = True self.lastForwardLineNumber = self.lastLineNumber self.typeType = None self.lastName = None self.preTypeLines = []
def check(self, lineNumber, line): if self.numOpen: stripped = line.lstrip() if stripped.startswith('//'): self.numOpen = 0 return self.long = self.long + stripped if self.long.endswith(','): self.long += ' ' temp = stripCommentsAndStrings(stripped) numBrackets = 0 hadBrace = False for char in temp: if '(' == char: self.numOpen += 1 elif ')' == char: self.numOpen -= 1 elif '[' == char or ']' == char: numBrackets += 1 elif '{' == char: hadBrace = True if hadBrace and numBrackets > 1: self.numOpen = 0 return if 0 >= self.numOpen: temp = re.sub('\t', ' ', self.long) if len(temp) < 140: errorMsg = 'block fits in a single line' self.errorReporter( self.NAME, Line(self.path, self.long, self.firstLine, errorMsg)) # find lines ending with ( - possible function calls or definitions/declarations # but ignore raw string literals if line.endswith('(') and not line.endswith('R"('): self.numOpen = 1 self.firstLine = lineNumber self.long = line
def _add_forward(self, type_type, type_name): if not (self.type_type and self.last_name): return current = self._get_path() if type_name in current['forwards']: self.error_reporter( self.NAME, Line(self.path, type_name, self.last_line_number)) current['forwards'][type_name] = { 'type': type_type, 'pre': self.pre_type_lines } self.had_forwards = True self.last_forward_line_number = self.last_line_number self.type_type = None self.last_name = None self.pre_type_lines = []
def check(self, lineNumber, line): # we want to match things like Foo { # and things like std::set<Foo> { result = re.search(self.patternNameSpaceBrace, line) if not result: return # skip if it matched return matched = result.group(1) if 'return' == matched: return # skip if only closing angle bracket is used (MultisigCacheTypes) if '>' in matched and '<' not in matched: return for pattern in self.skip: if re.search(pattern, line): return self.errorReporter(self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, matched))
def finalize(self): if 0 < self.carriageReturnCount: errorMsg = 'Carriage returns present in file {} occurences'.format( self.carriageReturnCount) self.errorReporter(self.NAME, Line(self.path, '', 0, errorMsg))
def finalize(self): if self.hasMismatchedTestClass: self.errorReporter(self.NAME, Line(self.path, '', 0))
def finalize(self): if self.hasUtils: self.errorReporter(self.NAME, Line(self.path, '', 0))
def check(self, lineNumber, line): for k, errorMsg in self.errors.items(): if re.search(k, line): self.errorReporter( self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, errorMsg))
def check(self, lineNumber, line): if re.search(self.patternTemplate, line): errorMsg = 'catch and closing try brace must be on same line' self.errorReporter( self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, errorMsg))
def check(self, lineNumber, line): if re.search(self.patternTemplate, line): self.errorReporter( self.NAME, Line(self.path, line.strip('\n\r'), lineNumber, 'Template followed by space'))
def check(self, lineNumber, line): temp = re.sub('\t', ' ', line) if len(temp) >= self.lineLengthLimit: self.errorReporter(self.NAME, Line(self.path, line.strip(), lineNumber))
def finalize(self): if 20 > self.lastLineNumber: self.errorReporter(self.NAME, Line(self.path, '', 1))
def reportError(self, lineNumber, message): self.errorReporter(self.NAME, Line(self.path, self.recentLines[1], lineNumber - 1, message))
def finalize(self): if self.hasImproperName: self.errorReporter(self.NAME, Line(self.path, '', 0))