From 326da6112ce5faf1c5dbc5b99f0a9ea75138c674 Mon Sep 17 00:00:00 2001 From: Dustin Spicuzza Date: Wed, 27 Sep 2023 01:14:21 -0400 Subject: [PATCH] Remove EmptyBlockState - Turns out you can't put an empty block except in code --- cxxheaderparser/parser.py | 5 +--- cxxheaderparser/parserstate.py | 7 ----- cxxheaderparser/simple.py | 12 --------- cxxheaderparser/visitor.py | 27 ------------------- tests/test_misc.py | 26 ------------------ tests/test_skip.py | 48 ---------------------------------- 6 files changed, 1 insertion(+), 124 deletions(-) diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index 75d2d39..1c32073 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -10,7 +10,6 @@ from .lexer import LexToken, Location, PhonyEnding from .options import ParserOptions from .parserstate import ( ClassBlockState, - EmptyBlockState, ExternBlockState, NamespaceBlockState, ParsedTypeModifiers, @@ -510,9 +509,7 @@ class CxxParser: def _on_empty_block_start( self, tok: LexToken, doxygen: typing.Optional[str] ) -> None: - state = self._push_state(EmptyBlockState) - if self.visitor.on_empty_block_start(state) is False: - self.visitor = null_visitor + raise self._parse_error(tok) def _on_block_end(self, tok: LexToken, doxygen: typing.Optional[str]) -> None: old_state = self._pop_state() diff --git a/cxxheaderparser/parserstate.py b/cxxheaderparser/parserstate.py index 86ed2f6..1bd238a 100644 --- a/cxxheaderparser/parserstate.py +++ b/cxxheaderparser/parserstate.py @@ -56,13 +56,6 @@ class State(typing.Generic[T, PT]): pass -class EmptyBlockState(State[T, PT]): - parent: State[PT, typing.Any] - - def _finish(self, visitor: "CxxVisitor") -> None: - visitor.on_empty_block_end(self) - - class ExternBlockState(State[T, PT]): parent: State[PT, typing.Any] diff --git a/cxxheaderparser/simple.py b/cxxheaderparser/simple.py index a58191e..612de75 100644 --- a/cxxheaderparser/simple.py +++ b/cxxheaderparser/simple.py @@ -51,7 +51,6 @@ from .types import ( from .parserstate import ( State, - EmptyBlockState, ClassBlockState, ExternBlockState, NamespaceBlockState, @@ -181,7 +180,6 @@ class ParsedData: # define what user data we store in each state type SState = State[Block, Block] -SEmptyBlockState = EmptyBlockState[Block, Block] SExternBlockState = ExternBlockState[Block, Block] SNamespaceBlockState = NamespaceBlockState[NamespaceScope, NamespaceScope] SClassBlockState = ClassBlockState[ClassScope, Block] @@ -209,16 +207,6 @@ class SimpleCxxVisitor: def on_include(self, state: SState, filename: str) -> None: self.data.includes.append(Include(filename)) - def on_empty_block_start(self, state: SEmptyBlockState) -> typing.Optional[bool]: - # this matters for some scope/resolving purposes, but you're - # probably going to want to use clang if you care about that - # level of detail - state.user_data = state.parent.user_data - return None - - def on_empty_block_end(self, state: SEmptyBlockState) -> None: - pass - def on_extern_block_start(self, state: SExternBlockState) -> typing.Optional[bool]: state.user_data = state.parent.user_data return None diff --git a/cxxheaderparser/visitor.py b/cxxheaderparser/visitor.py index 5c17a46..eb71f0c 100644 --- a/cxxheaderparser/visitor.py +++ b/cxxheaderparser/visitor.py @@ -25,7 +25,6 @@ from .types import ( from .parserstate import ( State, - EmptyBlockState, ClassBlockState, ExternBlockState, NamespaceBlockState, @@ -52,26 +51,6 @@ class CxxVisitor(Protocol): Called once for each ``#include`` directive encountered """ - def on_empty_block_start(self, state: EmptyBlockState) -> typing.Optional[bool]: - """ - Called when a ``{`` is encountered that isn't associated with or - consumed by other declarations. - - .. code-block:: c++ - - { - // stuff - } - - If this function returns False, the visitor will not be called for any - items inside this block (including on_empty_block_end) - """ - - def on_empty_block_end(self, state: EmptyBlockState) -> None: - """ - Called when an empty block ends - """ - def on_extern_block_start(self, state: ExternBlockState) -> typing.Optional[bool]: """ .. code-block:: c++ @@ -258,12 +237,6 @@ class NullVisitor: def on_include(self, state: State, filename: str) -> None: return None - def on_empty_block_start(self, state: EmptyBlockState) -> typing.Optional[bool]: - return None - - def on_empty_block_end(self, state: EmptyBlockState) -> None: - return None - def on_extern_block_start(self, state: ExternBlockState) -> typing.Optional[bool]: return None diff --git a/tests/test_misc.py b/tests/test_misc.py index 3cf52d8..f0bad01 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -351,29 +351,3 @@ def test_warning_directive() -> None: data = parse_string(content, cleandoc=True) assert data == ParsedData() - - -def test_empty_block() -> None: - """ - Ensure the simple visitor doesn't break with an empty block - """ - content = """ - { - class X {}; - } - """ - data = parse_string(content, cleandoc=True) - - assert data == ParsedData( - namespace=NamespaceScope( - classes=[ - ClassScope( - class_decl=ClassDecl( - typename=PQName( - segments=[NameSpecifier(name="X")], classkey="class" - ) - ) - ) - ] - ) - ) diff --git a/tests/test_skip.py b/tests/test_skip.py index 2415e03..a116af2 100644 --- a/tests/test_skip.py +++ b/tests/test_skip.py @@ -10,7 +10,6 @@ from cxxheaderparser.simple import ( NamespaceScope, ParsedData, SClassBlockState, - SEmptyBlockState, SExternBlockState, SNamespaceBlockState, SimpleCxxVisitor, @@ -148,53 +147,6 @@ def test_skip_class() -> None: ) -# -# ensure empty block is skipped -# - - -class SkipEmptyBlock(SimpleCxxVisitor): - def on_empty_block_start(self, state: SEmptyBlockState) -> typing.Optional[bool]: - return False - - -def test_skip_empty_block() -> None: - content = """ - void fn1(); - - { - void fn2(); - } - - void fn3(); - """ - v = SkipEmptyBlock() - parser = CxxParser("", inspect.cleandoc(content), v) - parser.parse() - data = v.data - - assert data == ParsedData( - namespace=NamespaceScope( - functions=[ - Function( - return_type=Type( - typename=PQName(segments=[FundamentalSpecifier(name="void")]) - ), - name=PQName(segments=[NameSpecifier(name="fn1")]), - parameters=[], - ), - Function( - return_type=Type( - typename=PQName(segments=[FundamentalSpecifier(name="void")]) - ), - name=PQName(segments=[NameSpecifier(name="fn3")]), - parameters=[], - ), - ] - ) - ) - - # # ensure namespace 'skip' is skipped #