Skip to content

Commit 220bae9

Browse files
committed
cleaner getters and setters
1 parent 57b92f1 commit 220bae9

File tree

1 file changed

+40
-49
lines changed

1 file changed

+40
-49
lines changed

addons/mod_loader/_export_plugin/export_plugin.gd

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,20 @@ extends EditorExportPlugin
33
const REQUIRE_EXPLICIT_ADDITION := false
44
const METHOD_PREFIX := "vanilla_"
55
const HASH_COLLISION_ERROR :="MODDING EXPORT ERROR: Hash collision between %s and %s. The collision can be resolved by renaming one of the methods or changing their scripts path."
6+
7+
static var regex_getter_setter: RegEx
8+
69
var hashmap := {}
710

11+
812
func _get_name() -> String:
913
return "Godot Mod Loader Export Plugin"
1014

1115
func _export_begin(features: PackedStringArray, is_debug: bool, path: String, flags: int) -> void:
1216
hashmap.clear()
17+
regex_getter_setter = RegEx.new()
18+
regex_getter_setter.compile("(.*?[sg]et\\s*=\\s*)(\\w+)(\\g<1>)?(\\g<2>)?")
19+
1320

1421
func _export_file(path: String, type: String, features: PackedStringArray) -> void:
1522
if path.begins_with("res://addons") or path.begins_with("res://mods-unpacked"):
@@ -22,7 +29,7 @@ func _export_file(path: String, type: String, features: PackedStringArray) -> vo
2229
var source_code := current_script.source_code
2330
var source_code_additions := ""
2431

