Rework text spans a bit to include script file, make binder log an error when two classes have a circular value reference.
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2021-01-09 13:20:56 +01:00
parent 8660933f27
commit 59af34fac9
16 changed files with 432 additions and 267 deletions

View File

@@ -66,7 +66,7 @@ namespace MalachScript::Binder {
break;
}
type = new BoundType(identifier, s->GetClassAttr());
type = new BoundType(identifier, s->GetClassAttr(), s->GetSpan());
if (activeType.has_value()) {
activeType.value()->RegisterType(identifier, type.value());
} else {
@@ -210,9 +210,39 @@ namespace MalachScript::Binder {
}
}
static void FinaliseType(BoundType* type, std::vector<const BoundType*>& stack, const Binder::log_func& log) {
if (type->IsInitialised()) {
return;
}
if (std::find(stack.begin(), stack.end(), type) != stack.end()) {
log(Diagnostics::DiagnosticLevel::Error, Diagnostics::DiagnosticType::CircularTypeReference,
type->GetSpan().value(),
{stack[stack.size() - 1]->GetIdentifier().GetStdString(), type->GetIdentifier().GetStdString()});
return;
}
stack.push_back(type);
size_t size = 0;
for (auto& inherits : type->GetInherits()) {
if (!inherits->IsInitialised()) {
FinaliseType(const_cast<BoundType*>(inherits), stack, log);
}
size += inherits->GetSize();
}
for (auto& field : type->GetFieldsLookup()) {
if (!field.second->GetType()->IsInitialised()) {
FinaliseType(const_cast<BoundType*>(field.second->GetType()), stack, log);
}
size += field.second->GetType()->GetSize();
}
stack.pop_back();
type->Finalise(size);
}
static void FinaliseNamespace(BoundNamespace* ns, const Binder::log_func& log) {
std::vector<const BoundType*> s = {};
for (const auto& t : ns->GetTypes()) {
t.second->Finalise();
FinaliseType(t.second, s, log);
}
for (const auto& n : ns->GetNamespaces()) {
FinaliseNamespace(n.second, log);