From 798012bfc89cf0e5806824b6253065e63ee3dfb1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 18 May 2015 17:02:54 +0200 Subject: [PATCH 1/5] second error location --- mix/CodeModel.cpp | 35 ++++++++++++++++-------- mix/CodeModel.h | 3 ++- mix/qml/CodeEditorView.qml | 2 +- mix/qml/WebCodeEditor.qml | 21 +++++++++++---- mix/qml/html/cm/errorannotation.js | 26 +++++++++--------- mix/qml/html/cm/solidityToken.js | 2 +- mix/qml/html/codeeditor.js | 43 ++++++++++++++++++++++-------- 7 files changed, 89 insertions(+), 43 deletions(-) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 5c6ec07c0..82f9291df 100644 --- a/mix/CodeModel.cpp +++ b/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(_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(_exception)) + firstLocation = resolveCompilationErrorLocation(cs, *first); + if (SecondarySourceLocation const* second = boost::get_error_info(_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 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 const& _sourceNames) { Guard pl(x_pendingContracts); diff --git a/mix/CodeModel.h b/mix/CodeModel.h index a0b03951f..05d013f9a 100644 --- a/mix/CodeModel.h +++ b/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 const& _sourceNames); + QVariantMap resolveCompilationErrorLocation(dev::solidity::CompilerStack const& _cs, dev::SourceLocation const& _location); std::atomic m_compiling; mutable dev::Mutex x_contractMap; diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index bb7e203bf..8ebb7319f 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -173,7 +173,7 @@ Item { Connections { target: codeModel onCompilationError: { - sourceInError = _sourceName; + sourceInError = _firstErrorLoc.source; } onCompilationComplete: { sourceInError = ""; diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index 38f2327b1..49a0576cc 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/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 diff --git a/mix/qml/html/cm/errorannotation.js b/mix/qml/html/cm/errorannotation.js index 071f0e0d8..f5266d4dc 100644 --- a/mix/qml/html/cm/errorannotation.js +++ b/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(); } + + + diff --git a/mix/qml/html/cm/solidityToken.js b/mix/qml/html/cm/solidityToken.js index d8e588a10..d803697cb 100644 --- a/mix/qml/html/cm/solidityToken.js +++ b/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() diff --git a/mix/qml/html/codeeditor.js b/mix/qml/html/codeeditor.js index d25fbd091..4c8af5888 100644 --- a/mix/qml/html/codeeditor.js +++ b/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) From 352ec1153632903f7c0396f8e32403060fbcf536 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 18 May 2015 19:28:31 +0200 Subject: [PATCH 2/5] add list of second errorannotation instead of single item. --- mix/CodeModel.cpp | 9 ++-- mix/CodeModel.h | 2 +- mix/qml/CodeEditorView.qml | 2 +- mix/qml/WebCodeEditor.qml | 38 ++++++++------- mix/qml/html/cm/errorannotation.js | 2 +- mix/qml/html/codeeditor.js | 75 ++++++++++++------------------ test/libethereum/stateOriginal.cpp | 2 +- 7 files changed, 61 insertions(+), 69 deletions(-) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 82f9291df..769497dcd 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -313,12 +313,15 @@ void CodeModel::runCompilationJob(int _jobId) solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", cs); QString message = QString::fromStdString(error.str()); QVariantMap firstLocation; - QVariantMap secondLocation; + QVariantList secondLocations; if (SourceLocation const* first = boost::get_error_info(_exception)) firstLocation = resolveCompilationErrorLocation(cs, *first); if (SecondarySourceLocation const* second = boost::get_error_info(_exception)) - secondLocation = resolveCompilationErrorLocation(cs, second->infos.front().second); - compilationError(message, firstLocation, secondLocation); + { + for (auto const& c: second->infos) + secondLocations.push_back(resolveCompilationErrorLocation(cs, c.second)); + } + compilationError(message, firstLocation, secondLocations); } m_compiling = false; emit stateChanged(); diff --git a/mix/CodeModel.h b/mix/CodeModel.h index 05d013f9a..2510b4248 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -175,7 +175,7 @@ signals: /// Emitted on compilation complete void compilationComplete(); /// Emitted on compilation error - void compilationError(QString _error, QVariantMap _firstErrorLoc, QVariantMap _secondErrorLoc); + void compilationError(QString _error, QVariantMap _firstErrorLoc, QVariantList _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 diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 8ebb7319f..1a5e3f0f8 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -74,7 +74,7 @@ Item { }); } editor.document = document; - editor.sourceName = document.documentId; + editor.setSourceName(document.documentId); editor.setFontSize(editorSettings.fontSize); editor.setText(data, document.syntaxMode); editor.changeGeneration(); diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index 49a0576cc..af3eda094 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/mix/qml/WebCodeEditor.qml @@ -83,6 +83,13 @@ Item { editorBrowser.runJavaScript("setFontSize(" + size + ")", function(result) {}); } + function setSourceName(sourceName) + { + sourceName = sourceName; + if (initialized && editorBrowser) + editorBrowser.runJavaScript("setSourceName('" + sourceName + "')", function(result) {}); + } + Clipboard { id: clipboard @@ -137,28 +144,23 @@ Item { editorBrowser.runJavaScript("compilationComplete()", function(result) { }); } - function compilationError(error, firstLocation, secondLocation) + function compilationError(error, firstLocation, secondLocations) { - console.log("current " + parent.sourceName); - console.log("source " + firstLocation.source); - if (firstLocation.source !== parent.sourceName && secondLocation.source !== parent.sourceName) - return; if (!editorBrowser || !error) return; - 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) { }); - } + var detail = error.split('\n')[0]; + var reg = detail.match(/:\d+:\d+:/g); + if (reg !== null) + detail = detail.replace(reg[0], ""); + displayErrorAnnotations(firstLocation, detail, "first"); + for (var k in secondLocations) + displayErrorAnnotations(secondLocations[k], detail, "second"); + } + function displayErrorAnnotations(location, detail, type) + { + //if (location.source === parent.sourceName) + editorBrowser.runJavaScript("compilationError('" + JSON.stringify(location) + "', '" + detail + "', '" + type + "')", function(result){}); } Timer diff --git a/mix/qml/html/cm/errorannotation.js b/mix/qml/html/cm/errorannotation.js index f5266d4dc..a8cdb6fe6 100644 --- a/mix/qml/html/cm/errorannotation.js +++ b/mix/qml/html/cm/errorannotation.js @@ -1,6 +1,6 @@ function ErrorAnnotation(editor, location, content) { - this.location = JSON.parse(location); + this.location = location; this.opened = false; this.rawContent = content; this.content = content.replace("Contract Error:", ""); diff --git a/mix/qml/html/codeeditor.js b/mix/qml/html/codeeditor.js index 4c8af5888..4cf443b72 100644 --- a/mix/qml/html/codeeditor.js +++ b/mix/qml/html/codeeditor.js @@ -8,6 +8,7 @@ var editor = CodeMirror(document.body, { styleSelectedText: true }); var ternServer; +var sourceName = ""; editor.setOption("theme", "inkpot"); editor.setOption("indentUnit", 4); @@ -157,65 +158,46 @@ showWarning = function(content) debugWarning = editor.addLineWidget(0, node, { coverGutter: false, above: true }); } -var annotation = null; -var secondaryAnnotation = null; +var annotations = []; var compilationCompleteBool = true; -compilationError = function(location, secondLocation, error) +compilationError = function(location, error, type) { compilationCompleteBool = false; - window.setTimeout(function(){ - if (compilationCompleteBool) - return; - - var loc = JSON.parse(location); - if (annotation == null) - { - 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, location, error); - if (secondaryAnnotation) - secondaryAnnotation.destroy(); - secondaryAnnotation = new ErrorAnnotation(editor, secondLocation, ""); - } - }, 500) + if (compilationCompleteBool) + return; + location = JSON.parse(location); + if (location.start.line) + ensureAnnotation(location, error, type); } -formatSource = function(line, column) +ensureAnnotation = function(location, error, type) { - line = parseInt(line); - column = parseInt(column); - if (line > 0) - line = line - 1; - if (column > 0) - column = column - 1; + for (var k in annotations) + { + if (annotations[k].annotation.location.start.line === location.start.line) + { + annotations[k].annotation.destroy(); + annotations.splice(k, 1); + break; + } + } + if (type === "second") + error = ""; + annotations.push({ "type": type, "annotation": new ErrorAnnotation(editor, location, error)}); } compilationComplete = function() { - if (annotation !== null) - { - annotation.destroy(); - annotation = null; - } - - if (secondaryAnnotation !== null) - { - secondaryAnnotation.destroy(); - secondaryAnnotation = null; - } - + for (var k in annotations) + annotations[k].annotation.destroy(); + annotations.length = 0; compilationCompleteBool = true; - console.log("end"); } goToCompilationError = function() { - editor.setCursor(annotation.start.line, annotation.start.column) + if (annotations.length > 0) + editor.setCursor(annotations[0].annotation.location.start.line, annotations[0].annotation.location.start.column) } setFontSize = function(size) @@ -224,5 +206,10 @@ setFontSize = function(size) editor.refresh(); } +setSourceName = function(_sourceName) +{ + sourceName = _sourceName; +} + editor.setOption("extraKeys", extraKeys); diff --git a/test/libethereum/stateOriginal.cpp b/test/libethereum/stateOriginal.cpp index 82d6288d6..bad0cf223 100644 --- a/test/libethereum/stateOriginal.cpp +++ b/test/libethereum/stateOriginal.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +//#include #include #include "../TestHelper.h" using namespace std; From babebadc29f217033aca52bee78cf5af46290997 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 19 May 2015 10:33:56 +0200 Subject: [PATCH 3/5] replace sourceNamne by contractName --- mix/CodeModel.cpp | 87 +++++++++++++++++++++------------------ mix/qml/WebCodeEditor.qml | 21 +++++++--- 2 files changed, 62 insertions(+), 46 deletions(-) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 769497dcd..9875ee1aa 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -45,7 +45,7 @@ using namespace dev::mix; const std::set c_predefinedContracts = - { "Config", "Coin", "CoinReg", "coin", "service", "owned", "mortal", "NameReg", "named", "std", "configUser" }; +{ "Config", "Coin", "CoinReg", "coin", "service", "owned", "mortal", "NameReg", "named", "std", "configUser" }; namespace @@ -56,7 +56,7 @@ class CollectLocalsVisitor: public ASTConstVisitor { public: CollectLocalsVisitor(QHash* _locals): - m_locals(_locals), m_functionScope(false) {} + m_locals(_locals), m_functionScope(false) {} private: LocationPair nodeLocation(ASTNode const& _node) @@ -96,7 +96,7 @@ class CollectLocationsVisitor: public ASTConstVisitor { public: CollectLocationsVisitor(SourceMap* _sourceMap): - m_sourceMap(_sourceMap) {} + m_sourceMap(_sourceMap) {} private: LocationPair nodeLocation(ASTNode const& _node) @@ -339,7 +339,14 @@ QVariantMap CodeModel::resolveCompilationErrorLocation(CompilerStack const& _com QVariantMap error; error.insert("start", startError); error.insert("end", endError); - error.insert("source", QString::fromStdString(*_location.sourceName)); + QString sourceName; + if (_location.sourceName) + sourceName = QString::fromStdString(*_location.sourceName); + error.insert("source", sourceName); + if (!sourceName.isEmpty()) + if (CompiledContract* contract = contractByDocumentId(sourceName)) + sourceName = contract->contract()->name(); //substitute the location to match our contract names + error.insert("contractName", sourceName); return error; } @@ -385,7 +392,7 @@ void CodeModel::collectContracts(dev::solidity::CompilerStack const& _cs, std::v { //make sure there are no other contracts in the same source, otherwise it is not a rename if (!std::any_of(result.begin(),result.end(), [=](ContractMap::const_iterator::value_type _v) { return _v != contract && _v->documentId() == contract->documentId(); })) - prevContract = c.value(); + prevContract = c.value(); } } if (prevContract != nullptr && prevContract->contractInterface() != result[name]->contractInterface()) @@ -435,59 +442,59 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) switch (_type->getCategory()) { case Type::Category::Integer: - { - IntegerType const* it = dynamic_cast(_type); - r.size = it->getNumBits() / 8; - r.type = it->isAddress() ? SolidityType::Type::Address : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger; - } + { + IntegerType const* it = dynamic_cast(_type); + r.size = it->getNumBits() / 8; + r.type = it->isAddress() ? SolidityType::Type::Address : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger; + } break; case Type::Category::Bool: r.type = SolidityType::Type::Bool; break; case Type::Category::FixedBytes: - { - FixedBytesType const* b = dynamic_cast(_type); - r.type = SolidityType::Type::Bytes; - r.size = static_cast(b->getNumBytes()); - } + { + FixedBytesType const* b = dynamic_cast(_type); + r.type = SolidityType::Type::Bytes; + r.size = static_cast(b->getNumBytes()); + } break; case Type::Category::Contract: r.type = SolidityType::Type::Address; break; case Type::Category::Array: + { + ArrayType const* array = dynamic_cast(_type); + if (array->isByteArray()) + r.type = SolidityType::Type::Bytes; + else { - ArrayType const* array = dynamic_cast(_type); - if (array->isByteArray()) - r.type = SolidityType::Type::Bytes; - else - { - SolidityType elementType = nodeType(array->getBaseType().get()); - elementType.name = r.name; - r = elementType; - } - r.count = static_cast(array->getLength()); - r.dynamicSize = _type->isDynamicallySized(); - r.array = true; + SolidityType elementType = nodeType(array->getBaseType().get()); + elementType.name = r.name; + r = elementType; } + r.count = static_cast(array->getLength()); + r.dynamicSize = _type->isDynamicallySized(); + r.array = true; + } break; case Type::Category::Enum: - { - r.type = SolidityType::Type::Enum; - EnumType const* e = dynamic_cast(_type); - for(auto const& enumValue: e->getEnumDefinition().getMembers()) - r.enumNames.push_back(QString::fromStdString(enumValue->getName())); - } + { + r.type = SolidityType::Type::Enum; + EnumType const* e = dynamic_cast(_type); + for(auto const& enumValue: e->getEnumDefinition().getMembers()) + r.enumNames.push_back(QString::fromStdString(enumValue->getName())); + } break; case Type::Category::Struct: + { + r.type = SolidityType::Type::Struct; + StructType const* s = dynamic_cast(_type); + for(auto const& structMember: s->getMembers()) { - r.type = SolidityType::Type::Struct; - StructType const* s = dynamic_cast(_type); - for(auto const& structMember: s->getMembers()) - { - auto slotAndOffset = s->getStorageOffsetsOfMember(structMember.name); - r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.name), nodeType(structMember.type.get()), slotAndOffset.first, slotAndOffset.second }); - } + auto slotAndOffset = s->getStorageOffsetsOfMember(structMember.name); + r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.name), nodeType(structMember.type.get()), slotAndOffset.first, slotAndOffset.second }); } + } break; case Type::Category::Function: case Type::Category::IntegerConstant: diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index af3eda094..32e62d584 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/mix/qml/WebCodeEditor.qml @@ -83,9 +83,9 @@ Item { editorBrowser.runJavaScript("setFontSize(" + size + ")", function(result) {}); } - function setSourceName(sourceName) + function setSourceName(_sourceName) { - sourceName = sourceName; + sourceName = _sourceName; if (initialized && editorBrowser) editorBrowser.runJavaScript("setSourceName('" + sourceName + "')", function(result) {}); } @@ -148,19 +148,28 @@ Item { { if (!editorBrowser || !error) return; + + var lineError = firstLocation.start.line + 1; + var errorOrigin = "source error in " + firstLocation.contractName + " line " + lineError + var secondErrorDetail = " Secondary sources: "; + for (var k in secondLocations) + { + lineError = secondLocations[k].start.line + 1; + secondErrorDetail += secondLocations[k].contractName + " line " + lineError + ", "; + displayErrorAnnotations(secondLocations[k], errorOrigin, "second"); + } var detail = error.split('\n')[0]; var reg = detail.match(/:\d+:\d+:/g); if (reg !== null) detail = detail.replace(reg[0], ""); + detail += secondErrorDetail; displayErrorAnnotations(firstLocation, detail, "first"); - for (var k in secondLocations) - displayErrorAnnotations(secondLocations[k], detail, "second"); } function displayErrorAnnotations(location, detail, type) { - //if (location.source === parent.sourceName) - editorBrowser.runJavaScript("compilationError('" + JSON.stringify(location) + "', '" + detail + "', '" + type + "')", function(result){}); + if (location.source === parent.sourceName) + editorBrowser.runJavaScript("compilationError('" + JSON.stringify(location) + "', '" + detail + "', '" + type + "')", function(result){}); } Timer From 6ec7a618c22545ca6bd0b8e76cc7ac5348cb8f12 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 19 May 2015 14:12:33 +0200 Subject: [PATCH 4/5] small changes --- mix/qml/Debugger.qml | 1 - mix/qml/WebCodeEditor.qml | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index c6283b60e..9decc91ae 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -4,7 +4,6 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import Qt.labs.settings 1.0 -import QtGraphicalEffects 1.0 import "js/Debugger.js" as Debugger import "js/ErrorLocationFormater.js" as ErrorLocationFormater import "." diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index 32e62d584..babb200e8 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/mix/qml/WebCodeEditor.qml @@ -155,14 +155,15 @@ Item { for (var k in secondLocations) { lineError = secondLocations[k].start.line + 1; - secondErrorDetail += secondLocations[k].contractName + " line " + lineError + ", "; + secondErrorDetail += secondLocations[k].contractName + " line " + lineError + " - "; displayErrorAnnotations(secondLocations[k], errorOrigin, "second"); } var detail = error.split('\n')[0]; var reg = detail.match(/:\d+:\d+:/g); if (reg !== null) detail = detail.replace(reg[0], ""); - detail += secondErrorDetail; + if (secondLocations.length > 0) + detail += secondErrorDetail; displayErrorAnnotations(firstLocation, detail, "first"); } From e37ddf8eac99eebcf8b48f446665418c0e3315f3 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 20 May 2015 11:45:39 +0200 Subject: [PATCH 5/5] bug fix --- mix/CodeModel.cpp | 8 +++---- mix/qml/CodeEditorView.qml | 2 +- mix/qml/StateListModel.qml | 1 + mix/qml/WebCodeEditor.qml | 26 +++------------------ mix/qml/html/cm/errorannotation.js | 3 --- mix/qml/html/codeeditor.js | 37 +++++++++++++++--------------- 6 files changed, 27 insertions(+), 50 deletions(-) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 9875ee1aa..f10b33408 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -331,11 +331,11 @@ QVariantMap CodeModel::resolveCompilationErrorLocation(CompilerStack const& _com { std::tuple pos = _compiler.positionFromSourceLocation(_location); QVariantMap startError; - startError.insert("line", std::get<0>(pos) - 1); - startError.insert("column", std::get<1>(pos) - 1); + startError.insert("line", std::get<0>(pos) > 1 ? (std::get<0>(pos) - 1) : 1); + startError.insert("column", std::get<1>(pos) > 1 ? (std::get<1>(pos) - 1) : 1); QVariantMap endError; - endError.insert("line", std::get<2>(pos) - 1); - endError.insert("column", std::get<3>(pos) - 1); + endError.insert("line", std::get<2>(pos) > 1 ? (std::get<2>(pos) - 1) : 1); + endError.insert("column", std::get<3>(pos) > 1 ? (std::get<3>(pos) - 1) : 1); QVariantMap error; error.insert("start", startError); error.insert("end", endError); diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 1a5e3f0f8..4f5516264 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -74,8 +74,8 @@ Item { }); } editor.document = document; - editor.setSourceName(document.documentId); editor.setFontSize(editorSettings.fontSize); + editor.sourceName = document.documentId; editor.setText(data, document.syntaxMode); editor.changeGeneration(); } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index f21c93199..a94188a23 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -225,6 +225,7 @@ Item { var ctorTr = defaultTransactionItem(); ctorTr.functionId = c; ctorTr.contractId = c; + ctorTr.label = qsTr("Deploy") + " " + ctorTr.contractId; ctorTr.sender = item.accounts[0].secret; item.transactions.push(ctorTr); } diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index babb200e8..b188cacd6 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/mix/qml/WebCodeEditor.qml @@ -83,13 +83,6 @@ Item { editorBrowser.runJavaScript("setFontSize(" + size + ")", function(result) {}); } - function setSourceName(_sourceName) - { - sourceName = _sourceName; - if (initialized && editorBrowser) - editorBrowser.runJavaScript("setSourceName('" + sourceName + "')", function(result) {}); - } - Clipboard { id: clipboard @@ -148,29 +141,16 @@ Item { { if (!editorBrowser || !error) return; - - var lineError = firstLocation.start.line + 1; - var errorOrigin = "source error in " + firstLocation.contractName + " line " + lineError - var secondErrorDetail = " Secondary sources: "; - for (var k in secondLocations) - { - lineError = secondLocations[k].start.line + 1; - secondErrorDetail += secondLocations[k].contractName + " line " + lineError + " - "; - displayErrorAnnotations(secondLocations[k], errorOrigin, "second"); - } var detail = error.split('\n')[0]; var reg = detail.match(/:\d+:\d+:/g); if (reg !== null) detail = detail.replace(reg[0], ""); - if (secondLocations.length > 0) - detail += secondErrorDetail; - displayErrorAnnotations(firstLocation, detail, "first"); + displayErrorAnnotations(detail, firstLocation, secondLocations); } - function displayErrorAnnotations(location, detail, type) + function displayErrorAnnotations(detail, location, secondaryErrors) { - if (location.source === parent.sourceName) - editorBrowser.runJavaScript("compilationError('" + JSON.stringify(location) + "', '" + detail + "', '" + type + "')", function(result){}); + editorBrowser.runJavaScript("compilationError('" + sourceName + "', '" + JSON.stringify(location) + "', '" + detail + "', '" + JSON.stringify(secondaryErrors) + "')", function(result){}); } Timer diff --git a/mix/qml/html/cm/errorannotation.js b/mix/qml/html/cm/errorannotation.js index a8cdb6fe6..33837ed37 100644 --- a/mix/qml/html/cm/errorannotation.js +++ b/mix/qml/html/cm/errorannotation.js @@ -44,6 +44,3 @@ ErrorAnnotation.prototype.destroy = function() if (this.errorMark) this.errorMark.clear(); } - - - diff --git a/mix/qml/html/codeeditor.js b/mix/qml/html/codeeditor.js index fd5d88df0..c85a87597 100644 --- a/mix/qml/html/codeeditor.js +++ b/mix/qml/html/codeeditor.js @@ -8,7 +8,6 @@ var editor = CodeMirror(document.body, { styleSelectedText: true }); var ternServer; -var sourceName = ""; editor.setOption("theme", "inkpot"); editor.setOption("indentUnit", 4); @@ -160,35 +159,40 @@ showWarning = function(content) var annotations = []; var compilationCompleteBool = true; -compilationError = function(location, error, type) +compilationError = function(currentSourceName, location, error, secondaryErrors) { compilationCompleteBool = false; if (compilationCompleteBool) return; + clearAnnotations(); location = JSON.parse(location); - if (location.start.line) - ensureAnnotation(location, error, type); + if (location.source === currentSourceName) + ensureAnnotation(location, error, "first"); + var lineError = location.start.line + 1; + var errorOrigin = "Source " + location.contractName + " line " + lineError; + secondaryErrors = JSON.parse(secondaryErrors); + for(var i in secondaryErrors) + { + if (secondaryErrors[i].source === currentSourceName) + ensureAnnotation(secondaryErrors[i], errorOrigin, "second"); + } } ensureAnnotation = function(location, error, type) { - for (var k in annotations) - { - if (annotations[k].annotation.location.start.line === location.start.line) - { - annotations[k].annotation.destroy(); - annotations.splice(k, 1); - break; - } - } annotations.push({ "type": type, "annotation": new ErrorAnnotation(editor, location, error)}); } -compilationComplete = function() +clearAnnotations = function() { for (var k in annotations) annotations[k].annotation.destroy(); annotations.length = 0; +} + +compilationComplete = function() +{ + clearAnnotations(); compilationCompleteBool = true; } @@ -204,10 +208,5 @@ setFontSize = function(size) editor.refresh(); } -setSourceName = function(_sourceName) -{ - sourceName = _sourceName; -} - editor.setOption("extraKeys", extraKeys);