Support getting line for diagnostic
This commit is contained in:
parent
e07d5cb7cb
commit
dc35ba4698
|
@ -3,6 +3,7 @@
|
|||
#define PORYGONLANG_DIAGNOSTICSHOLDER_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "DiagnosticSeverity.hpp"
|
||||
#include "DiagnosticCode.hpp"
|
||||
#include "Diagnostic.hpp"
|
||||
|
@ -13,9 +14,21 @@ namespace Porygon::Diagnostics {
|
|||
class DiagnosticsHolder {
|
||||
bool _hasErrors;
|
||||
vector<Diagnostic> _diagnostics;
|
||||
vector<size_t> _lineStarts;
|
||||
vector<size_t> _lineLength;
|
||||
public:
|
||||
DiagnosticsHolder() {
|
||||
explicit DiagnosticsHolder(const u16string& str) {
|
||||
_hasErrors = false;
|
||||
_lineStarts = vector<size_t>{0};
|
||||
size_t lineLength = 0;
|
||||
for (size_t i = 0; i < str.size(); i++){
|
||||
lineLength++;
|
||||
if (str[i] == '\n'){
|
||||
_lineStarts.push_back(i + 1);
|
||||
_lineLength.push_back(lineLength);
|
||||
lineLength = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~DiagnosticsHolder() {
|
||||
|
@ -37,6 +50,29 @@ namespace Porygon::Diagnostics {
|
|||
int DiagnosticsCount();
|
||||
|
||||
Diagnostic *GetDiagnosticAt(int position);
|
||||
|
||||
size_t GetLineFromPosition(size_t i){
|
||||
size_t topLimit = _lineStarts.size() - 1;
|
||||
size_t bottomLimit = 0;
|
||||
while (true){
|
||||
if (bottomLimit == topLimit){
|
||||
return bottomLimit;
|
||||
}
|
||||
size_t half = (topLimit - bottomLimit) / 2;
|
||||
size_t pos = _lineStarts[half];
|
||||
size_t length = _lineLength[half];
|
||||
if (pos < i && pos + length > i){
|
||||
return half;
|
||||
}
|
||||
if (pos > i){
|
||||
bottomLimit = half;
|
||||
} else if (pos < i){
|
||||
topLimit = half;
|
||||
} else{
|
||||
return half;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
#include "Binder/Binder.hpp"
|
||||
|
||||
Porygon::Script* Porygon::Script::Create(const u16string& script) {
|
||||
auto s = new Script();
|
||||
s -> Parse(script);
|
||||
return s;
|
||||
return new Script(script);
|
||||
}
|
||||
|
||||
std::u16string To_UTF16(const string &s)
|
||||
|
@ -24,11 +22,13 @@ Porygon::Script *Porygon::Script::Create(const string &script) {
|
|||
return Script::Create(To_UTF16(script));
|
||||
}
|
||||
|
||||
Porygon::Script::Script() {
|
||||
Diagnostics = new Diagnostics::DiagnosticsHolder();
|
||||
Porygon::Script::Script(const u16string& s) {
|
||||
Diagnostics = new Diagnostics::DiagnosticsHolder(s);
|
||||
_boundScript = nullptr;
|
||||
_scriptVariables = new unordered_map<uint32_t, shared_ptr<EvalValue>>(0);
|
||||
_evaluator = new Evaluator(this -> _scriptVariables);
|
||||
|
||||
this -> Parse(s);
|
||||
}
|
||||
|
||||
EvalValue* Porygon::Script::Evaluate() {
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Porygon{
|
|||
Binder::BoundScriptStatement* _boundScript;
|
||||
shared_ptr<ScriptType> _returnType;
|
||||
|
||||
explicit Script();
|
||||
explicit Script(const u16string&);
|
||||
void Parse(const u16string& script);
|
||||
public:
|
||||
static Script* Create(const u16string& script);
|
||||
|
|
|
@ -23,8 +23,24 @@ TEST_CASE( "Diagnostic invalid token", "[integration]" ) {
|
|||
CHECK(diags[0].GetCode() == Diagnostics::DiagnosticCode::UnexpectedToken);
|
||||
CHECK(diags[0].GetStartPosition() == 3);
|
||||
CHECK(diags[0].GetLength() == 1);
|
||||
CHECK(script->Diagnostics->GetLineFromPosition(diags[0].GetStartPosition()) == 0);
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "Get diagnostic line", "[integration]" ) {
|
||||
auto script = Script::Create(uR"(
|
||||
1 +/ 1
|
||||
)");
|
||||
REQUIRE(script->Diagnostics -> HasErrors());
|
||||
auto diags = script->Diagnostics -> GetDiagnostics();
|
||||
REQUIRE(diags.size() == 1);
|
||||
CHECK(diags[0].GetCode() == Diagnostics::DiagnosticCode::UnexpectedToken);
|
||||
CHECK(diags[0].GetStartPosition() == 4);
|
||||
CHECK(diags[0].GetLength() == 1);
|
||||
CHECK(script->Diagnostics->GetLineFromPosition(diags[0].GetStartPosition()) == 1);
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue