arkpar
10 years ago
7 changed files with 318 additions and 30 deletions
@ -0,0 +1,139 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file CodeHighlighter.cpp
|
||||
|
* @author Arkadiy Paronyan arkadiy@ethdev.com |
||||
|
* @date 2015 |
||||
|
* Ethereum IDE client. |
||||
|
*/ |
||||
|
|
||||
|
#include <algorithm> |
||||
|
#include <QRegularExpression> |
||||
|
#include <QTextDocument> |
||||
|
#include <QTextBlock> |
||||
|
#include <QTextLayout> |
||||
|
#include "CodeHighlighter.h" |
||||
|
#include "libsolidity/ASTVisitor.h" |
||||
|
#include "libsolidity/AST.h" |
||||
|
#include "libsolidity/Scanner.h" |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
CodeHighlighterSettings::CodeHighlighterSettings() |
||||
|
{ |
||||
|
bg = QColor(0x00, 0x2b, 0x36); |
||||
|
fg = QColor (0xee, 0xe8, 0xd5); |
||||
|
formats[Keyword].setForeground(QColor(0x93, 0xa1, 0xa1)); |
||||
|
//formats[Type].setForeground(Qt::darkCyan);
|
||||
|
formats[Comment].setForeground(QColor(0x85, 0x99, 0x00)); |
||||
|
formats[StringLiteral].setForeground(QColor(0xdc, 0x32, 0x2f)); |
||||
|
formats[NumLiteral].setForeground(fg); |
||||
|
formats[Import].setForeground(QColor(0x6c, 0x71, 0xc4)); |
||||
|
} |
||||
|
|
||||
|
namespace |
||||
|
{ |
||||
|
using namespace dev::solidity; |
||||
|
class HighlightVisitor : public solidity::ASTConstVisitor |
||||
|
{ |
||||
|
public: |
||||
|
HighlightVisitor(CodeHighlighter::Formats* _formats) { m_formats = _formats; } |
||||
|
private: |
||||
|
CodeHighlighter::Formats* m_formats; |
||||
|
|
||||
|
virtual bool visit(ImportDirective const& _node) |
||||
|
{ |
||||
|
m_formats->push_back(CodeHighlighter::FormatRange(CodeHighlighterSettings::Import, _node.getLocation())); |
||||
|
return true; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
CodeHighlighter::FormatRange::FormatRange(CodeHighlighterSettings::Token _t, solidity::Location const& _location): |
||||
|
token(_t), start(_location.start), length(_location.end - _location.start) |
||||
|
{} |
||||
|
|
||||
|
void CodeHighlighter::processSource(solidity::Scanner* _scanner) |
||||
|
{ |
||||
|
solidity::Token::Value token = _scanner->getCurrentToken(); |
||||
|
while (token != Token::EOS) |
||||
|
{ |
||||
|
if ((token >= Token::BREAK && token < Token::TYPES_END) || |
||||
|
token == Token::IN || token == Token::DELETE || token == Token::NULL_LITERAL || token == Token::TRUE_LITERAL || token == Token::FALSE_LITERAL) |
||||
|
m_formats.push_back(FormatRange(CodeHighlighterSettings::Keyword, _scanner->getCurrentLocation())); |
||||
|
else if (token == Token::STRING_LITERAL) |
||||
|
m_formats.push_back(FormatRange(CodeHighlighterSettings::StringLiteral, _scanner->getCurrentLocation())); |
||||
|
else if (token == Token::COMMENT_LITERAL) |
||||
|
m_formats.push_back(FormatRange(CodeHighlighterSettings::Comment, _scanner->getCurrentLocation())); |
||||
|
else if (token == Token::NUMBER) |
||||
|
m_formats.push_back(FormatRange(CodeHighlighterSettings::NumLiteral, _scanner->getCurrentLocation())); |
||||
|
|
||||
|
token = _scanner->next(); |
||||
|
} |
||||
|
std::sort(m_formats.begin(), m_formats.end()); |
||||
|
} |
||||
|
|
||||
|
void CodeHighlighter::processAST(solidity::ASTNode const& _ast) |
||||
|
{ |
||||
|
HighlightVisitor visitor(&m_formats); |
||||
|
_ast.accept(visitor); |
||||
|
|
||||
|
std::sort(m_formats.begin(), m_formats.end()); |
||||
|
} |
||||
|
|
||||
|
void CodeHighlighter::updateFormatting(QTextDocument* _document, CodeHighlighterSettings const& _settings) |
||||
|
{ |
||||
|
QTextBlock block = _document->firstBlock(); |
||||
|
QList<QTextLayout::FormatRange> ranges; |
||||
|
|
||||
|
Formats::const_iterator format = m_formats.begin(); |
||||
|
while (true) |
||||
|
{ |
||||
|
while ((format == m_formats.end() || (block.position() + block.length() <= format->start)) && block.isValid()) |
||||
|
{ |
||||
|
auto layout = block.layout(); |
||||
|
layout->clearAdditionalFormats(); |
||||
|
layout->setAdditionalFormats(ranges); |
||||
|
_document->markContentsDirty(block.position(), block.length()); |
||||
|
block = block.next(); |
||||
|
ranges.clear(); |
||||
|
} |
||||
|
if (!block.isValid()) |
||||
|
break; |
||||
|
|
||||
|
int intersectionStart = std::max(format->start, block.position()); |
||||
|
int intersectionLength = std::min(format->start + format->length, block.position() + block.length()) - intersectionStart; |
||||
|
if (intersectionLength > 0) |
||||
|
{ |
||||
|
QTextLayout::FormatRange range; |
||||
|
range.format = _settings.formats[format->token]; |
||||
|
range.start = format->start - block.position(); |
||||
|
range.length = format->length; |
||||
|
ranges.append(range); |
||||
|
} |
||||
|
++format; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,94 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file CodeHighlighter.h
|
||||
|
* @author Arkadiy Paronyan arkadiy@ethdev.com |
||||
|
* @date 2015 |
||||
|
* Ethereum IDE client. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <vector> |
||||
|
#include <QString> |
||||
|
#include <QTextCharFormat> |
||||
|
|
||||
|
class QTextDocument; |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
|
||||
|
namespace solidity |
||||
|
{ |
||||
|
class ASTNode; |
||||
|
class Scanner; |
||||
|
struct Location; |
||||
|
} |
||||
|
|
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
class CodeHighlighterSettings |
||||
|
{ |
||||
|
public: |
||||
|
enum Token |
||||
|
{ |
||||
|
Import, |
||||
|
Keyword, |
||||
|
Comment, |
||||
|
StringLiteral, |
||||
|
NumLiteral, |
||||
|
Size, //this must be kept last
|
||||
|
}; |
||||
|
|
||||
|
CodeHighlighterSettings(); |
||||
|
///Format for each token
|
||||
|
QTextCharFormat formats[Size]; |
||||
|
///Background color
|
||||
|
QColor bg; |
||||
|
///Foreground color
|
||||
|
QColor fg; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
class CodeHighlighter |
||||
|
{ |
||||
|
public: |
||||
|
struct FormatRange |
||||
|
{ |
||||
|
FormatRange(CodeHighlighterSettings::Token _t, int _start, int _length): token(_t), start(_start), length(_length) {} |
||||
|
FormatRange(CodeHighlighterSettings::Token _t, solidity::Location const& _location); |
||||
|
bool operator<(FormatRange const& _other) { return start < _other.start || (start == _other.start && length < _other.length); } |
||||
|
|
||||
|
CodeHighlighterSettings::Token token; |
||||
|
int start; |
||||
|
int length; |
||||
|
}; |
||||
|
typedef std::vector<FormatRange> Formats; // Sorted by start position
|
||||
|
|
||||
|
public: |
||||
|
/// Collect highligting information
|
||||
|
void processSource(solidity::Scanner* _scanner); |
||||
|
void processAST(solidity::ASTNode const& _ast); |
||||
|
void updateFormatting(QTextDocument* _document, CodeHighlighterSettings const& _settings); |
||||
|
|
||||
|
private: |
||||
|
Formats m_formats; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
Loading…
Reference in new issue