1#!/usr/bin/env python3 2# coding=utf-8 3# 4# Copyright (c) 2024 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17 18"""Provides line iterator class.""" 19 20from text_tools import find_first_of_characters 21from cpp_keywords import known_macroses 22 23 24class LineIterator: # pylint: disable=C0115 25 def __init__(self, data_raw: str, start: int = 0): 26 self.data = data_raw 27 28 self.start = start 29 self.end = find_first_of_characters("\n", self.data, start) 30 31 self.current_line = self.data[self.start : self.end].strip(" \n") 32 33 self.next_parenthese = find_first_of_characters("(", self.data, start) 34 self.next_semicolon = find_first_of_characters(";", self.data, start) 35 self.next_equal = find_first_of_characters("=", self.data, start) 36 37 self.processed_first_line = False 38 39 def next_line(self) -> bool: 40 if not self.processed_first_line: 41 self.processed_first_line = True 42 if self.current_line != "": 43 return True 44 45 self.end = find_first_of_characters("\n", self.data, self.end) 46 47 if self.end == len(self.data): 48 return False 49 50 self.start = self.end + 1 51 self.end = find_first_of_characters("\n", self.data, self.start) 52 self.current_line = self.data[self.start : self.end].strip(" \n") 53 54 self.next_parenthese = find_first_of_characters("(", self.data, self.start) 55 self.next_semicolon = find_first_of_characters(";", self.data, self.start) 56 self.next_equal = find_first_of_characters("=", self.data, self.start) 57 58 if self.current_line == "": 59 return self.next_line() 60 61 return True 62 63 def is_skip_line(self) -> bool: 64 return ( 65 self.current_line.find("#ifndef") != -1 66 or self.current_line.find("#undef") != -1 67 or self.current_line.find("#endif") != -1 68 ) 69 70 def is_template(self) -> bool: 71 return self.current_line.find("template") != -1 72 73 def is_namespace(self) -> bool: 74 return self.current_line.find("namespace") != -1 75 76 def is_enum(self) -> bool: 77 return self.current_line.find("enum class") != -1 78 79 def is_struct(self) -> bool: 80 return self.current_line.find("struct ") != -1 81 82 def is_using(self) -> bool: 83 return self.current_line.find("using ") != -1 84 85 def is_known_macros(self) -> bool: 86 for name in known_macroses: 87 if self.current_line.find(name) != -1: 88 return True 89 return False 90 91 def is_define_macro(self) -> bool: 92 return self.current_line.find("#define ") != -1 93 94 def is_access_modifier(self) -> bool: 95 return self.current_line in ["private:", "public:", "protected:"] 96 97 def is_firend_class(self) -> bool: 98 return self.current_line.find("friend class ") != -1 99 100 def is_class_forward_decl(self) -> bool: 101 return self.current_line.find("class ") != -1 and self.current_line.find(";") != -1 102 103 def is_class_definition(self) -> bool: 104 return self.current_line.find("class ") != -1 and not self.is_class_forward_decl() 105 106 def is_function_or_field(self) -> bool: 107 return self.next_parenthese < self.end or self.next_semicolon < self.end or self.next_equal < self.end 108 109 def is_method_or_constructor(self) -> bool: 110 return ( 111 self.is_function_or_field() 112 and self.next_parenthese < self.next_semicolon 113 and (self.next_parenthese < self.next_equal or self.current_line.find("operator==") != -1) 114 ) 115 116 def is_field(self) -> bool: 117 return self.is_function_or_field() 118