feat: avoid hard-coding exclusion lists.

This commit is contained in:
2025-03-07 11:00:41 +08:00
parent 797acb39c4
commit ccac9623d9
5 changed files with 111 additions and 26 deletions

View File

@@ -0,0 +1,61 @@
# This is part of the failure of DeThunk's design, so it will be deprecated sooner or later.
# Supported phrase:
# equal, not_equal, contains, startswith, endswith
[forward_decl_translator.ignored]
contains = [
# see CommandRegistry.h, to resolve circular reference.
'CommandParameterData',
]
[trivial_dynamic_initializer_generator.ignored]
equal = [
'Json::ValueIteratorBase', # std::vector<T>::iterator
'Json::ValueConstIterator',
'Json::ValueIterator',
'MemoryStream', # std::istream
'Core::FileStream', # ::std::iostream
'CommandRegistry::Overload', # circular references
'CommandRegistry::Signature',
'Bedrock::UniqueOwnerPointer', # bug?
'MovementDataExtractionUtility::StorageStorage::StorageTupleT', # shit template
'PlayerNotificationEvent', # EventVariantImpl
'ClientInstanceNotificationEvent',
'ScriptingNotificationEvent',
'ServerNetworkGameplayNotificationEvent',
'ServerInstanceNotificationEvent',
'LevelNotificationEvent',
'BlockNotificationEvent',
'ItemNotificationEvent',
'ActorNotificationEvent',
'Details::ValueOrRef::Variant',
]
startswith = [
# bug?
'brstd::detail::function::',
]
[typeunwrapper.erased]
contains = [
'WeakRef<',
'::entt::basic_registry<',
'::Bedrock::Application::ThreadOwner<',
'::OwnerPtr<::EntityContext>',
]
[typeunwrapper.dyninit_erased]
equal = [
# # unique_ptr with user deleter
'::std::unique_ptr<::RakNet::RakPeerInterface, void (*)(::RakNet::RakPeerInterface*)>',
'::std::unique_ptr<uchar[0], ::mce::Blob::Deleter>',
'::SemVersion',
'::ServiceReference<::AppConfigs>',
'::ActorDataFlagComponent',
'::ActorDataBoundingBoxComponent',
'::glm::qua<float>',
]
contains = [
# todo
'::std::variant<',
]

View File

@@ -133,18 +133,10 @@ def process(path_to_file: str, args: Options):
if empty_class in type_name or (
args.erase_extra_invalid_types
and (
'WeakRef<' in type_name # TODO: remove it.
or '::entt::basic_registry<' in type_name
or '::Bedrock::Application::ThreadOwner<' in type_name
or '::OwnerPtr<::EntityContext>' in type_name
args.should_erase_type(type_name)
or (
args.add_trivial_dynamic_initializer
and '::std::variant<' in type_name # TODO: ...
)
or (
args.add_trivial_dynamic_initializer
and type_name # unique_ptr with user deleter, TODO: ...
== '::std::unique_ptr<::RakNet::RakPeerInterface, void (*)(::RakNet::RakPeerInterface*)>'
and args.should_erase_type_dyninit(type_name)
)
)
):
@@ -288,8 +280,7 @@ def process(path_to_file: str, args: Options):
content += line
if args.fix_includes_for_member_variables and has_typed_storage:
for decl in forward_declarations:
if args.add_trivial_dynamic_initializer and 'CommandParameterData' in decl:
# see CommandRegistry.h, to resolve circular reference.
if args.add_trivial_dynamic_initializer and args.should_ignore_forward_decl(decl):
continue
class_define = try_translate_forward_declaration(decl, member_variable_types)
if class_define:
@@ -311,19 +302,7 @@ def process(path_to_file: str, args: Options):
if ns:
full_name += '::'
full_name += cl
if (
full_name
in [
'Json::ValueIteratorBase', # std::vector<T>::iterator
'Json::ValueConstIterator',
'Json::ValueIterator',
'MemoryStream', # std::istream
'Core::FileStream', # ::std::iostream
'CommandRegistry::Overload', # circular references
'Bedrock::UniqueOwnerPointer', # bug?
'MovementDataExtractionUtility::StorageStorage::StorageTupleT', # shit template
]
):
if args.should_ignore_generate_dynamic_initializer(full_name):
continue
is_modified = True
content += f'\ninline {full_name} {var_name};'

View File

@@ -7,6 +7,7 @@ def main():
parser = argparse.ArgumentParser('dethunk')
parser.add_argument('path', help='Path to header project.')
parser.add_argument('--exclusion-list', help='Configure ignore rules.', required=True)
parser.add_argument('--remove-constructor-thunk', action='store_true')
parser.add_argument('--remove-destructor-thunk', action='store_true')

View File

@@ -2,6 +2,8 @@
Runtime Options
"""
import tomllib
class Options:
base_dir = str()
@@ -38,6 +40,8 @@ class Options:
# * see also https://reviews.llvm.org/D45978
fix_msvc_c2734 = True
exclusion_list = {}
def __init__(self, args):
self.base_dir = args.path
self.remove_constructor_thunk = args.remove_constructor_thunk
@@ -59,6 +63,9 @@ class Options:
# others
self.judge_other_options()
with open(args.exclusion_list, 'rb') as file:
self.exclusion_list = tomllib.load(file)
def set_function(self, opt: bool):
self.remove_constructor_thunk = opt
self.remove_destructor_thunk = opt
@@ -94,3 +101,40 @@ class Options:
if not self.restore_static_variable:
self.fix_msvc_c2734 = False
def _check_base(self, data, con: str):
if 'equal' in data:
for e in data['equal']:
if con == e:
return True
if 'not_equal' in data:
for ne in data['not_equal']:
if con == ne:
return False
if 'contains' in data:
for c in data['contains']:
if c in con:
return True
if 'startswith' in data:
for s in data['startswith']:
if con.startswith(s):
return True
if 'endswith' in data:
for e in data['endswith']:
if con.endswith(e):
return True
return False
def should_ignore_forward_decl(self, decl):
return self._check_base(self.exclusion_list['forward_decl_translator']['ignored'], decl)
def should_ignore_generate_dynamic_initializer(self, type_name):
return self._check_base(
self.exclusion_list['trivial_dynamic_initializer_generator']['ignored'], type_name
)
def should_erase_type(self, type_name):
return self._check_base(self.exclusion_list['typeunwrapper']['erased'], type_name)
def should_erase_type_dyninit(self, type_name):
return self._check_base(self.exclusion_list['typeunwrapper']['dyninit_erased'], type_name)

View File

@@ -175,7 +175,7 @@ def is_full_type_required(namespace_decl: str, class_decl: str, type_decl: str):
'shared_ptr',
'unique_ptr',
'weak_ptr',
# 'vector',
# 'vector', # for dyninit gen.
'queue',
'set',
'function',