13af6ab5fSopenharmony_ci#!/usr/bin/env python3
23af6ab5fSopenharmony_ci# coding=utf-8
33af6ab5fSopenharmony_ci#
43af6ab5fSopenharmony_ci# Copyright (c) 2024 Huawei Device Co., Ltd.
53af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
63af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License.
73af6ab5fSopenharmony_ci# You may obtain a copy of the License at
83af6ab5fSopenharmony_ci#
93af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0
103af6ab5fSopenharmony_ci#
113af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
123af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
133af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and
153af6ab5fSopenharmony_ci# limitations under the License.
163af6ab5fSopenharmony_ci
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_ci"""Provides line iterator class."""
193af6ab5fSopenharmony_ci
203af6ab5fSopenharmony_cifrom text_tools import find_first_of_characters
213af6ab5fSopenharmony_cifrom cpp_keywords import known_macroses
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_ci
243af6ab5fSopenharmony_ciclass LineIterator:  # pylint: disable=C0115
253af6ab5fSopenharmony_ci    def __init__(self, data_raw: str, start: int = 0):
263af6ab5fSopenharmony_ci        self.data = data_raw
273af6ab5fSopenharmony_ci
283af6ab5fSopenharmony_ci        self.start = start
293af6ab5fSopenharmony_ci        self.end = find_first_of_characters("\n", self.data, start)
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_ci        self.current_line = self.data[self.start : self.end].strip(" \n")
323af6ab5fSopenharmony_ci
333af6ab5fSopenharmony_ci        self.next_parenthese = find_first_of_characters("(", self.data, start)
343af6ab5fSopenharmony_ci        self.next_semicolon = find_first_of_characters(";", self.data, start)
353af6ab5fSopenharmony_ci        self.next_equal = find_first_of_characters("=", self.data, start)
363af6ab5fSopenharmony_ci
373af6ab5fSopenharmony_ci        self.processed_first_line = False
383af6ab5fSopenharmony_ci
393af6ab5fSopenharmony_ci    def next_line(self) -> bool:
403af6ab5fSopenharmony_ci        if not self.processed_first_line:
413af6ab5fSopenharmony_ci            self.processed_first_line = True
423af6ab5fSopenharmony_ci            if self.current_line != "":
433af6ab5fSopenharmony_ci                return True
443af6ab5fSopenharmony_ci
453af6ab5fSopenharmony_ci        self.end = find_first_of_characters("\n", self.data, self.end)
463af6ab5fSopenharmony_ci
473af6ab5fSopenharmony_ci        if self.end == len(self.data):
483af6ab5fSopenharmony_ci            return False
493af6ab5fSopenharmony_ci
503af6ab5fSopenharmony_ci        self.start = self.end + 1
513af6ab5fSopenharmony_ci        self.end = find_first_of_characters("\n", self.data, self.start)
523af6ab5fSopenharmony_ci        self.current_line = self.data[self.start : self.end].strip(" \n")
533af6ab5fSopenharmony_ci
543af6ab5fSopenharmony_ci        self.next_parenthese = find_first_of_characters("(", self.data, self.start)
553af6ab5fSopenharmony_ci        self.next_semicolon = find_first_of_characters(";", self.data, self.start)
563af6ab5fSopenharmony_ci        self.next_equal = find_first_of_characters("=", self.data, self.start)
573af6ab5fSopenharmony_ci
583af6ab5fSopenharmony_ci        if self.current_line == "":
593af6ab5fSopenharmony_ci            return self.next_line()
603af6ab5fSopenharmony_ci
613af6ab5fSopenharmony_ci        return True
623af6ab5fSopenharmony_ci
633af6ab5fSopenharmony_ci    def is_skip_line(self) -> bool:
643af6ab5fSopenharmony_ci        return (
653af6ab5fSopenharmony_ci            self.current_line.find("#ifndef") != -1
663af6ab5fSopenharmony_ci            or self.current_line.find("#undef") != -1
673af6ab5fSopenharmony_ci            or self.current_line.find("#endif") != -1
683af6ab5fSopenharmony_ci        )
693af6ab5fSopenharmony_ci
703af6ab5fSopenharmony_ci    def is_template(self) -> bool:
713af6ab5fSopenharmony_ci        return self.current_line.find("template") != -1
723af6ab5fSopenharmony_ci
733af6ab5fSopenharmony_ci    def is_namespace(self) -> bool:
743af6ab5fSopenharmony_ci        return self.current_line.find("namespace") != -1
753af6ab5fSopenharmony_ci
763af6ab5fSopenharmony_ci    def is_enum(self) -> bool:
773af6ab5fSopenharmony_ci        return self.current_line.find("enum class") != -1
783af6ab5fSopenharmony_ci
793af6ab5fSopenharmony_ci    def is_struct(self) -> bool:
803af6ab5fSopenharmony_ci        return self.current_line.find("struct ") != -1
813af6ab5fSopenharmony_ci
823af6ab5fSopenharmony_ci    def is_using(self) -> bool:
833af6ab5fSopenharmony_ci        return self.current_line.find("using ") != -1
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ci    def is_known_macros(self) -> bool:
863af6ab5fSopenharmony_ci        for name in known_macroses:
873af6ab5fSopenharmony_ci            if self.current_line.find(name) != -1:
883af6ab5fSopenharmony_ci                return True
893af6ab5fSopenharmony_ci        return False
903af6ab5fSopenharmony_ci
913af6ab5fSopenharmony_ci    def is_define_macro(self) -> bool:
923af6ab5fSopenharmony_ci        return self.current_line.find("#define ") != -1
933af6ab5fSopenharmony_ci
943af6ab5fSopenharmony_ci    def is_access_modifier(self) -> bool:
953af6ab5fSopenharmony_ci        return self.current_line in ["private:", "public:", "protected:"]
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_ci    def is_firend_class(self) -> bool:
983af6ab5fSopenharmony_ci        return self.current_line.find("friend class ") != -1
993af6ab5fSopenharmony_ci
1003af6ab5fSopenharmony_ci    def is_class_forward_decl(self) -> bool:
1013af6ab5fSopenharmony_ci        return self.current_line.find("class ") != -1 and self.current_line.find(";") != -1
1023af6ab5fSopenharmony_ci
1033af6ab5fSopenharmony_ci    def is_class_definition(self) -> bool:
1043af6ab5fSopenharmony_ci        return self.current_line.find("class ") != -1 and not self.is_class_forward_decl()
1053af6ab5fSopenharmony_ci
1063af6ab5fSopenharmony_ci    def is_function_or_field(self) -> bool:
1073af6ab5fSopenharmony_ci        return self.next_parenthese < self.end or self.next_semicolon < self.end or self.next_equal < self.end
1083af6ab5fSopenharmony_ci
1093af6ab5fSopenharmony_ci    def is_method_or_constructor(self) -> bool:
1103af6ab5fSopenharmony_ci        return (
1113af6ab5fSopenharmony_ci            self.is_function_or_field()
1123af6ab5fSopenharmony_ci            and self.next_parenthese < self.next_semicolon
1133af6ab5fSopenharmony_ci            and (self.next_parenthese < self.next_equal or self.current_line.find("operator==") != -1)
1143af6ab5fSopenharmony_ci        )
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_ci    def is_field(self) -> bool:
1173af6ab5fSopenharmony_ci        return self.is_function_or_field()
118