diff --git a/scripts/dethunk/exclusion_list/r21_u6.toml b/scripts/dethunk/exclusion_list/r21_u6.toml new file mode 100644 index 0000000..3c296ed --- /dev/null +++ b/scripts/dethunk/exclusion_list/r21_u6.toml @@ -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::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', + '::SemVersion', + '::ServiceReference<::AppConfigs>', + '::ActorDataFlagComponent', + '::ActorDataBoundingBoxComponent', + '::glm::qua', +] +contains = [ + # todo + '::std::variant<', +] diff --git a/scripts/dethunk/header_processor.py b/scripts/dethunk/header_processor.py index 377fe00..6054cd0 100644 --- a/scripts/dethunk/header_processor.py +++ b/scripts/dethunk/header_processor.py @@ -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::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};' diff --git a/scripts/dethunk/main.py b/scripts/dethunk/main.py index b546628..f184c4b 100644 --- a/scripts/dethunk/main.py +++ b/scripts/dethunk/main.py @@ -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') diff --git a/scripts/dethunk/options.py b/scripts/dethunk/options.py index ed1fdaf..3331a23 100644 --- a/scripts/dethunk/options.py +++ b/scripts/dethunk/options.py @@ -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) diff --git a/scripts/dethunk/util/cpp_language.py b/scripts/dethunk/util/cpp_language.py index 879a253..984fa8f 100644 --- a/scripts/dethunk/util/cpp_language.py +++ b/scripts/dethunk/util/cpp_language.py @@ -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',