-
-
Notifications
You must be signed in to change notification settings - Fork 183
/
Copy pathScriptError.gd
113 lines (91 loc) · 3.01 KB
/
ScriptError.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Represents a Script error.
#
# Mirrors the JSON structure of the language server, with the notable exception
# of `error_range` instead of `range` ("range" is a reserved word in GDScript).
#
# Use it like so:
#
# var error = ScriptError.new()
# error.from_JSON(json_error)
class_name ScriptError
extends Reference
var error_range := ErrorRange.new()
var message := ""
var severity := 0
var code := 0
func from_JSON(json: Dictionary) -> void:
if "message" in json:
message = String(json.message)
if "range" in json:
error_range.from_JSON(json.range)
if "severity" in json:
severity = int(json.severity)
if "code" in json:
code = _improve_error_code(json.code, message)
func _improve_error_code(raw_code: int, raw_message: String) -> int:
# If the code has a valid value, just use it.
if not raw_code == -1:
return raw_code
# But if it's -1, try to remap the message to a new code using the GDScript codes database.
var remapped_code := -1
# Iterate through every record to find the one that has a matching pattern.
for record in GDScriptCodes.MESSAGE_DATABASE:
# First check if the record has a valid structure, just in case.
if not typeof(record) == TYPE_DICTIONARY:
continue
if not record.has("patterns") or not record.has("code"):
continue
if not typeof(record.patterns) == TYPE_ARRAY or not typeof(record.code) == TYPE_INT:
continue
# Iterate through an array of match patterns to see if any of them matches our message
# completely.
var matched = false
for pattern in record.patterns:
# Pattern must be an array of strings.
if not typeof(pattern) == TYPE_ARRAY:
continue
# We'll be modifying the message here, so copy it.
var curr_message = raw_message
# Pattern's substrings must match the target message in order.
for i in pattern.size():
# If the substring does not match, exit early, this is not our match.
var substring := pattern[i] as String
var found = curr_message.find(substring)
if found == -1:
break
# Cut a part of the message that we have already matched to exclude it from
# further checks.
curr_message = curr_message.substr(found)
i += 1
# We reached the end of the pattern without errors, so this is our match.
if i >= pattern.size():
matched = true
break
if matched:
break
if matched:
remapped_code = record.code
break
return remapped_code
func _to_string() -> String:
return "{ERR (%s:%s): %s}" % [code, error_range, message]
class ErrorRange:
var start := ErrorPosition.new()
var end := ErrorPosition.new()
func from_JSON(json: Dictionary) -> void:
if "start" in json:
start.from_JSON(json.start)
if "end" in json:
end.from_JSON(json.end)
func _to_string() -> String:
return "[%s-%s]" % [start, end]
class ErrorPosition:
var character := 0
var line := 0
func from_JSON(json: Dictionary) -> void:
if "character" in json:
character = int(json.character)
if "line" in json:
line = int(json.line)
func _to_string() -> String:
return "(%s:%s)" % [line, character]