Holds states related to parsing braces.
| 1914 | |
| 1915 | |
| 1916 | class _NestingState(object): |
| 1917 | """Holds states related to parsing braces.""" |
| 1918 | |
| 1919 | def __init__(self): |
| 1920 | # Stack for tracking all braces. An object is pushed whenever we |
| 1921 | # see a "{", and popped when we see a "}". Only 3 types of |
| 1922 | # objects are possible: |
| 1923 | # - _ClassInfo: a class or struct. |
| 1924 | # - _NamespaceInfo: a namespace. |
| 1925 | # - _BlockInfo: some other type of block. |
| 1926 | self.stack = [] |
| 1927 | |
| 1928 | # Stack of _PreprocessorInfo objects. |
| 1929 | self.pp_stack = [] |
| 1930 | |
| 1931 | def SeenOpenBrace(self): |
| 1932 | """Check if we have seen the opening brace for the innermost block. |
| 1933 | |
| 1934 | Returns: |
| 1935 | True if we have seen the opening brace, False if the innermost |
| 1936 | block is still expecting an opening brace. |
| 1937 | """ |
| 1938 | return (not self.stack) or self.stack[-1].seen_open_brace |
| 1939 | |
| 1940 | def InNamespaceBody(self): |
| 1941 | """Check if we are currently one level inside a namespace body. |
| 1942 | |
| 1943 | Returns: |
| 1944 | True if top of the stack is a namespace block, False otherwise. |
| 1945 | """ |
| 1946 | return self.stack and isinstance(self.stack[-1], _NamespaceInfo) |
| 1947 | |
| 1948 | def UpdatePreprocessor(self, line): |
| 1949 | """Update preprocessor stack. |
| 1950 | |
| 1951 | We need to handle preprocessors due to classes like this: |
| 1952 | #ifdef SWIG |
| 1953 | struct ResultDetailsPageElementExtensionPoint { |
| 1954 | #else |
| 1955 | struct ResultDetailsPageElementExtensionPoint : public Extension { |
| 1956 | #endif |
| 1957 | |
| 1958 | We make the following assumptions (good enough for most files): |
| 1959 | - Preprocessor condition evaluates to true from #if up to first |
| 1960 | #else/#elif/#endif. |
| 1961 | |
| 1962 | - Preprocessor condition evaluates to false from #else/#elif up |
| 1963 | to #endif. We still perform lint checks on these lines, but |
| 1964 | these do not affect nesting stack. |
| 1965 | |
| 1966 | Args: |
| 1967 | line: current line to check. |
| 1968 | """ |
| 1969 | if Match(r'^\s*#\s*(if|ifdef|ifndef)\b', line): |
| 1970 | # Beginning of #if block, save the nesting stack here. The saved |
| 1971 | # stack will allow us to restore the parsing state in the #else case. |
| 1972 | self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack))) |
| 1973 | elif Match(r'^\s*#\s*(else|elif)\b', line): |