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
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user