25-
#we need to stop all vanilla methods from forming inheritance chains
32+
#we need to stop all vanilla methods from forming inheritance chains
2633
#since the generated methods will fulfill inheritance requirements
2734
var class_prefix = str(hash(path))
2835
var method_store: Array[String] = []
@@ -37,20 +44,26 @@ func _export_file(path: String, type: String, features: PackedStringArray) -> vo
3744
#print("-------------------- Method List")
3845
#print(JSON.stringify(current_script.get_script_method_list(), "\t"))
3946
#print("--------------------")
47+
#print(path.get_file())
48+
var getters_setters := collect_getters_and_setters(source_code)
49+
4050
for method in current_script.get_script_method_list():
4151
var method_first_line_start := get_index_at_method_start(method.name, source_code)
4252
if method_first_line_start == -1 or method.name in method_store:
4353
continue
44-
45-
if not is_func_moddable(method.name, method_first_line_start, source_code):
54+
55+
if getters_setters.has(method.name):
56+
continue
57+
58+
if not is_func_moddable(method_first_line_start, source_code):
4659
continue
47-
60+
4861
#print(method.flags)
4962
var type_string := get_return_type_string(method.return)
5063
var is_static := true if method.flags == METHOD_FLAG_STATIC + METHOD_FLAG_NORMAL else false
5164
var method_arg_string_with_defaults_and_types := get_function_parameters(method.name, source_code, is_static)
5265
var method_arg_string_names_only := get_function_arg_name_string(method.args)
53-
66+
5467
var hash_before = ModLoaderMod.get_hook_hash(path, method.name, true)
5568
var hash_after = ModLoaderMod.get_hook_hash(path, method.name, false)
5669
var hash_before_data = [path, method.name,true]
@@ -61,7 +74,7 @@ func _export_file(path: String, type: String, features: PackedStringArray) -> vo
6174
push_error(HASH_COLLISION_ERROR %[hashmap[hash_after], hash_after_data])
6275
hashmap[hash_before] = hash_before_data
6376
hashmap[hash_after] = hash_after_data
64-
77+
6578
var mod_loader_hook_string := get_mod_loader_hook(
6679
method.name,
6780
method_arg_string_names_only,
@@ -83,11 +96,11 @@ func _export_file(path: String, type: String, features: PackedStringArray) -> vo
8396
method_store.push_back(method.name)
8497
source_code = prefix_method_name(method.name, is_static, source_code, METHOD_PREFIX + class_prefix)
8598
source_code_additions += "\n%s" % mod_loader_hook_string
86-
99+
87100
#if we have some additions to the code, append them at the end
88101
if source_code_additions != "":
89102
source_code = "%s\n%s\n%s" % [source_code,mod_loader_hooks_start_string, source_code_additions]
90-
103+
91104
skip()
92105
add_file(path, source_code.to_utf8_buffer(), false)
93106

@@ -112,7 +125,7 @@ static func get_function_arg_name_string(args: Array) -> String:
112125
arg_string += args[x].name
113126
else:
114127
arg_string += "%s, " % args[x].name
115-
128+
116129
return arg_string
117130

118131

@@ -198,7 +211,7 @@ static func get_mod_loader_hook(
198211
var self_string := "null" if is_static else "self"
199212
var return_var := "var %s = " % "return_var" if not method_type.is_empty() or return_prop_usage == 131072 else ""
200213
var method_return := "return %s" % "return_var" if not method_type.is_empty() or return_prop_usage == 131072 else ""
201-
214+
202215
return """
203216
{%STATIC%}func {%METHOD_NAME%}({%METHOD_PARAMS%}){%RETURN_TYPE_STRING%}:
204217
ModLoaderMod.call_hooks({%SELF%}, [{%METHOD_ARGS%}], {%HOOK_ID_BEFORE%})
@@ -231,7 +244,7 @@ static func get_previous_line_to(text: String, index: int) -> String:
231244

232245
if start_index == 0:
233246
return ""
234-
247+
235248
start_index -= 1
236249

237250
# Find the start of the previous line
@@ -241,9 +254,7 @@ static func get_previous_line_to(text: String, index: int) -> String:
241254

242255
return text.substr(start_index, end_index - start_index + 1)
243256

244-
static func is_func_moddable(method_name, method_start_idx, text) -> bool:
245-
if is_setter(method_name, text) or is_getter(method_name,text):
246-
return false
257+
static func is_func_moddable(method_start_idx, text) -> bool:
247258
if not REQUIRE_EXPLICIT_ADDITION:
248259
return true
249260
return get_previous_line_to(text, method_start_idx).contains("@moddable")
@@ -280,47 +291,27 @@ static func get_return_type_string(return_data: Dictionary) -> String:
280291
return ""
281292
var type_base
282293
if return_data.has("class_name") and not str(return_data.class_name).is_empty():
283-
type_base = str(return_data.class_name)
294+
type_base = str(return_data.class_name)
284295
else:
285296
type_base = type_string(return_data.type)
286-
297+
287298
var type_hint = "" if return_data.hint_string.is_empty() else ("[%s]" % return_data.hint_string)
288299

289300
return "%s%s" % [type_base, type_hint]
290301

291-
static func is_setter(method_name: String, text: String, offset := 0) -> bool:
292-
var pattern := "set\\s*=\\s*%s" % method_name
293-
var regex := RegEx.new()
294-
regex.compile(pattern)
295302

296-
var result := regex.search(text, offset)
297-
298-
if result:
299-
var line_start_index := text.rfind("\n", result.get_start()) + 1
300-
var line_start_string := text.substr(result.get_start(), result.get_start() - line_start_index)
301-
if line_start_string.contains("#"):
302-
303-
return is_setter(method_name, text, result.get_end())
304-
305-
return true
306-
307-
return false
308-
309-
310-
static func is_getter(method_name: String, text: String, offset := 0) -> bool:
311-
var pattern := "get\\s*=\\s*%s" % method_name
312-
var regex := RegEx.new()
313-
regex.compile(pattern)
314-
315-
var result := regex.search(text, offset)
316-
317-
if result:
318-
var line_start_index := text.rfind("\n", result.get_start()) + 1
319-
var line_start_string := text.substr(result.get_start(), result.get_start() - line_start_index)
320-
if line_start_string.contains("#"):
321-
322-
return is_setter(method_name, text, result.get_end())
303+
static func collect_getters_and_setters(text: String) -> Dictionary:
304+
var result := {}
305+
# a valid match has 2 or 4 groups, split into the method names and the rest of the line
306+
# (var example: set = )(example_setter)(, get = )(example_getter)
307+
# if things between the names are empty or commented, exclude them
308+
for mat in regex_getter_setter.search_all(text):
309+
if mat.get_string(1).is_empty() or mat.get_string(1).contains("#"):
310+
continue
311+
result[mat.get_string(2)] = null
323312

324-
return true
313+
if mat.get_string(3).is_empty() or mat.get_string(3).contains("#"):
314+
continue
315+
result[mat.get_string(4)] = null
325316

326-
return false
317+
return result

0 commit comments

Comments
 (0)