From f5988085a75ccf7ea5503db64262372a04aabd3a Mon Sep 17 00:00:00 2001 From: Nicolas Hake Date: Tue, 24 Jul 2018 14:35:12 +0200 Subject: [PATCH] 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. --- src/script/C4AulCompiler.cpp | 43 +++++++++++++++++++++++++++++++----- src/script/C4AulLink.cpp | 2 +- src/script/C4ScriptHost.h | 3 ++- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/script/C4AulCompiler.cpp b/src/script/C4AulCompiler.cpp index c4c734663..cc974cdad 100644 --- a/src/script/C4AulCompiler.cpp +++ b/src/script/C4AulCompiler.cpp @@ -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; diff --git a/src/script/C4AulLink.cpp b/src/script/C4AulLink.cpp index 03cda04f0..adc0cf121 100644 --- a/src/script/C4AulLink.cpp +++ b/src/script/C4AulLink.cpp @@ -106,7 +106,7 @@ bool C4ScriptHost::ResolveIncludes(C4DefList *rDefs) if (!Def->Script.ResolveIncludes(rDefs)) continue; // skip this #include - for (std::list::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); diff --git a/src/script/C4ScriptHost.h b/src/script/C4ScriptHost.h index d41358d68..d4d535caa 100644 --- a/src/script/C4ScriptHost.h +++ b/src/script/C4ScriptHost.h @@ -25,6 +25,7 @@ #include "script/C4AulAST.h" #include +#include // 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 SourceScripts; + std::deque SourceScripts; StdCopyStrBuf ScriptName; // script name bool IsWarningEnabled(const char *pos, C4AulWarningId warning) const;