detect when a super defined in the schema doesn't exist

Note that this is only detected if the tag referencing the missing super is used in a .cfg file. The super element itself doesn't need to be used for the detection to work.

The schema self validator should already catch this, but it deserves a warning of its own as the schema self validator can be disabled.
This commit is contained in:
Rafael Fillipe Silva 2023-12-20 00:49:00 -03:00 committed by Pentarctagon
parent 40e7dff3ad
commit 4600043492
3 changed files with 35 additions and 2 deletions

View file

@ -390,7 +390,6 @@ void wml_tag::expand(wml_tag& root)
super_refs_.emplace(super, super_tag);
}
}
// TODO: Warn if the super doesn't exist
}
}

View file

@ -153,6 +153,20 @@ static std::string inheritance_cycle_error(const std::string& file,
return ss.str();
}
static std::string missing_super_error(
const std::string& file,
int line,
const std::string& tag,
const std::string& schema_name,
const std::string& super,
bool flag_exception)
{
std::ostringstream ss;
ss << "Super " << super << " not found. Needed by " << tag << "\n" << at(file, line) << "\nwith schema " << schema_name << "\n";
print_output(ss.str(), flag_exception);
return ss.str();
}
static void wrong_path_error(const std::string& file,
int line,
const std::string& tag,
@ -376,6 +390,23 @@ void schema_validator::validate(const config& cfg, const std::string& name, int
derivation_graph_
);
}
// Report missing super
const auto super_expected = utils::split(active.get_super());
for(const auto& expected : super_expected) {
const auto super_exists = std::any_of(
super_tags.begin(),
super_tags.end(),
[&] (const std::pair<std::string, const wml_tag*>& super) {
return super.first == expected;
}
);
if(!super_exists) {
queue_message(cfg, MISSING_SUPER, file, start_line, 0, active_tag_path(), name_, expected);
}
}
}
for(const auto& tag : active.tags(cfg)) {
@ -522,6 +553,9 @@ void schema_validator::print(message_info& el)
case MISSING_KEY:
errors_.emplace_back(missing_key_error(el.file, el.line, el.tag, el.key, create_exceptions_));
break;
case MISSING_SUPER:
errors_.emplace_back(missing_super_error(el.file, el.line, el.tag, el.key, el.value, create_exceptions_));
break;
case SUPER_CYCLE:
errors_.emplace_back(inheritance_cycle_error(el.file, el.line, el.tag, el.key, el.value, create_exceptions_));
break;

View file

@ -83,7 +83,7 @@ private:
protected:
using message_type = int;
enum { WRONG_TAG, EXTRA_TAG, MISSING_TAG, EXTRA_KEY, MISSING_KEY, WRONG_VALUE, SUPER_CYCLE, NEXT_ERROR };
enum { WRONG_TAG, EXTRA_TAG, MISSING_TAG, EXTRA_KEY, MISSING_KEY, WRONG_VALUE, MISSING_SUPER, SUPER_CYCLE, NEXT_ERROR };
/**
* Messages are cached.