Browse Source

second error location

cl-refactor
yann300 10 years ago
parent
commit
798012bfc8
  1. 35
      mix/CodeModel.cpp
  2. 3
      mix/CodeModel.h
  3. 2
      mix/qml/CodeEditorView.qml
  4. 21
      mix/qml/WebCodeEditor.qml
  5. 26
      mix/qml/html/cm/errorannotation.js
  6. 2
      mix/qml/html/cm/solidityToken.js
  7. 43
      mix/qml/html/codeeditor.js

35
mix/CodeModel.cpp

@ -309,24 +309,37 @@ void CodeModel::runCompilationJob(int _jobId)
}
catch (dev::Exception const& _exception)
{
std::ostringstream error;
std::stringstream error;
solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", cs);
QString message = QString::fromStdString(error.str());
QString sourceName;
if (SourceLocation const* location = boost::get_error_info<solidity::errinfo_sourceLocation>(_exception))
{
if (location->sourceName)
sourceName = QString::fromStdString(*location->sourceName);
if (!sourceName.isEmpty())
if (CompiledContract* contract = contractByDocumentId(sourceName))
message = message.replace(sourceName, contract->contract()->name()); //substitute the location to match our contract names
}
compilationError(message, sourceName);
QVariantMap firstLocation;
QVariantMap secondLocation;
if (SourceLocation const* first = boost::get_error_info<solidity::errinfo_sourceLocation>(_exception))
firstLocation = resolveCompilationErrorLocation(cs, *first);
if (SecondarySourceLocation const* second = boost::get_error_info<solidity::errinfo_secondarySourceLocation>(_exception))
secondLocation = resolveCompilationErrorLocation(cs, second->infos.front().second);
compilationError(message, firstLocation, secondLocation);
}
m_compiling = false;
emit stateChanged();
}
QVariantMap CodeModel::resolveCompilationErrorLocation(CompilerStack const& _compiler, SourceLocation const& _location)
{
std::tuple<int, int, int, int> pos = _compiler.positionFromSourceLocation(_location);
QVariantMap startError;
startError.insert("line", std::get<0>(pos) - 1);
startError.insert("column", std::get<1>(pos) - 1);
QVariantMap endError;
endError.insert("line", std::get<2>(pos) - 1);
endError.insert("column", std::get<3>(pos) - 1);
QVariantMap error;
error.insert("start", startError);
error.insert("end", endError);
error.insert("source", QString::fromStdString(*_location.sourceName));
return error;
}
void CodeModel::collectContracts(dev::solidity::CompilerStack const& _cs, std::vector<std::string> const& _sourceNames)
{
Guard pl(x_pendingContracts);

3
mix/CodeModel.h

@ -175,7 +175,7 @@ signals:
/// Emitted on compilation complete
void compilationComplete();
/// Emitted on compilation error
void compilationError(QString _error, QString _sourceName);
void compilationError(QString _error, QVariantMap _firstErrorLoc, QVariantMap _secondErrorLoc);
/// Internal signal used to transfer compilation job to background thread
void scheduleCompilationJob(int _jobId);
/// Emitted if there are any changes in the code model
@ -198,6 +198,7 @@ private:
void stop();
void releaseContracts();
void collectContracts(dev::solidity::CompilerStack const& _cs, std::vector<std::string> const& _sourceNames);
QVariantMap resolveCompilationErrorLocation(dev::solidity::CompilerStack const& _cs, dev::SourceLocation const& _location);
std::atomic<bool> m_compiling;
mutable dev::Mutex x_contractMap;

2
mix/qml/CodeEditorView.qml

@ -173,7 +173,7 @@ Item {
Connections {
target: codeModel
onCompilationError: {
sourceInError = _sourceName;
sourceInError = _firstErrorLoc.source;
}
onCompilationComplete: {
sourceInError = "";

21
mix/qml/WebCodeEditor.qml

@ -137,17 +137,28 @@ Item {
editorBrowser.runJavaScript("compilationComplete()", function(result) { });
}
function compilationError(error, sourceName)
function compilationError(error, firstLocation, secondLocation)
{
if (sourceName !== parent.sourceName)
console.log("current " + parent.sourceName);
console.log("source " + firstLocation.source);
if (firstLocation.source !== parent.sourceName && secondLocation.source !== parent.sourceName)
return;
if (!editorBrowser || !error)
return;
var errorInfo = ErrorLocationFormater.extractErrorInfo(error, false);
if (errorInfo.line && errorInfo.column)
editorBrowser.runJavaScript("compilationError('" + errorInfo.line + "', '" + errorInfo.column + "', '" + errorInfo.errorDetail + "')", function(result) { });
if (firstLocation.start.line)
{
var detail = error.split('\n')[0];
var reg = detail.match(/:\d+:\d+:/g);
if (reg !== null)
detail = detail.replace(reg[0], "");
editorBrowser.runJavaScript("compilationError('" + JSON.stringify(firstLocation) + "', '" + JSON.stringify(secondLocation) + "', '" + detail + "')", function(result){});
}
else
{
console.log("e d qml");
editorBrowser.runJavaScript("compilationComplete()", function(result) { });
}
}
Timer

26
mix/qml/html/cm/errorannotation.js

@ -1,42 +1,39 @@
function ErrorAnnotation(editor, line, column, content)
function ErrorAnnotation(editor, location, content)
{
this.location = JSON.parse(location);
this.opened = false;
this.line = line;
this.column = column;
this.rawContent = content;
this.content = content.replace("Contract Error:", "");
this.editor = editor;
this.errorMark = null;
this.lineWidget = null;
this.init();
this.open();
if (this.content)
this.open();
}
ErrorAnnotation.prototype.init = function()
{
var separators = [';', ',', '\\\(', '\\\{', '\\\}', '\\\)', ':'];
var errorPart = editor.getLine(this.line).substring(this.column);
var incrMark = this.column + errorPart.split(new RegExp(separators.join('|'), 'g'))[0].length;
if (incrMark === this.column)
incrMark = this.column + 1;
this.errorMark = editor.markText({ line: this.line, ch: this.column }, { line: this.line, ch: incrMark }, { className: "CodeMirror-errorannotation", inclusiveRight: true });
this.errorMark = editor.markText({ line: this.location.start.line, ch: this.location.start.column }, { line: this.location.end.line, ch: this.location.end.column }, { className: "CodeMirror-errorannotation", inclusiveRight: true });
}
ErrorAnnotation.prototype.open = function()
{
if (this.line)
if (this.location.start.line)
{
var node = document.createElement("div");
node.id = "annotation"
node.innerHTML = this.content;
node.className = "CodeMirror-errorannotation-context";
this.lineWidget = this.editor.addLineWidget(this.line, node, { coverGutter: false });
this.lineWidget = this.editor.addLineWidget(this.location.start.line, node, { coverGutter: false });
this.opened = true;
}
}
ErrorAnnotation.prototype.close = function()
{
this.lineWidget.clear();
if (this.lineWidget)
this.lineWidget.clear();
this.opened = false;
}
@ -47,3 +44,6 @@ ErrorAnnotation.prototype.destroy = function()
if (this.errorMark)
this.errorMark.clear();
}

2
mix/qml/html/cm/solidityToken.js

@ -5,7 +5,7 @@ function solCurrency()
function solKeywords()
{
return { "break": true, "case": true, "constant": true, "continue": true, "contract": true, "default": true, "do": true, "else": true, "event": true, "external": true, "is": true, "indexed": true, "for": true, "function": true, "if": true, "import": true, "mapping": true, "modifier": true, "new": true, "public": true, "private": true, "internal": true, "return": true, "returns": true, "struct": true, "switch": true, "var": true, "while": true, "enum": true };
return { "delete": true, "break": true, "case": true, "constant": true, "continue": true, "contract": true, "default": true, "do": true, "else": true, "event": true, "external": true, "is": true, "indexed": true, "for": true, "function": true, "if": true, "import": true, "mapping": true, "modifier": true, "new": true, "public": true, "private": true, "internal": true, "return": true, "returns": true, "struct": true, "switch": true, "var": true, "while": true, "enum": true };
}
function solStdContract()

43
mix/qml/html/codeeditor.js

@ -158,30 +158,43 @@ showWarning = function(content)
}
var annotation = null;
var secondaryAnnotation = null;
var compilationCompleteBool = true;
compilationError = function(line, column, content)
compilationError = function(location, secondLocation, error)
{
compilationCompleteBool = false;
window.setTimeout(function(){
if (compilationCompleteBool)
return;
line = parseInt(line);
column = parseInt(column);
if (line > 0)
line = line - 1;
if (column > 0)
column = column - 1;
var loc = JSON.parse(location);
if (annotation == null)
annotation = new ErrorAnnotation(editor, line, column, content);
else if (annotation.line !== line || annotation.column !== column || annotation.content !== content)
{
annotation = new ErrorAnnotation(editor, location, error);
if (secondLocation.start)
secondaryAnnotation = new ErrorAnnotation(editor, secondLocation, "");
}
else if (annotation.location.start.line !== loc.start.line || annotation.location.start.column !== loc.start.column || annotation.rawContent !== error)
{
annotation.destroy();
annotation = new ErrorAnnotation(editor, line, column, content);
annotation = new ErrorAnnotation(editor, location, error);
if (secondaryAnnotation)
secondaryAnnotation.destroy();
secondaryAnnotation = new ErrorAnnotation(editor, secondLocation, "");
}
}, 500)
}
formatSource = function(line, column)
{
line = parseInt(line);
column = parseInt(column);
if (line > 0)
line = line - 1;
if (column > 0)
column = column - 1;
}
compilationComplete = function()
{
if (annotation !== null)
@ -189,12 +202,20 @@ compilationComplete = function()
annotation.destroy();
annotation = null;
}
if (secondaryAnnotation !== null)
{
secondaryAnnotation.destroy();
secondaryAnnotation = null;
}
compilationCompleteBool = true;
console.log("end");
}
goToCompilationError = function()
{
editor.setCursor(annotation.line, annotation.column)
editor.setCursor(annotation.start.line, annotation.start.column)
}
setFontSize = function(size)

Loading…
Cancel
Save