Figure out whether a warning/error was #include'd or #appendto'd

We already notified the user on warning/error that the mistake
happened in a different script than the one we were currently
compiing. It's not too difficult to figure out whether that other
script was added due to an #include or an #appendto directive, so we
can just show the user which one it is.

We also don't show warnings in #include'd scripts anymore, since
they get compiled individually anyway and all warnings will show up
there. This way we don't duplicate warnings several times.
master
Nicolas Hake 2018-07-24 14:35:12 +02:00
parent 829bb8cb28
commit f5988085a7
3 changed files with 41 additions and 7 deletions

View File

@ -29,6 +29,31 @@
#define C4AUL_SafeInherited "_inherited"
#define C4AUL_DebugBreak "__debugbreak"
namespace
{
enum class ScriptLinkType
{
Include,
Same,
Appendto,
};
}
static ScriptLinkType GetScriptLinkType(const C4ScriptHost *source_host, const C4ScriptHost *target_host)
{
if (source_host == target_host)
return ScriptLinkType::Same;
const auto &sources = target_host->SourceScripts;
const auto source_script_index = std::find(begin(sources), end(sources), source_host);
const auto target_script_index = std::find(begin(sources), end(sources), target_host);
assert(source_script_index != target_script_index);
if (source_script_index < target_script_index)
return ScriptLinkType::Include;
else if (source_script_index > target_script_index)
return ScriptLinkType::Appendto;
return ScriptLinkType::Same;
}
static std::string FormatCodePosition(const C4ScriptHost *source_host, const char *pos, const C4ScriptHost *target_host = nullptr, const C4AulScriptFunc *func = nullptr)
{
std::string s;
@ -48,14 +73,16 @@ static std::string FormatCodePosition(const C4ScriptHost *source_host, const cha
int line = SGetLine(source_host->GetScript(), pos);
int col = SLineGetCharacters(source_host->GetScript(), pos);
s += strprintf("%s:%d:%d)",
source_host->GetFilePath(),
line, col
);
s += strprintf("%s:%d:%d)", source_host->GetFilePath(), line, col);
}
if (target_host && source_host != target_host)
{
s += strprintf(" (as #appendto/#include to %s)", target_host->ScriptName.getData());
assert(source_script_index != target_script_index);
if (GetScriptLinkType(source_host, target_host) == ScriptLinkType::Include)
s += strprintf(" (included by %s)", target_host->ScriptName.getData());
else
s += strprintf(" (appended to %s)", target_host->ScriptName.getData());
}
return s;
}
@ -74,6 +101,12 @@ static void Warn(const C4ScriptHost *target_host, const C4ScriptHost *host, cons
#include "C4AulWarnings.h"
#undef DIAG
}
else if (target_host && GetScriptLinkType(host, target_host) == ScriptLinkType::Include)
{
// Don't re-emit warnings for an #include'd script, they've already
// been shown when the original script was compiled
return;
}
else if (!host->IsWarningEnabled(SPos, warning))
{
return;

View File

@ -106,7 +106,7 @@ bool C4ScriptHost::ResolveIncludes(C4DefList *rDefs)
if (!Def->Script.ResolveIncludes(rDefs))
continue; // skip this #include
for (std::list<C4ScriptHost *>::reverse_iterator s = Def->Script.SourceScripts.rbegin(); s != Def->Script.SourceScripts.rend(); ++s)
for (auto s = Def->Script.SourceScripts.rbegin(); s != Def->Script.SourceScripts.rend(); ++s)
{
if (std::find(SourceScripts.begin(), SourceScripts.end(), *s) == SourceScripts.end())
SourceScripts.push_front(*s);

View File

@ -25,6 +25,7 @@
#include "script/C4AulAST.h"
#include <bitset>
#include <deque>
// aul script state
enum C4AulScriptState
@ -53,7 +54,7 @@ public:
bool IsReady() { return State == ASS_PARSED; } // whether script calls may be done
// Translate a string using the script's lang table
std::string Translate(const std::string &text) const;
std::list<C4ScriptHost *> SourceScripts;
std::deque<C4ScriptHost *> SourceScripts;
StdCopyStrBuf ScriptName; // script name
bool IsWarningEnabled(const char *pos, C4AulWarningId warning) const;