Remove EmptyBlockState

- Turns out you can't put an empty block except in code
This commit is contained in:
Dustin Spicuzza 2023-09-27 01:14:21 -04:00
parent 8c69970857
commit 326da6112c
6 changed files with 1 additions and 124 deletions

View File

@ -10,7 +10,6 @@ from .lexer import LexToken, Location, PhonyEnding
from .options import ParserOptions from .options import ParserOptions
from .parserstate import ( from .parserstate import (
ClassBlockState, ClassBlockState,
EmptyBlockState,
ExternBlockState, ExternBlockState,
NamespaceBlockState, NamespaceBlockState,
ParsedTypeModifiers, ParsedTypeModifiers,
@ -510,9 +509,7 @@ class CxxParser:
def _on_empty_block_start( def _on_empty_block_start(
self, tok: LexToken, doxygen: typing.Optional[str] self, tok: LexToken, doxygen: typing.Optional[str]
) -> None: ) -> None:
state = self._push_state(EmptyBlockState) raise self._parse_error(tok)
if self.visitor.on_empty_block_start(state) is False:
self.visitor = null_visitor
def _on_block_end(self, tok: LexToken, doxygen: typing.Optional[str]) -> None: def _on_block_end(self, tok: LexToken, doxygen: typing.Optional[str]) -> None:
old_state = self._pop_state() old_state = self._pop_state()

View File

@ -56,13 +56,6 @@ class State(typing.Generic[T, PT]):
pass 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]): class ExternBlockState(State[T, PT]):
parent: State[PT, typing.Any] parent: State[PT, typing.Any]

View File

@ -51,7 +51,6 @@ from .types import (
from .parserstate import ( from .parserstate import (
State, State,
EmptyBlockState,
ClassBlockState, ClassBlockState,
ExternBlockState, ExternBlockState,
NamespaceBlockState, NamespaceBlockState,
@ -181,7 +180,6 @@ class ParsedData:
# define what user data we store in each state type # define what user data we store in each state type
SState = State[Block, Block] SState = State[Block, Block]
SEmptyBlockState = EmptyBlockState[Block, Block]
SExternBlockState = ExternBlockState[Block, Block] SExternBlockState = ExternBlockState[Block, Block]
SNamespaceBlockState = NamespaceBlockState[NamespaceScope, NamespaceScope] SNamespaceBlockState = NamespaceBlockState[NamespaceScope, NamespaceScope]
SClassBlockState = ClassBlockState[ClassScope, Block] SClassBlockState = ClassBlockState[ClassScope, Block]
@ -209,16 +207,6 @@ class SimpleCxxVisitor:
def on_include(self, state: SState, filename: str) -> None: def on_include(self, state: SState, filename: str) -> None:
self.data.includes.append(Include(filename)) 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]: def on_extern_block_start(self, state: SExternBlockState) -> typing.Optional[bool]:
state.user_data = state.parent.user_data state.user_data = state.parent.user_data
return None return None

View File

@ -25,7 +25,6 @@ from .types import (
from .parserstate import ( from .parserstate import (
State, State,
EmptyBlockState,
ClassBlockState, ClassBlockState,
ExternBlockState, ExternBlockState,
NamespaceBlockState, NamespaceBlockState,
@ -52,26 +51,6 @@ class CxxVisitor(Protocol):
Called once for each ``#include`` directive encountered 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]: def on_extern_block_start(self, state: ExternBlockState) -> typing.Optional[bool]:
""" """
.. code-block:: c++ .. code-block:: c++
@ -258,12 +237,6 @@ class NullVisitor:
def on_include(self, state: State, filename: str) -> None: def on_include(self, state: State, filename: str) -> None:
return 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]: def on_extern_block_start(self, state: ExternBlockState) -> typing.Optional[bool]:
return None return None

View File

@ -351,29 +351,3 @@ def test_warning_directive() -> None:
data = parse_string(content, cleandoc=True) data = parse_string(content, cleandoc=True)
assert data == ParsedData() 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"
)
)
)
]
)
)

View File

@ -10,7 +10,6 @@ from cxxheaderparser.simple import (
NamespaceScope, NamespaceScope,
ParsedData, ParsedData,
SClassBlockState, SClassBlockState,
SEmptyBlockState,
SExternBlockState, SExternBlockState,
SNamespaceBlockState, SNamespaceBlockState,
SimpleCxxVisitor, 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("<str>", 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 # ensure namespace 'skip' is skipped
# #