makerst: Improve error reporting
- List file names before error descriptions, as is common in linters. - Print the number of errors reported at the end of the list. - Use double quotes instead of single quotes in messages.
This commit is contained in:
parent
83d2673772
commit
f0b860fbad
@ -58,7 +58,7 @@ strings_l10n = {}
|
|||||||
|
|
||||||
def print_error(error, state): # type: (str, State) -> None
|
def print_error(error, state): # type: (str, State) -> None
|
||||||
print("ERROR: {}".format(error))
|
print("ERROR: {}".format(error))
|
||||||
state.errored = True
|
state.num_errors += 1
|
||||||
|
|
||||||
|
|
||||||
class TypeName:
|
class TypeName:
|
||||||
@ -163,8 +163,7 @@ class ClassDef:
|
|||||||
|
|
||||||
class State:
|
class State:
|
||||||
def __init__(self): # type: () -> None
|
def __init__(self): # type: () -> None
|
||||||
# Has any error been reported?
|
self.num_errors = 0
|
||||||
self.errored = False
|
|
||||||
self.classes = OrderedDict() # type: OrderedDict[str, ClassDef]
|
self.classes = OrderedDict() # type: OrderedDict[str, ClassDef]
|
||||||
self.current_class = "" # type: str
|
self.current_class = "" # type: str
|
||||||
|
|
||||||
@ -194,7 +193,7 @@ class State:
|
|||||||
|
|
||||||
property_name = property.attrib["name"]
|
property_name = property.attrib["name"]
|
||||||
if property_name in class_def.properties:
|
if property_name in class_def.properties:
|
||||||
print_error("Duplicate property '{}', file: {}".format(property_name, class_name), self)
|
print_error('{}.xml: Duplicate property "{}".'.format(class_name, property_name), self)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
type_name = TypeName.from_element(property)
|
type_name = TypeName.from_element(property)
|
||||||
@ -305,7 +304,7 @@ class State:
|
|||||||
constant_def = ConstantDef(constant_name, value, constant.text)
|
constant_def = ConstantDef(constant_name, value, constant.text)
|
||||||
if enum is None:
|
if enum is None:
|
||||||
if constant_name in class_def.constants:
|
if constant_name in class_def.constants:
|
||||||
print_error("Duplicate constant '{}', file: {}".format(constant_name, class_name), self)
|
print_error('{}.xml: Duplicate constant "{}".'.format(class_name, constant_name), self)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
class_def.constants[constant_name] = constant_def
|
class_def.constants[constant_name] = constant_def
|
||||||
@ -328,7 +327,7 @@ class State:
|
|||||||
signal_name = signal.attrib["name"]
|
signal_name = signal.attrib["name"]
|
||||||
|
|
||||||
if signal_name in class_def.signals:
|
if signal_name in class_def.signals:
|
||||||
print_error("Duplicate signal '{}', file: {}".format(signal_name, class_name), self)
|
print_error('{}.xml: Duplicate signal "{}".'.format(class_name, signal_name), self)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
params = parse_arguments(signal)
|
params = parse_arguments(signal)
|
||||||
@ -351,8 +350,8 @@ class State:
|
|||||||
theme_item_id = "{}_{}".format(theme_item_data_name, theme_item_name)
|
theme_item_id = "{}_{}".format(theme_item_data_name, theme_item_name)
|
||||||
if theme_item_id in class_def.theme_items:
|
if theme_item_id in class_def.theme_items:
|
||||||
print_error(
|
print_error(
|
||||||
"Duplicate theme property '{}' of type '{}', file: {}".format(
|
'{}.xml: Duplicate theme item "{}" of type "{}".'.format(
|
||||||
theme_item_name, theme_item_data_name, class_name
|
class_name, theme_item_name, theme_item_data_name
|
||||||
),
|
),
|
||||||
self,
|
self,
|
||||||
)
|
)
|
||||||
@ -430,7 +429,7 @@ def main(): # type: () -> None
|
|||||||
if entry.msgid in BASE_STRINGS:
|
if entry.msgid in BASE_STRINGS:
|
||||||
strings_l10n[entry.msgid] = entry.msgstr
|
strings_l10n[entry.msgid] = entry.msgstr
|
||||||
else:
|
else:
|
||||||
print("No PO file at '{}' for language '{}'.".format(lang_file, args.lang))
|
print('No PO file at "{}" for language "{}".'.format(lang_file, args.lang))
|
||||||
|
|
||||||
print("Checking for errors in the XML class reference...")
|
print("Checking for errors in the XML class reference...")
|
||||||
|
|
||||||
@ -453,7 +452,7 @@ def main(): # type: () -> None
|
|||||||
|
|
||||||
elif os.path.isfile(path):
|
elif os.path.isfile(path):
|
||||||
if not path.endswith(".xml"):
|
if not path.endswith(".xml"):
|
||||||
print("Got non-.xml file '{}' in input, skipping.".format(path))
|
print('Got non-.xml file "{}" in input, skipping.'.format(path))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
file_list.append(path)
|
file_list.append(path)
|
||||||
@ -465,17 +464,17 @@ def main(): # type: () -> None
|
|||||||
try:
|
try:
|
||||||
tree = ET.parse(cur_file)
|
tree = ET.parse(cur_file)
|
||||||
except ET.ParseError as e:
|
except ET.ParseError as e:
|
||||||
print_error("Parse error reading file '{}': {}".format(cur_file, e), state)
|
print_error("{}.xml: Parse error while reading the file: {}".format(cur_file, e), state)
|
||||||
continue
|
continue
|
||||||
doc = tree.getroot()
|
doc = tree.getroot()
|
||||||
|
|
||||||
if "version" not in doc.attrib:
|
if "version" not in doc.attrib:
|
||||||
print_error("Version missing from 'doc', file: {}".format(cur_file), state)
|
print_error('{}.xml: "version" attribute missing from "doc".'.format(cur_file), state)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
name = doc.attrib["name"]
|
name = doc.attrib["name"]
|
||||||
if name in classes:
|
if name in classes:
|
||||||
print_error("Duplicate class '{}'".format(name), state)
|
print_error('{}.xml: Duplicate class "{}".'.format(cur_file, name), state)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
classes[name] = (doc, cur_file)
|
classes[name] = (doc, cur_file)
|
||||||
@ -484,7 +483,7 @@ def main(): # type: () -> None
|
|||||||
try:
|
try:
|
||||||
state.parse_class(data[0], data[1])
|
state.parse_class(data[0], data[1])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print_error("Exception while parsing class '{}': {}".format(name, e), state)
|
print_error("{}.xml: Exception while parsing class: {}".format(name, e), state)
|
||||||
|
|
||||||
state.sort_classes()
|
state.sort_classes()
|
||||||
|
|
||||||
@ -499,12 +498,17 @@ def main(): # type: () -> None
|
|||||||
state.current_class = class_name
|
state.current_class = class_name
|
||||||
make_rst_class(class_def, state, args.dry_run, args.output)
|
make_rst_class(class_def, state, args.dry_run, args.output)
|
||||||
|
|
||||||
if not state.errored:
|
if state.num_errors == 0:
|
||||||
print("No errors found.")
|
print("No errors found in the class reference XML.")
|
||||||
if not args.dry_run:
|
if not args.dry_run:
|
||||||
print("Wrote reStructuredText files for each class to: %s" % args.output)
|
print("Wrote reStructuredText files for each class to: %s" % args.output)
|
||||||
else:
|
else:
|
||||||
print("Errors were found in the class reference XML. Please check the messages above.")
|
if state.num_errors >= 2:
|
||||||
|
print(
|
||||||
|
"%d errors were found in the class reference XML. Please check the messages above." % state.num_errors
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print("1 error was found in the class reference XML. Please check the messages above.")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
@ -856,7 +860,7 @@ def escape_rst(text, until_pos=-1): # type: (str) -> str
|
|||||||
def format_codeblock(code_type, post_text, indent_level, state): # types: str, str, int, state
|
def format_codeblock(code_type, post_text, indent_level, state): # types: str, str, int, state
|
||||||
end_pos = post_text.find("[/" + code_type + "]")
|
end_pos = post_text.find("[/" + code_type + "]")
|
||||||
if end_pos == -1:
|
if end_pos == -1:
|
||||||
print_error("[" + code_type + "] without a closing tag, file: {}".format(state.current_class), state)
|
print_error("{}.xml: [" + code_type + "] without a closing tag.".format(state.current_class), state)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
code_text = post_text[len("[" + code_type + "]") : end_pos]
|
code_text = post_text[len("[" + code_type + "]") : end_pos]
|
||||||
@ -875,9 +879,9 @@ def format_codeblock(code_type, post_text, indent_level, state): # types: str,
|
|||||||
|
|
||||||
if to_skip > indent_level:
|
if to_skip > indent_level:
|
||||||
print_error(
|
print_error(
|
||||||
"Four spaces should be used for indentation within ["
|
"{}.xml: Four spaces should be used for indentation within ["
|
||||||
+ code_type
|
+ code_type
|
||||||
+ "], file: {}".format(state.current_class),
|
+ "].".format(state.current_class),
|
||||||
state,
|
state,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -987,7 +991,7 @@ def rstize_text(text, state): # type: (str, State) -> str
|
|||||||
if param.find(".") != -1:
|
if param.find(".") != -1:
|
||||||
ss = param.split(".")
|
ss = param.split(".")
|
||||||
if len(ss) > 2:
|
if len(ss) > 2:
|
||||||
print_error("Bad reference: '{}', file: {}".format(param, state.current_class), state)
|
print_error('{}.xml: Bad reference: "{}".'.format(state.current_class, param), state)
|
||||||
class_param, method_param = ss
|
class_param, method_param = ss
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -1000,33 +1004,31 @@ def rstize_text(text, state): # type: (str, State) -> str
|
|||||||
if cmd.startswith("constructor"):
|
if cmd.startswith("constructor"):
|
||||||
if method_param not in class_def.constructors:
|
if method_param not in class_def.constructors:
|
||||||
print_error(
|
print_error(
|
||||||
"Unresolved constructor '{}', file: {}".format(param, state.current_class), state
|
'{}.xml: Unresolved constructor "{}".'.format(state.current_class, param), state
|
||||||
)
|
)
|
||||||
ref_type = "_constructor"
|
ref_type = "_constructor"
|
||||||
if cmd.startswith("method"):
|
if cmd.startswith("method"):
|
||||||
if method_param not in class_def.methods:
|
if method_param not in class_def.methods:
|
||||||
print_error("Unresolved method '{}', file: {}".format(param, state.current_class), state)
|
print_error('{}.xml: Unresolved method "{}".'.format(state.current_class, param), state)
|
||||||
ref_type = "_method"
|
ref_type = "_method"
|
||||||
if cmd.startswith("operator"):
|
if cmd.startswith("operator"):
|
||||||
if method_param not in class_def.operators:
|
if method_param not in class_def.operators:
|
||||||
print_error("Unresolved operator '{}', file: {}".format(param, state.current_class), state)
|
print_error('{}.xml: Unresolved operator "{}".'.format(state.current_class, param), state)
|
||||||
ref_type = "_operator"
|
ref_type = "_operator"
|
||||||
|
|
||||||
elif cmd.startswith("member"):
|
elif cmd.startswith("member"):
|
||||||
if method_param not in class_def.properties:
|
if method_param not in class_def.properties:
|
||||||
print_error("Unresolved member '{}', file: {}".format(param, state.current_class), state)
|
print_error('{}.xml: Unresolved member "{}".'.format(state.current_class, param), state)
|
||||||
ref_type = "_property"
|
ref_type = "_property"
|
||||||
|
|
||||||
elif cmd.startswith("theme_item"):
|
elif cmd.startswith("theme_item"):
|
||||||
if method_param not in class_def.theme_items:
|
if method_param not in class_def.theme_items:
|
||||||
print_error(
|
print_error('{}.xml: Unresolved theme item "{}".'.format(state.current_class, param), state)
|
||||||
"Unresolved theme item '{}', file: {}".format(param, state.current_class), state
|
|
||||||
)
|
|
||||||
ref_type = "_theme_{}".format(class_def.theme_items[method_param].data_name)
|
ref_type = "_theme_{}".format(class_def.theme_items[method_param].data_name)
|
||||||
|
|
||||||
elif cmd.startswith("signal"):
|
elif cmd.startswith("signal"):
|
||||||
if method_param not in class_def.signals:
|
if method_param not in class_def.signals:
|
||||||
print_error("Unresolved signal '{}', file: {}".format(param, state.current_class), state)
|
print_error('{}.xml: Unresolved signal "{}".'.format(state.current_class, param), state)
|
||||||
ref_type = "_signal"
|
ref_type = "_signal"
|
||||||
|
|
||||||
elif cmd.startswith("constant"):
|
elif cmd.startswith("constant"):
|
||||||
@ -1052,13 +1054,13 @@ def rstize_text(text, state): # type: (str, State) -> str
|
|||||||
break
|
break
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
print_error("Unresolved constant '{}', file: {}".format(param, state.current_class), state)
|
print_error('{}.xml: Unresolved constant "{}".'.format(state.current_class, param), state)
|
||||||
ref_type = "_constant"
|
ref_type = "_constant"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print_error(
|
print_error(
|
||||||
"Unresolved type reference '{}' in method reference '{}', file: {}".format(
|
'{}.xml: Unresolved type reference "{}" in method reference "{}".'.format(
|
||||||
class_param, param, state.current_class
|
state.current_class, class_param, param
|
||||||
),
|
),
|
||||||
state,
|
state,
|
||||||
)
|
)
|
||||||
@ -1078,7 +1080,7 @@ def rstize_text(text, state): # type: (str, State) -> str
|
|||||||
endurl_pos = text.find("[/url]", endq_pos + 1)
|
endurl_pos = text.find("[/url]", endq_pos + 1)
|
||||||
if endurl_pos == -1:
|
if endurl_pos == -1:
|
||||||
print_error(
|
print_error(
|
||||||
"Tag depth mismatch for [url]: no closing [/url], file: {}".format(state.current_class), state
|
"{}.xml: Tag depth mismatch for [url]: no closing [/url]".format(state.current_class), state
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
link_title = text[endq_pos + 1 : endurl_pos]
|
link_title = text[endq_pos + 1 : endurl_pos]
|
||||||
@ -1203,7 +1205,9 @@ def rstize_text(text, state): # type: (str, State) -> str
|
|||||||
previous_pos = pos
|
previous_pos = pos
|
||||||
|
|
||||||
if tag_depth > 0:
|
if tag_depth > 0:
|
||||||
print_error("Tag depth mismatch: too many/little open/close tags, file: {}".format(state.current_class), state)
|
print_error(
|
||||||
|
"{}.xml: Tag depth mismatch: too many (or too little) open/close tags.".format(state.current_class), state
|
||||||
|
)
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
@ -1247,7 +1251,7 @@ def make_type(klass, state): # type: (str, State) -> str
|
|||||||
link_type = link_type[:-2]
|
link_type = link_type[:-2]
|
||||||
if link_type in state.classes:
|
if link_type in state.classes:
|
||||||
return ":ref:`{}<class_{}>`".format(klass, link_type)
|
return ":ref:`{}<class_{}>`".format(klass, link_type)
|
||||||
print_error("Unresolved type '{}', file: {}".format(klass, state.current_class), state)
|
print_error('{}.xml: Unresolved type "{}".'.format(state.current_class, klass), state)
|
||||||
return klass
|
return klass
|
||||||
|
|
||||||
|
|
||||||
@ -1271,7 +1275,7 @@ def make_enum(t, state): # type: (str, State) -> str
|
|||||||
|
|
||||||
# Don't fail for `Vector3.Axis`, as this enum is a special case which is expected not to be resolved.
|
# Don't fail for `Vector3.Axis`, as this enum is a special case which is expected not to be resolved.
|
||||||
if "{}.{}".format(c, e) != "Vector3.Axis":
|
if "{}.{}".format(c, e) != "Vector3.Axis":
|
||||||
print_error("Unresolved enum '{}', file: {}".format(t, state.current_class), state)
|
print_error('{}.xml: Unresolved enum "{}".'.format(state.current_class, t), state)
|
||||||
|
|
||||||
return t
|
return t
|
||||||
|
|
||||||
@ -1429,7 +1433,7 @@ def sanitize_operator_name(dirty_name, state): # type: (str, State) -> str
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
clear_name = "xxx"
|
clear_name = "xxx"
|
||||||
print_error("Unsupported operator type '{}', please add the missing rule.".format(dirty_name), state)
|
print_error('Unsupported operator type "{}", please add the missing rule.'.format(dirty_name), state)
|
||||||
|
|
||||||
return clear_name
|
return clear_name
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user