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