Support getting line for diagnostic

This commit is contained in:
2019-06-18 17:14:18 +02:00
parent e07d5cb7cb
commit dc35ba4698
4 changed files with 59 additions and 7 deletions

View File

@@ -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;
}
}
}
};
}