├── LICENSE.GPL2 ├── LICENSE.GPL3 ├── README.md ├── VerilogCreator.json.in ├── VerilogCreator.pro ├── VerilogCreator.qrc ├── VlAutoCompleter.cpp ├── VlAutoCompleter.h ├── VlCompletionAssistProvider.cpp ├── VlCompletionAssistProvider.h ├── VlConfigurationFactory.cpp ├── VlConfigurationFactory.h ├── VlConstants.h ├── VlEditor.mimetypes.xml ├── VlHighlighter.cpp ├── VlHighlighter.h ├── VlHoverHandler.cpp ├── VlHoverHandler.h ├── VlIcarusConfiguration.cpp ├── VlIcarusConfiguration.h ├── VlIndenter.cpp ├── VlIndenter.h ├── VlModelManager.cpp ├── VlModelManager.h ├── VlModuleLocator.cpp ├── VlModuleLocator.h ├── VlOutlineMdl.cpp ├── VlOutlineMdl.h ├── VlOutlineWidget.cpp ├── VlOutlineWidget.h ├── VlPlugin.cpp ├── VlPlugin.h ├── VlProject.cpp ├── VlProject.h ├── VlProjectEditor.cpp ├── VlProjectEditor.h ├── VlProjectManager.cpp ├── VlProjectManager.h ├── VlSdfEditor.cpp ├── VlSdfEditor.h ├── VlSymbolLocator.cpp ├── VlSymbolLocator.h ├── VlTclConfiguration.cpp ├── VlTclConfiguration.h ├── VlTclEngine.cpp ├── VlTclEngine.h ├── VlVerilatorConfiguration.cpp ├── VlVerilatorConfiguration.h ├── VlVerilogEditor.cpp ├── VlVerilogEditor.h ├── VlYosysConfiguration.cpp ├── VlYosysConfiguration.h ├── examples ├── Readme.txt ├── counter.v ├── counter.vlpro ├── counter_tb.v ├── hello.v └── hello.vlpro ├── images ├── block.png ├── category.png ├── class.png ├── func.png └── var.png └── verilogcreator_global.h /README.md: -------------------------------------------------------------------------------- 1 | ![icon](http://software.rochus-keller.ch/VerilogCreator_100.png) 2 | ## Welcome to VerilogCreator 3 | 4 | VerilogCreator is a [QtCreator](https://download.qt.io/official_releases/qtcreator/) plugin. It turns QtCreator into a Verilog 2005 IDE. 5 | 6 | The plugin is still work in progress, but it already has enough functionality to analyze existing code bases or to develop new code. The current version supports Verilog 2005 syntax checking/coloring and semantic code navigation/highlighting; there are build configurations for Icarus, Verilator, Yosys and Tcl. Projects can be configured using a file format similar to qmake. 7 | 8 | ![screenshot](http://software.rochus-keller.ch/VlCreator_screenshot2.png "VerilogCreator Screenshot") 9 | 10 | 11 | ![screenshot](http://software.rochus-keller.ch/VlCreator_screenshot7.png "VerilogCreator Screenshot") 12 | 13 | ### Implemented Features 14 | 15 | - Syntax highlighting (including ifdefed out blocks and markers) 16 | - Context sensitive code completer, see [screenshot](http://software.rochus-keller.ch/vlcreator_completer_screenshot.png) 17 | - Inline code warnings and errors 18 | - Parentheses and begin/end block matching/navigation 19 | - Hover tooltips 20 | - Follow symbol under cursor, follow includes (multi-file support) 21 | - Show where a symbol is used 22 | - Drop-down menu to jump to modules, module instances, functions and tasks in current file 23 | - Outline view; see [screenshot](http://software.rochus-keller.ch/vlcreator_outline_screenshot.png) 24 | - Module locator (global) and symbol locator (current document); see [screenshot 1](http://software.rochus-keller.ch/vlcreator_module_locator_screenshot.png) and [screenshot 2](http://software.rochus-keller.ch/vlcreator_symbol_locator_screenshot.png) 25 | - Syntax based code folding and some other features supported by QtCreator, see http://doc.qt.io/qtcreator/ 26 | - Marker based code folding (MBCF); use section markers like //{ and //}, or //> and //<; see [screenshot 1](http://software.rochus-keller.ch/vlcreator_mbcf_screenshot1.png) and [screenshot 2](http://software.rochus-keller.ch/vlcreator_mbcf_screenshot2.png) 27 | - Project file to configure source files, include dirs, defines and libraries 28 | - Icarus Verilog build and run configuration; directly run compiler and simulator from within QtCreator 29 | - Verilator and Yosys build configurations; generate command files, optional arguments 30 | - Build configuration based on custom Tcl scripts which can access project configuration (e.g. to run Vivado commands) 31 | - Selected optional SystemVerilog syntax extensions such as assert, assume, cover and restrict (see [here for more information](#supported-systemverilog-subset)) 32 | - Supports Standard Delay Format (SDF) files with syntax highlighting, see [screenshot](http://software.rochus-keller.ch/vlcreator_sdf_editor_screenshot.png) 33 | 34 | ### Project file format 35 | 36 | VerilogCreator can either open single verilog files or project configuration files with the suffix ".vlpro". 37 | 38 | The vlpro file can be empty; in that case all Verilog files (default suffix ".v") located in the vlpro directory including subdirectories are assumed to be the source files of the project. 39 | 40 | Vlpro files follow the same syntax as QtCreator pro files (see http://doc.qt.io/qt-5/qmake-project-files.html), but uses other variable names. The following variables are supported: 41 | 42 | `SRCFILES += /path/filename.v` 43 | 44 | `SRCFILES += "/path with whitespace/filename.v"` 45 | 46 | ``` 47 | SRCFILES += /firstpath/filename.v /secondpath/filename.v \ 48 | /thirdpath_on_new_line/filename.v 49 | ``` 50 | 51 | `SRCFILES += /directory_path1/ filename1.v filename2.v /directory_path2/ filename3.v filename4.v` 52 | 53 | The variable `SRCFILES` lets you add source files explicitly to your project. There are different syntax versions. You can add filenames with absolute or relative paths; if you add a directory path only then the following filenames are assumed to belong to the directory with the given path. 54 | Note that path/filenames including whitespace have to be quoted by " ". Also note that you can add more than one element to a line separated by whitespace and that a \ lets you continue on the next line; this applies to all variables. 55 | 56 | `SRCEXT = .v .vl .verilog` 57 | 58 | The `SRCEXT` variable can be used to override the expected suffix of verilog files. Default is ".v". 59 | 60 | 61 | `SRCDIRS += dirpath1 dirpath2 dirpath3*` 62 | 63 | `SRCDIRS += dirpath4 -filename1 -filename2 dirpath5 -filename3` 64 | 65 | With the `SRCDIRS` variable it is possible to add all verilog files in a given directory. All files with a suffix specified in SRCEXT are considered. There are different syntax versions. You can add directories with absolute or relative path. If you postfix the path with an "*" then also all subdirectories are implicitly added. If you want to leave out certain files add the filename to the line prefixed with "-". 66 | 67 | `LIBFILES += ` 68 | 69 | `LIBDIRS += ` 70 | 71 | `LIBEXT = ` 72 | 73 | These variables are used the same way as their SRC counterparts. Use them to add Verilog files which are used but not modified by the present project. 74 | 75 | `INCDIRS += dirpath1 dirpath2` 76 | 77 | The variable `INCDIRS` specifies where the parser looks for include files (included by the Verilog include compiler directive). 78 | 79 | `DEFINES += DISABLE_SV_ASSERTION "E203_PC_SIZE 24"` 80 | 81 | This has the same effect as the Verilog include compiler directive and affects all files. Note that also the syntax corresponds to Verilog defines; since Verilog uses whitespace to separate name and values you have to use quotes in the vlpro file. 82 | There is also a variable `BUILD_UNDEFS` by which defines can be deactivated in the command file generated for Icarus, Verilator and Yosys; you could for example define VERILATOR in the vlpro so VerilogCreator can see it but then use `BUILD_UNDEFS = VERILATOR` to avoid define warnings in Verilator. 83 | 84 | `TOPMOD = picosoc` 85 | 86 | Use TOPMOD to explicitly set the top-level module; this is useful in case there is more than one top-level module in the code base. VerilogCreator does not use this information but hands it over to Icarus, Verilator and Yosys. 87 | 88 | `SVEXT = ` 89 | 90 | This variable is used to tell the parser which files should be considered SystemVerilog files; default is ".sv"; the parser will enable the SV extension for these files in any case, regardless of the UseSvExtension option. 91 | 92 | `CONFIG += UseSvExtension` 93 | 94 | Use this option to enable the SystemVerilog extension for the whole project. Without this option, all files are assumed to be in Verilog 05 format besides the files whose suffix corresponds to one in SVEXT. With the option enabled all files are assumed to be in the supported SystemVerilog 2012 subset. 95 | 96 | `OTHER_FILES += ` 97 | 98 | The variable `OTHER_FILES` lets you add other than source or library files (e.g. SDF files) to your project. The syntax and semantics are the same as with `SRCFILES`. 99 | 100 | ### Supported SystemVerilog subset 101 | 102 | If enabled (see the SVEXT and UseSvExtension project file options) the VerilogCreator plugin supports the following subset of SystemVerilog as specified in IEEE 1800-2012: 103 | 104 | - assert_property_statement, simple_immediate_assert_statement and deferred_immediate_assert_statement 105 | - assume_property_statement, simple_immediate_assume_statement and deferred_immediate_assume_statement 106 | - cover_sequence_statement, cover_property_statement, simple_immediate_cover_statement and deferred_immediate_cover_statement 107 | - restrict_property_statement 108 | - deferred_immediate_assertion_item 109 | - concurrent_assertion_item 110 | - property_spec, without property_instance, checker_instantiation 111 | - sequence_expr, without sequence_abbrev, sequence_match_item, first_match 112 | 113 | ### Download Binaries 114 | 115 | Pre-compiled versions of the VerilogCreator plugin can be downloaded for Windows, Linux and Macintosh as part of the QtcVerilog application. 116 | 117 | See here to learn more: https://github.com/rochus-keller/QtcVerilog/blob/master/README.md 118 | 119 | ### Build Steps 120 | Follow these steps if you want to build VerilogCreator yourself: 121 | 122 | 1. Make sure that QtCreator and the Qt base development package are installed on your system. VerilogCreator was developed and tested with QtCreator 3.4 and Qt 5.4 on Linux. It also compiles with QtCreator 3.6 and Qt 5.7, but not (yet) with QtCreator 4.x (see below). Instead of using QtCreator, you can also use QtcVerilog (see https://github.com/rochus-keller/QtcVerilog). 123 | 1. Create a build directory; let's call it BUILD_DIR 124 | 1. Download the VerilogCreator source code from https://github.com/rochus-keller/VerilogCreator/archive/master.zip and unpack it to the BUILD_DIR; rename the subdirectory to "VerilogCreator". 125 | 1. Download the Verilog parser source code from https://github.com/rochus-keller/Verilog/archive/master.zip and unpack it to the BUILD_DIR; rename "Verilog-Master" to "Verilog". 126 | 1. Download the Sdf parser source code from https://github.com/rochus-keller/Sdf/archive/master.zip and unpack it to the BUILD_DIR; rename "Sdf-Master" to "Sdf". 127 | 1. Download the appropriate version of the QtCreator source code from https://download.qt.io/official_releases/qtcreator/ and unpack it to the BUILD_DIR. Instead of the QtCreator source code you can also use the QtcCreator source code (see https://github.com/rochus-keller/QtcVerilog). 128 | 1. In case you don't have the Tcl development package installed: download http://software.rochus-keller.ch/tcl_headers.zip and unpack it to BUILD_DIR/tcl. 129 | 1. Either set the QTC_SOURCE (path to the QtCreator/QtcVerilog source code directory) and QTC_BUILD (path to the QtCreator/QtcVerilog installation directory) environment variables or directly modify the QTCREATOR_SOURCES and IDE_BUILD_TREE variables in VerilogCreator.pro. 130 | 1. Goto the BUILD_DIR/VerilogCreator subdirectory and execute `QTDIR/bin/qmake VerilogCreator.pro` (see the Qt documentation concerning QTDIR). 131 | 1. Run make; after a couple of minutes the plugin is compiled and automatically deployed to the local QtCreator plugin directory (on Linux to ~/.local/share/data/QtProject/qtcreator/plugins/x.y.z/libVerilogCreator.so) or directly to QtcVerilog. 132 | 1. Start QtCreator/QtcVerilog and check in the "Help/About Plugins..." dialog (section "Other Languages") that the plugin is activated. 133 | 134 | Instead of using qmake and make you can open VerilogCreator.pro using QtCreator and build it there. 135 | 136 | Note that on Windows you also have to compile QtCreator/QtcVerilog itself because you also need the lib files for the plugin dll's (i.e. Core.lib, TextEditor.lib and ProjectExplorer.lib). Compiling QtCreator is not an easy task; compiling QtcVerilog is much easier. 137 | 138 | ### State of Development 139 | Even though I'm using Qt for twenty years and QtCreator for ten years this is my first noteworthy QtCreator plugin. Of course I read all available documentation and watched all available lectures. But still the available information is very sparse, of lesser quality than the Qt documentation and often outdated. So I had to invest half the development time in reverse engineering of the QtCreator 3.4 source code. I don't use QtCreator 4.x yet because I'm working on Ubuntu LTS versions which only have QtCreator 3.x packages and also because I'm fully satisfied with 3.x and the more recent versions run slower and consume more resources. 140 | 141 | I'm aware of the Binary and Source Compatibility rules of QtCreator plugins and managed to make the source code compatible with QtCreator 3.4.x to the latest 3.6.1 using ifdefs. But in QtCreator 4.x they not only have changed some function signatures, but also the architecture to a considerable extent. According to my current state of investigation, managing compatibility with a few ifdefs is no longer feasible; instead it seems necessary to maintain different codebases in parallel to be compatible with both QtCreator 3.x and 4.x and cope with the different architectures at the same time. Thus the question arises whether using QtCreator as the basis for the Verilog IDE is an advantage or rather a disadvantage. If you know a better work-around, please send me an email. 142 | 143 | All in all it is now clear to me why there are comparatively few plugins for QtCreator in all these years and most of them come directly from the Qt Company. Source and binary compatibility between QtCreator versions is not only complex, but a full-blown nightmare. All the more annoying that many changes to the API seem to be purely cosmetic in nature. Unfortunately, you only realize the size and consequences of this problem when you have developed a sufficiently large plugin yourself and built it for several versions of QtCreator, unless you know the source code of QtCreator very well in several versions, which might only be the case for a few people. 144 | 145 | Since I currently consider the effort to reverse engineer each QtCreator version anew and to develop different variants of the code in parallel to be too high, I do it the other way round: instead of adapting the plugin to each major and minor QtCreator version, I offer a simple binary deployment for Linux, Windows and Mac of a lean QtCreator version including VerilogCreator and some other minimal required plugins. See here to learn more: https://github.com/rochus-keller/QtcVerilog. 146 | 147 | ### To do's 148 | 149 | - Documentation 150 | - Semantic indenter (the current one simply adjusts to the previous line) 151 | - Parse output of Icarus/Verilator/Yosys and post it to the Issues pane 152 | - Implement wizzard to add or import files, generate stub modules and automatically update the vlpro file 153 | - Improve hover text 154 | - Implement options dialog (format settings, paths, etc.) 155 | - Improve code completer (for hierarchical identifiers) 156 | - Integrate wave viewer 157 | - Extend SystemVerilog support, goal is to support everything Verilator does. 158 | 159 | ### Support 160 | If you need support or would like to post issues or feature requests please use the Github issue list at https://github.com/rochus-keller/VerilogCreator/issues or send an email to the author. 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /VerilogCreator.json.in: -------------------------------------------------------------------------------- 1 | { 2 | \"Name\" : \"VerilogCreator\", 3 | \"Version\" : \"0.8.0\", 4 | \"CompatVersion\" : \"0.8.0\", 5 | \"Vendor\" : \"Rochus Keller\", 6 | \"Copyright\" : \"(C) 2019 Rochus Keller\", 7 | \"License\" : \"GPL\", 8 | \"Category\" : \"Other Languages\", 9 | \"Description\" : \"QtCreator based IDE for Verilog\", 10 | \"Url\" : \"https://github.com/rochus-keller/VerilogCreator\", 11 | $$dependencyList 12 | } 13 | 14 | -------------------------------------------------------------------------------- /VerilogCreator.pro: -------------------------------------------------------------------------------- 1 | #/* 2 | #* Copyright 2018 Rochus Keller 3 | #* 4 | #* This file is part of the VerilogCreator plugin. 5 | #* 6 | #* The following is the license that applies to this copy of the 7 | #* plugin. For a license to use the plugin under conditions 8 | #* other than those described here, please email to me@rochus-keller.ch. 9 | #* 10 | #* GNU General Public License Usage 11 | #* This file may be used under the terms of the GNU General Public 12 | #* License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | #* Foundation and appearing in the file LICENSE.GPL included in 14 | #* the packaging of this file. Please review the following information 15 | #* to ensure GNU General Public Licensing requirements will be met: 16 | #* http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | #* http://www.gnu.org/copyleft/gpl.html. 18 | #*/ 19 | 20 | DEFINES += VERILOGCREATOR_LIBRARY 21 | 22 | # Qt Creator linking 23 | 24 | ## set the QTC_SOURCE environment variable to override the setting here 25 | QTCREATOR_SOURCES = $$(QTC_SOURCE) 26 | isEmpty(QTCREATOR_SOURCES):QTCREATOR_SOURCES=../QtcVerilog 27 | 28 | ## set the QTC_BUILD environment variable to override the setting here 29 | IDE_BUILD_TREE = $$(QTC_BUILD) 30 | isEmpty(IDE_BUILD_TREE):IDE_BUILD_TREE=../QtcVerilogBuild 31 | 32 | ###### If the plugin can be depended upon by other plugins, this code needs to be outsourced to 33 | ###### _dependencies.pri, where is the name of the directory containing the 34 | ###### plugin's sources. 35 | 36 | QTC_PLUGIN_NAME = VerilogCreator 37 | QTC_LIB_DEPENDS += \ 38 | # nothing here at this time 39 | 40 | QTC_PLUGIN_DEPENDS += \ 41 | coreplugin texteditor projectexplorer 42 | 43 | QTC_PLUGIN_RECOMMENDS += \ 44 | # optional plugin dependencies. nothing here at this time 45 | 46 | ###### End _dependencies.pri contents ###### 47 | 48 | include($$QTCREATOR_SOURCES/src/qtcreatorplugin.pri) 49 | 50 | ## uncomment to build plugin into user config directory 51 | ## /plugins/ 52 | ## where is e.g. 53 | ## "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later 54 | ## "$XDG_DATA_HOME/data/QtProject/qtcreator" or "~/.local/share/data/QtProject/qtcreator" on Linux 55 | ## "~/Library/Application Support/QtProject/Qt Creator" on Mac 56 | isEmpty(QTC_VERILOG) { 57 | message(Use user destdir) 58 | USE_USER_DESTDIR = yes 59 | } 60 | 61 | VL_COMPAT_VERSION_LIST=$$split(QTCREATOR_COMPAT_VERSION,.) 62 | VL_COMPAT_VER_MAJ=$$format_number($$member(VL_COMPAT_VERSION_LIST,0), width=2 zeropad) 63 | VL_COMPAT_VER_MIN=$$format_number($$member(VL_COMPAT_VERSION_LIST,1), width=2 zeropad) 64 | DEFINES += "VL_QTC_VER_MAJ=$$VL_COMPAT_VER_MAJ" # 03 65 | DEFINES += "VL_QTC_VER_MIN=$$VL_COMPAT_VER_MIN" # 04 66 | DEFINES += "VL_QTC_VER=$$VL_COMPAT_VER_MAJ$$VL_COMPAT_VER_MIN" # 0304 67 | #message($$DEFINES) 68 | 69 | DEFINES -= QT_NO_CAST_FROM_ASCII 70 | 71 | # VerilogCreator files 72 | 73 | CONFIG(debug, debug|release) { 74 | DEFINES += _DEBUG 75 | } 76 | !win32 { QMAKE_CXXFLAGS += -Wno-reorder -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable } 77 | 78 | INCLUDEPATH += .. 79 | 80 | SOURCES += \ 81 | VlHighlighter.cpp \ 82 | VlPlugin.cpp \ 83 | VlIndenter.cpp \ 84 | VlModelManager.cpp \ 85 | VlProject.cpp \ 86 | VlProjectManager.cpp \ 87 | VlHoverHandler.cpp \ 88 | VlConfigurationFactory.cpp \ 89 | VlIcarusConfiguration.cpp \ 90 | VlVerilatorConfiguration.cpp \ 91 | VlYosysConfiguration.cpp \ 92 | VlOutlineMdl.cpp \ 93 | VlTclConfiguration.cpp \ 94 | VlTclEngine.cpp \ 95 | VlAutoCompleter.cpp \ 96 | VlCompletionAssistProvider.cpp \ 97 | VlOutlineWidget.cpp \ 98 | VlModuleLocator.cpp \ 99 | VlSymbolLocator.cpp \ 100 | VlVerilogEditor.cpp \ 101 | VlProjectEditor.cpp \ 102 | VlSdfEditor.cpp 103 | 104 | HEADERS += \ 105 | verilogcreator_global.h \ 106 | VlHighlighter.h \ 107 | VlConstants.h \ 108 | VlPlugin.h \ 109 | VlIndenter.h \ 110 | VlModelManager.h \ 111 | VlProject.h \ 112 | VlProjectManager.h \ 113 | VlHoverHandler.h \ 114 | VlConfigurationFactory.h \ 115 | VlIcarusConfiguration.h \ 116 | VlVerilatorConfiguration.h \ 117 | VlYosysConfiguration.h \ 118 | VlOutlineMdl.h \ 119 | VlTclConfiguration.h \ 120 | VlTclEngine.h \ 121 | VlAutoCompleter.h \ 122 | VlCompletionAssistProvider.h \ 123 | VlOutlineWidget.h \ 124 | VlModuleLocator.h \ 125 | VlSymbolLocator.h \ 126 | VlVerilogEditor.h \ 127 | VlProjectEditor.h \ 128 | VlSdfEditor.h 129 | 130 | include (../Verilog/Verilog.pri ) 131 | include (../Sdf/Sdf.pri ) 132 | 133 | OTHER_FILES += 134 | 135 | DISTFILES += \ 136 | VerilogCreator.json.in 137 | 138 | RESOURCES += \ 139 | VerilogCreator.qrc 140 | -------------------------------------------------------------------------------- /VerilogCreator.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | VlEditor.mimetypes.xml 4 | 5 | 6 | images/class.png 7 | images/func.png 8 | images/var.png 9 | images/block.png 10 | images/category.png 11 | 12 | 13 | -------------------------------------------------------------------------------- /VlAutoCompleter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlAutoCompleter.h" 21 | #include "VlConstants.h" 22 | #include 23 | #include 24 | #include 25 | using namespace Vl; 26 | 27 | // borrowed parts from RubyCreator 28 | 29 | bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor& cursor, const QString& textToInsert) const 30 | { 31 | if (isInComment(cursor)) 32 | return false; 33 | 34 | QChar ch; 35 | 36 | if (!textToInsert.isEmpty()) 37 | ch = textToInsert.at(0); 38 | 39 | switch( ch.toLatin1() ) 40 | { 41 | case '"': 42 | case '(': 43 | case '[': 44 | case '{': 45 | case ')': 46 | case ']': 47 | case '}': 48 | return true; 49 | default: 50 | return false; 51 | } 52 | } 53 | 54 | bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor& cursor) const 55 | { 56 | return TextEditor::AutoCompleter::contextAllowsElectricCharacters(cursor); 57 | } 58 | 59 | bool AutoCompleter::isInComment(const QTextCursor& cursor) const 60 | { 61 | const int state = cursor.block().userState(); 62 | if( state != -1 && state & 0xff ) // Zeichen für Multiline Comment aus Highlighter 63 | return true; 64 | 65 | const QString line = cursor.block().text(); 66 | const int col = cursor.columnNumber(); 67 | const int pos = line.indexOf(QLatin1String("//") ); 68 | if (pos == -1 || pos > col ) 69 | return false; 70 | else 71 | return true; 72 | } 73 | 74 | bool AutoCompleter::isInString(const QTextCursor& cursor) const 75 | { 76 | return TextEditor::AutoCompleter::isInString(cursor); 77 | } 78 | 79 | QString AutoCompleter::insertMatchingBrace(const QTextCursor& cursor, const QString& text, QChar la, int* skippedChars) const 80 | { 81 | if (text.length() != 1) 82 | return QString(); 83 | 84 | const QChar ch = text.at(0); 85 | switch (ch.toLatin1()) 86 | { 87 | case '"': 88 | if (la != ch) 89 | return QString(ch); 90 | ++*skippedChars; 91 | break; 92 | case '(': 93 | return QStringLiteral(")"); 94 | 95 | case '[': 96 | return QStringLiteral("]"); 97 | 98 | case '{': 99 | return QStringLiteral("}"); 100 | 101 | case ')': 102 | case ']': 103 | case '}': 104 | case ';': 105 | if (la == ch) 106 | ++*skippedChars; 107 | break; 108 | 109 | default: 110 | break; 111 | } // end of switch 112 | 113 | return QString(); 114 | } 115 | 116 | QString AutoCompleter::insertParagraphSeparator(const QTextCursor& cursor) const 117 | { 118 | return TextEditor::AutoCompleter::insertParagraphSeparator(cursor); 119 | } 120 | 121 | -------------------------------------------------------------------------------- /VlAutoCompleter.h: -------------------------------------------------------------------------------- 1 | #ifndef VLAUTOCOMPLETER_H 2 | #define VLAUTOCOMPLETER_H 3 | 4 | /* 5 | * Copyright 2019 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | 25 | namespace Vl 26 | { 27 | class AutoCompleter : public TextEditor::AutoCompleter 28 | { 29 | public: 30 | AutoCompleter() {} 31 | 32 | virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, 33 | const QString &textToInsert = QString()) const; 34 | virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const; 35 | virtual bool isInComment(const QTextCursor &cursor) const; 36 | virtual bool isInString(const QTextCursor &cursor) const; 37 | virtual QString insertMatchingBrace(const QTextCursor &cursor, 38 | const QString &text, 39 | QChar la, 40 | int *skippedChars) const; 41 | virtual QString insertParagraphSeparator(const QTextCursor &cursor) const; 42 | }; 43 | 44 | } 45 | 46 | #endif // VLAUTOCOMPLETER_H 47 | -------------------------------------------------------------------------------- /VlCompletionAssistProvider.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlCompletionAssistProvider.h" 21 | #include "VlConstants.h" 22 | #include "VlModelManager.h" 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | namespace Vl 38 | { 39 | class CompletionAssistProcessor : public TextEditor::IAssistProcessor 40 | { 41 | public: 42 | CompletionAssistProcessor() {} 43 | TextEditor::IAssistProposal* perform(const TextEditor::AssistInterface *ai) 44 | { 45 | m_interface.reset(ai); 46 | 47 | if (ai->reason() == TextEditor::IdleEditor) 48 | return 0; 49 | 50 | const int curPos = ai->position(); 51 | 52 | const QTextBlock block = ai->textDocument()->findBlock(curPos); 53 | const int lineNr = block.blockNumber() + 1; 54 | const int colNr = curPos - block.position() + 1; 55 | const QString seq = QChar(' ') + ai->textDocument()->findBlock(curPos).text().left(colNr-1); 56 | //const QString seq = ai->textAt(curPos, -CompletionAssistProvider::SeqLen ); 57 | const QString fileName = ai->fileName(); 58 | 59 | CrossRefModel* mdl = ModelManager::instance()->getModelForCurrentProject(); 60 | if( mdl == 0 ) 61 | return 0; 62 | 63 | const int prefixPos = CompletionAssistProvider::checkSequence(seq,0); 64 | if( prefixPos > 0 ) 65 | return 0; 66 | 67 | enum { PlainIdent, MacroUse, DotExpand } what = PlainIdent; 68 | if( seq.size() + prefixPos - 1 >= 0 ) 69 | { 70 | switch( seq[ seq.size() + prefixPos - 1 ].toLatin1() ) 71 | { 72 | case '.': 73 | what = DotExpand; 74 | break; 75 | case '`': 76 | what = MacroUse; 77 | break; 78 | } 79 | } 80 | //const QString prefix = seq.right(-prefixPos); 81 | //qDebug() << prefix << what << seq; 82 | 83 | QList proposals; 84 | 85 | if( what == MacroUse ) 86 | { 87 | const QByteArrayList names = mdl->getSyms()->getNames(); 88 | for( auto i = names.begin(); i != names.end(); ++i ) 89 | { 90 | auto proposal = new TextEditor::AssistProposalItem(); 91 | proposal->setText(QString::fromLatin1((*i))); 92 | //proposal->setIcon(icon); 93 | //proposal->setOrder(order); 94 | proposals << proposal; 95 | 96 | } 97 | 98 | }else // PlainIdent or DotExpand 99 | { 100 | CrossRefModel::TreePath p = mdl->findSymbolBySourcePos( fileName, lineNr, colNr, false, true ); 101 | if( p.isEmpty() ) 102 | return 0; 103 | 104 | // foreach( const CrossRefModel::SymRef& sym, p ) 105 | // qDebug() << SynTree::rToStr( sym->tok().d_type ) << sym->tok().d_lineNr << sym->tok().d_colNr; 106 | // if( p.size() > 1 ) 107 | // { 108 | // CrossRefModel::dump(p[1].constData(), 0, false); 109 | // CrossRefModel::dump(p[0].constData(), 1, false); 110 | // //qDebug() << SynTree::rToStr( p[0]->tok().d_type ) << p[0]->tok().d_lineNr << p[0]->tok().d_colNr; 111 | // } 112 | // if( !p.isEmpty() ) 113 | // CrossRefModel::dump(p.first().constData(), 0, true); 114 | 115 | CrossRefModel::Scope::Names2 names; 116 | 117 | if( what == DotExpand ) 118 | { 119 | CrossRefModel::ScopeRef module; 120 | const CrossRefModel::Branch* branch = CrossRefModel::closestBranch(p); 121 | if( branch && branch->tok().d_type == SynTree::R_module_or_udp_instantiation_ ) 122 | { 123 | CrossRefModel::SymRef sym = mdl->findGlobal(branch->tok().d_val); 124 | if( sym.constData() ) 125 | module = sym->toScope(); 126 | }else if( branch && branch->tok().d_type == SynTree::R_module_or_udp_instance_ ) 127 | { 128 | CrossRefModel::SymRef sym = mdl->findGlobal(branch->super()->tok().d_val); 129 | if( sym.constData() ) 130 | module = sym->toScope(); 131 | } 132 | if( module.constData() ) 133 | { 134 | //qDebug() << "fetching symbols of" << module->tok().d_val; 135 | names = module->getNames2(false); 136 | } 137 | 138 | }else // PlainIdent 139 | { 140 | CrossRefModel::ScopeRef scope( CrossRefModel::closestScope(p) ); 141 | if( scope.constData() ) 142 | { 143 | //qDebug() << "fetching symbols of" << scope->tok().d_val; 144 | names = scope->getNames2(); 145 | } 146 | } 147 | 148 | QPixmap iMod(":/verilogcreator/images/block.png"); 149 | QPixmap iVar(":/verilogcreator/images/var.png"); 150 | QPixmap iFunc(":/verilogcreator/images/func.png"); 151 | 152 | for( auto i = names.begin(); i != names.end(); ++i ) 153 | { 154 | auto proposal = new TextEditor::AssistProposalItem(); 155 | proposal->setText(QString::fromLatin1(i.key())); 156 | const int declType = i.value()->decl()->tok().d_type; 157 | proposal->setDetail( SynTree::rToStr( declType ) ); 158 | QPixmap icon; 159 | switch(declType) 160 | { 161 | case SynTree::R_module_declaration: 162 | case SynTree::R_udp_declaration: 163 | icon = iMod; 164 | break; 165 | case SynTree::R_task_declaration: 166 | case SynTree::R_function_declaration: 167 | icon = iFunc; 168 | break; 169 | default: 170 | icon = iVar; 171 | break; 172 | } 173 | proposal->setIcon(icon); 174 | //proposal->setOrder(order); 175 | proposals << proposal; 176 | 177 | } 178 | } 179 | 180 | if( proposals.isEmpty() ) 181 | return 0; 182 | 183 | TextEditor::GenericProposalModel *model = new TextEditor::GenericProposalModel(); 184 | model->loadContent(proposals); 185 | TextEditor::IAssistProposal *proposal = new TextEditor::GenericProposal(curPos+prefixPos, model); 186 | return proposal; 187 | } 188 | private: 189 | QScopedPointer m_interface; 190 | }; 191 | } 192 | 193 | using namespace Vl; 194 | 195 | static inline bool isInIdentChar( QChar c ) 196 | { 197 | return c.isLetterOrNumber() || c == '_' || c == '$'; 198 | } 199 | 200 | static inline bool isFirstIdentChar( QChar c ) 201 | { 202 | return c.isLetter() || c == '_' || c == '$'; 203 | } 204 | 205 | int CompletionAssistProvider::checkSequence(const QString& s, int minLen ) 206 | { 207 | // returns >0 if nothing found 208 | // else returns position from s.size() leftwards, where text begins 209 | if( s.isEmpty() ) 210 | return 1; 211 | 212 | for( int off = s.size() - 1; off >= 0; off-- ) 213 | { 214 | QChar c = s[off]; 215 | if( c == '.' || c == '`' ) 216 | return off - s.size() + 1; 217 | else if( !isInIdentChar(c) ) 218 | { 219 | off++; 220 | if( ( s.size() - off ) < minLen ) 221 | break; 222 | if( off < s.size() && isFirstIdentChar( s[off] ) ) 223 | return off - s.size(); 224 | else 225 | return 0; 226 | } 227 | } 228 | return 1; 229 | // obsolet: 230 | #if 0 231 | QChar c = s[s.size() - 1]; 232 | //qDebug() << "isActivationCharSequence" << s; 233 | if( c == '.' || c == '`' ) 234 | return 0; 235 | if( s.size() < 2 ) 236 | return 1; 237 | c = s[s.size() - 2]; 238 | if( c == '.' || c == '`' ) 239 | return -1; 240 | if( s.size() < 3 ) 241 | return 1; 242 | if( isInIdentChar(c) && isInIdentChar(s[s.size()-2]) && isFirstIdentChar(s[s.size() - 3]) ) 243 | { 244 | if( s.size() < 4 || !isInIdentChar(s[s.size()-4]) ) 245 | return -3; // Start of document; actually s includes strange content when at start of document 246 | } 247 | return 1; 248 | #endif 249 | } 250 | 251 | TextEditor::IAssistProvider::RunType CompletionAssistProvider::runType() const 252 | { 253 | return TextEditor::IAssistProvider::Synchronous; 254 | } 255 | 256 | bool CompletionAssistProvider::supportsEditor(Core::Id editorId) const 257 | { 258 | return editorId == Constants::EditorId1; 259 | } 260 | 261 | TextEditor::IAssistProcessor*CompletionAssistProvider::createProcessor() const 262 | { 263 | return new CompletionAssistProcessor(); 264 | } 265 | 266 | bool CompletionAssistProvider::isActivationCharSequence(const QString& s) const 267 | { 268 | return checkSequence(s,SeqLen-1) <= 0; 269 | } 270 | 271 | bool CompletionAssistProvider::isContinuationChar(const QChar& c) const 272 | { 273 | //qDebug() << "isContinuationChar" << c; 274 | return c.isLetterOrNumber() || c == '_' || c == '$'; 275 | } 276 | -------------------------------------------------------------------------------- /VlCompletionAssistProvider.h: -------------------------------------------------------------------------------- 1 | #ifndef VLCOMPLETIONASSISTPROVIDER_H 2 | #define VLCOMPLETIONASSISTPROVIDER_H 3 | 4 | /* 5 | * Copyright 2019 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | namespace Vl 28 | { 29 | class CompletionAssistProvider : public TextEditor::CompletionAssistProvider 30 | { 31 | Q_OBJECT 32 | public: 33 | enum { SeqLen = 4 }; 34 | 35 | static int checkSequence(const QString& , int minLen = 1 ); 36 | 37 | // overrides 38 | RunType runType() const; 39 | bool supportsEditor(Core::Id editorId) const; 40 | TextEditor::IAssistProcessor* createProcessor() const; 41 | int activationCharSequenceLength() const { return SeqLen; } 42 | bool isActivationCharSequence(const QString &sequence) const; 43 | bool isContinuationChar(const QChar &c) const; 44 | }; 45 | } 46 | 47 | #endif // VLCOMPLETIONASSISTPROVIDER_H 48 | -------------------------------------------------------------------------------- /VlConfigurationFactory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlConfigurationFactory.h" 21 | #include "VlProject.h" 22 | #include "VlIcarusConfiguration.h" 23 | #include "VlVerilatorConfiguration.h" 24 | #include "VlYosysConfiguration.h" 25 | #include "VlTclConfiguration.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | using namespace Vl; 33 | 34 | BuildConfigurationFactory::BuildConfigurationFactory(QObject* parent): 35 | IBuildConfigurationFactory(parent) 36 | { 37 | 38 | } 39 | 40 | int BuildConfigurationFactory::priority(const ProjectExplorer::Target* parent) const 41 | { 42 | return canHandle(parent) ? 0 : -1; 43 | } 44 | 45 | QList BuildConfigurationFactory::availableBuilds(const ProjectExplorer::Target* parent) const 46 | { 47 | QList result; 48 | /* 49 | ProjectExplorer::BuildInfo *info = new ProjectExplorer::BuildInfo(this); 50 | info->typeName = tr("Test Build 1"); 51 | info->kitId = parent->kit()->id(); 52 | result << info; 53 | info = new ProjectExplorer::BuildInfo(this); 54 | info->typeName = tr("Test Build 2"); 55 | info->kitId = parent->kit()->id(); 56 | result << info; 57 | */ 58 | return result; 59 | } 60 | 61 | int BuildConfigurationFactory::priority(const ProjectExplorer::Kit* k, const QString& projectPath) const 62 | { 63 | return 0; 64 | } 65 | 66 | QList BuildConfigurationFactory::availableSetups(const ProjectExplorer::Kit* k, 67 | const QString& projectPath) const 68 | { 69 | // projectPath ist der Pfad zur vlpro-Datei 70 | QList result; 71 | ProjectExplorer::BuildInfo* info = new ProjectExplorer::BuildInfo(this); 72 | info->typeName = IcarusBuildConfig::ID; 73 | info->displayName = IcarusRunConfiguration::Name; 74 | info->buildDirectory = Utils::FileName::fromString(QFileInfo(projectPath).path()); 75 | info->kitId = k->id(); 76 | result << info; 77 | info = new ProjectExplorer::BuildInfo(this); 78 | info->typeName = VerilatorBuildConfig::ID; 79 | info->displayName = VerilatorBuildConfig::Name; 80 | info->buildDirectory = Utils::FileName::fromString(QFileInfo(projectPath).path()); 81 | info->kitId = k->id(); 82 | result << info; 83 | info = new ProjectExplorer::BuildInfo(this); 84 | info->typeName = YosysBuildConfig::ID; 85 | info->displayName = YosysBuildConfig::Name; 86 | info->buildDirectory = Utils::FileName::fromString(QFileInfo(projectPath).path()); 87 | info->kitId = k->id(); 88 | result << info; 89 | info = new ProjectExplorer::BuildInfo(this); 90 | info->typeName = TclBuildConfig::ID; 91 | info->displayName = TclRunConfiguration::Name; 92 | info->buildDirectory = Utils::FileName::fromString(QFileInfo(projectPath).path()); 93 | info->kitId = k->id(); 94 | result << info; 95 | return result; 96 | } 97 | 98 | ProjectExplorer::BuildConfiguration* BuildConfigurationFactory::create(ProjectExplorer::Target* parent, 99 | const ProjectExplorer::BuildInfo* info) const 100 | { 101 | // Wird aufgerufen, wenn Projekt neu erstellt wird bzw. restore noch nicht vorhanden ist 102 | //qDebug() << "BuildConfigurationFactory::create" << info->typeName; 103 | if( info->typeName == IcarusBuildConfig::ID ) 104 | return IcarusBuildConfig::create( parent, info ); 105 | else if( info->typeName == VerilatorBuildConfig::ID ) 106 | return VerilatorBuildConfig::create( parent, info ); 107 | else if( info->typeName == TclBuildConfig::ID ) 108 | return TclBuildConfig::create( parent, info ); 109 | else if( info->typeName == YosysBuildConfig::ID ) 110 | return YosysBuildConfig::create( parent, info ); 111 | else 112 | return 0; 113 | } 114 | 115 | bool BuildConfigurationFactory::canClone(const ProjectExplorer::Target* parent, ProjectExplorer::BuildConfiguration* source) const 116 | { 117 | // Wird nicht direkt aufgerufen, sondern clone wird direkt aufgerufen, wenn in GUI gewählt 118 | Q_UNUSED(parent); 119 | //qDebug() << "BuildConfigurationFactory::canClone" << source->id().toString(); 120 | return false; 121 | // if (!canHandle(parent)) 122 | // return false; 123 | // return source->id() == Constants::BuildConfigId || source->id() == IcarusBuildConfig::ID; 124 | } 125 | 126 | ProjectExplorer::BuildConfiguration* BuildConfigurationFactory::clone(ProjectExplorer::Target* parent, ProjectExplorer::BuildConfiguration* source) 127 | { 128 | //qDebug() << "BuildConfigurationFactory::clone" << source->id().toString(); 129 | if (!canClone(parent, source)) 130 | return 0; 131 | if( IcarusBuildConfig* bc = qobject_cast(source) ) 132 | return new IcarusBuildConfig(parent, bc ); 133 | else if( VerilatorBuildConfig* bc = qobject_cast(source) ) 134 | return new VerilatorBuildConfig(parent, bc ); 135 | else if( TclBuildConfig* bc = qobject_cast(source) ) 136 | return new TclBuildConfig(parent, bc ); 137 | else if( YosysBuildConfig* bc = qobject_cast(source) ) 138 | return new YosysBuildConfig(parent, bc ); 139 | else 140 | return 0; 141 | } 142 | 143 | bool BuildConfigurationFactory::canRestore(const ProjectExplorer::Target* parent, const QVariantMap& map) const 144 | { 145 | Q_UNUSED(parent); 146 | if (!canHandle(parent)) 147 | return false; 148 | const Core::Id id = ProjectExplorer::idFromMap(map); 149 | return id == IcarusBuildConfig::ID || id == VerilatorBuildConfig::ID || 150 | id == YosysBuildConfig::ID || id == TclBuildConfig::ID; 151 | } 152 | 153 | ProjectExplorer::BuildConfiguration* BuildConfigurationFactory::restore(ProjectExplorer::Target* parent, const QVariantMap& map) 154 | { 155 | if (!canRestore(parent, map)) 156 | return 0; 157 | ProjectExplorer::BuildConfiguration* bc = 0; 158 | const Core::Id id = ProjectExplorer::idFromMap(map); 159 | if( id == IcarusBuildConfig::ID ) 160 | bc = new IcarusBuildConfig(parent); 161 | else if( id == VerilatorBuildConfig::ID ) 162 | bc = new VerilatorBuildConfig(parent); 163 | else if( id == TclBuildConfig::ID ) 164 | bc = new TclBuildConfig(parent); 165 | else if( id == YosysBuildConfig::ID ) 166 | bc = new YosysBuildConfig(parent); 167 | if( bc && bc->fromMap(map) ) 168 | return bc; 169 | if( bc ) 170 | delete bc; 171 | return 0; 172 | } 173 | 174 | bool BuildConfigurationFactory::canHandle(const ProjectExplorer::Target* t) const 175 | { 176 | Vl::Project* p = dynamic_cast( t->project() ); 177 | //qDebug() << t->toMap() << p; 178 | return p != 0; 179 | } 180 | 181 | MakeStepFactory::MakeStepFactory(QObject* parent): 182 | IBuildStepFactory(parent) 183 | { 184 | 185 | } 186 | 187 | bool MakeStepFactory::canCreate(ProjectExplorer::BuildStepList* parent, Core::Id id) const 188 | { 189 | Q_UNUSED(parent); 190 | if( id == TclStep::ID ) 191 | return true; 192 | return false; 193 | } 194 | 195 | ProjectExplorer::BuildStep* MakeStepFactory::create(ProjectExplorer::BuildStepList* parent, Core::Id id) 196 | { 197 | Q_UNUSED(parent); 198 | //qDebug() << "MakeStepFactory::create" << id.toString(); 199 | if( id == TclStep::ID ) 200 | return new TclStep(parent); 201 | else 202 | return 0; 203 | } 204 | 205 | bool MakeStepFactory::canClone(ProjectExplorer::BuildStepList* parent, ProjectExplorer::BuildStep* source) const 206 | { 207 | return false; // source->id() == IcarusMakeStep::ID || source->id() == IcarusCleanStep::ID; 208 | } 209 | 210 | ProjectExplorer::BuildStep* MakeStepFactory::clone(ProjectExplorer::BuildStepList* parent, ProjectExplorer::BuildStep* source) 211 | { 212 | return 0; 213 | } 214 | 215 | bool MakeStepFactory::canRestore(ProjectExplorer::BuildStepList* parent, const QVariantMap& map) const 216 | { 217 | Q_UNUSED(parent); 218 | const Core::Id id = ProjectExplorer::idFromMap(map); 219 | return id == IcarusMakeStep::ID || id == IcarusCleanStep::ID || 220 | id == VerilatorMakeStep::ID || id == VerilatorCleanStep::ID || 221 | id == TclStep::ID || 222 | id == YosysMakeStep::ID || id == YosysCleanStep::ID; 223 | } 224 | 225 | ProjectExplorer::BuildStep* MakeStepFactory::restore(ProjectExplorer::BuildStepList* parent, const QVariantMap& map) 226 | { 227 | if (!canRestore(parent, map)) 228 | return 0; 229 | ProjectExplorer::BuildStep* bs = 0; 230 | const Core::Id id = ProjectExplorer::idFromMap(map); 231 | if( id == IcarusMakeStep::ID ) 232 | bs = new IcarusMakeStep(parent); 233 | else if( id == IcarusCleanStep::ID ) 234 | bs = new IcarusCleanStep(parent); 235 | else if( id == VerilatorMakeStep::ID ) 236 | bs = new VerilatorMakeStep(parent); 237 | else if( id == VerilatorCleanStep::ID ) 238 | bs = new VerilatorCleanStep(parent); 239 | else if( id == TclStep::ID ) 240 | bs = new TclStep(parent); 241 | else if( id == YosysMakeStep::ID ) 242 | bs = new YosysMakeStep(parent); 243 | else if( id == YosysCleanStep::ID ) 244 | bs = new YosysCleanStep(parent); 245 | if( bs && bs->fromMap(map) ) 246 | return bs; 247 | if( bs ) 248 | delete bs; 249 | return 0; 250 | } 251 | 252 | QList MakeStepFactory::availableCreationIds(ProjectExplorer::BuildStepList* bc) const 253 | { 254 | Q_UNUSED(bc); 255 | // Die hier angegebenen Steps erscheinen in der Create-Liste der Steps 256 | // canCreate wird dann gar nicht mehr abgefragt, sondern direkt create aufgerufen 257 | QList result; 258 | result << TclStep::ID; 259 | return result; 260 | } 261 | 262 | QString MakeStepFactory::displayNameForId(Core::Id id) const 263 | { 264 | Q_UNUSED(id); 265 | if( id == TclStep::ID ) 266 | return tr("TCL Step"); 267 | return QString(); 268 | } 269 | 270 | 271 | RunConfigurationFactory::RunConfigurationFactory(QObject* parent) 272 | { 273 | 274 | } 275 | 276 | bool RunConfigurationFactory::canCreate(ProjectExplorer::Target* parent, Core::Id id) const 277 | { 278 | return true; 279 | } 280 | 281 | bool RunConfigurationFactory::canRestore(ProjectExplorer::Target* parent, const QVariantMap& map) const 282 | { 283 | return true; 284 | } 285 | 286 | bool RunConfigurationFactory::canClone(ProjectExplorer::Target* parent, ProjectExplorer::RunConfiguration* product) const 287 | { 288 | return false; 289 | } 290 | 291 | ProjectExplorer::RunConfiguration*RunConfigurationFactory::clone(ProjectExplorer::Target* parent, ProjectExplorer::RunConfiguration* product) 292 | { 293 | return 0; 294 | } 295 | 296 | QList RunConfigurationFactory::availableCreationIds(ProjectExplorer::Target* parent, ProjectExplorer::IRunConfigurationFactory::CreationMode mode) const 297 | { 298 | Q_UNUSED(mode); 299 | QList result; 300 | if( parent->project()->id() == Project::ID ) 301 | result << IcarusRunConfiguration::ID; // << TclRunConfiguration::ID; // << VerilatorRunConfiguration::ID; 302 | return result; 303 | } 304 | 305 | QString RunConfigurationFactory::displayNameForId(Core::Id id) const 306 | { 307 | if( id == IcarusRunConfiguration::ID ) 308 | return IcarusRunConfiguration::Name; 309 | else if( id == TclRunConfiguration::ID ) 310 | return TclRunConfiguration::Name; 311 | else 312 | return QString(); 313 | } 314 | 315 | ProjectExplorer::RunConfiguration* RunConfigurationFactory::doCreate(ProjectExplorer::Target* parent, Core::Id id) 316 | { 317 | if( id == IcarusRunConfiguration::ID ) 318 | return new IcarusRunConfiguration(parent); 319 | else if( id == TclRunConfiguration::ID ) 320 | return new TclRunConfiguration(parent); 321 | else 322 | return 0; 323 | } 324 | 325 | ProjectExplorer::RunConfiguration* RunConfigurationFactory::doRestore(ProjectExplorer::Target* parent, const QVariantMap& map) 326 | { 327 | const Core::Id id = ProjectExplorer::idFromMap(map); 328 | if( id == IcarusRunConfiguration::ID ) 329 | return new IcarusRunConfiguration(parent); 330 | else if( id == TclRunConfiguration::ID ) 331 | return new TclRunConfiguration(parent); 332 | else 333 | return 0; 334 | } 335 | -------------------------------------------------------------------------------- /VlConfigurationFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef VLCONFIGURATIONFACTORY_H 2 | #define VLCONFIGURATIONFACTORY_H 3 | 4 | /* 5 | * Copyright 2018 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | namespace Vl 28 | { 29 | class BuildConfigurationFactory : public ProjectExplorer::IBuildConfigurationFactory 30 | { 31 | Q_OBJECT 32 | public: 33 | explicit BuildConfigurationFactory(QObject *parent = 0); 34 | 35 | int priority(const ProjectExplorer::Target *parent) const; 36 | QList availableBuilds(const ProjectExplorer::Target *parent) const; 37 | int priority(const ProjectExplorer::Kit *k, const QString &projectPath) const; 38 | QList availableSetups(const ProjectExplorer::Kit *k, 39 | const QString &projectPath) const; 40 | ProjectExplorer::BuildConfiguration *create(ProjectExplorer::Target *parent, 41 | const ProjectExplorer::BuildInfo *info) const; 42 | 43 | bool canClone(const ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const; 44 | ProjectExplorer::BuildConfiguration *clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source); 45 | bool canRestore(const ProjectExplorer::Target *parent, const QVariantMap &map) const; 46 | ProjectExplorer::BuildConfiguration *restore(ProjectExplorer::Target *parent, const QVariantMap &map); 47 | 48 | private: 49 | bool canHandle(const ProjectExplorer::Target *t) const; 50 | 51 | }; 52 | 53 | class MakeStepFactory : public ProjectExplorer::IBuildStepFactory 54 | { 55 | Q_OBJECT 56 | public: 57 | explicit MakeStepFactory(QObject *parent = 0); 58 | 59 | bool canCreate(ProjectExplorer::BuildStepList *parent, Core::Id id) const; 60 | ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, Core::Id id); 61 | bool canClone(ProjectExplorer::BuildStepList *parent, 62 | ProjectExplorer::BuildStep *source) const; 63 | ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent, 64 | ProjectExplorer::BuildStep *source); 65 | bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const; 66 | ProjectExplorer::BuildStep *restore(ProjectExplorer::BuildStepList *parent, 67 | const QVariantMap &map); 68 | 69 | QList availableCreationIds(ProjectExplorer::BuildStepList *bc) const; 70 | QString displayNameForId(Core::Id id) const; 71 | }; 72 | 73 | class RunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory 74 | { 75 | Q_OBJECT 76 | 77 | public: 78 | explicit RunConfigurationFactory(QObject *parent = 0); 79 | 80 | bool canCreate(ProjectExplorer::Target *parent, Core::Id id) const; 81 | bool canRestore(ProjectExplorer::Target *parent, const QVariantMap &map) const; 82 | bool canClone(ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *product) const; 83 | ProjectExplorer::RunConfiguration* clone(ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *product); 84 | 85 | QList availableCreationIds(ProjectExplorer::Target *parent, CreationMode mode) const; 86 | QString displayNameForId(Core::Id id) const; 87 | 88 | private: 89 | ProjectExplorer::RunConfiguration* doCreate(ProjectExplorer::Target *parent, Core::Id id); 90 | ProjectExplorer::RunConfiguration* doRestore(ProjectExplorer::Target *parent, 91 | const QVariantMap &map); 92 | }; 93 | } 94 | 95 | #endif // VLCONFIGURATIONFACTORY_H 96 | -------------------------------------------------------------------------------- /VlConstants.h: -------------------------------------------------------------------------------- 1 | #ifndef VLCONSTANTS_H 2 | #define VLCONSTANTS_H 3 | 4 | /* 5 | * Copyright 2018 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | namespace Vl 24 | { 25 | namespace Constants 26 | { 27 | const char LangVerilog[] = "Verilog"; 28 | const char LangQmake[] = "Qmake"; 29 | const char LangSdf[] = "Sdf"; 30 | const char EditorId1[] = "Verilog.Editor"; 31 | const char TaskId[] = "Verilog.TaskId"; 32 | const char EditorDisplayName1[] = "Verilog Editor"; 33 | const char EditorId2[] = "Verilog.Project.Editor"; 34 | const char EditorDisplayName2[] = "Verilog Project Editor"; 35 | const char MimeType[] = "text/x-verilog"; 36 | const char ProjectMimeType[] = "text/x-verilogcreator-project"; 37 | const char EditorId3[] = "Verilog.Sdf.Editor"; 38 | const char EditorDisplayName3[] = "Sdf Editor"; 39 | const char SdfMimeType[] = "text/x-verilogcreator-sdf"; 40 | const char SettingsId[] = "Verilog.Settings"; 41 | const char EditorContextMenuId1[] = "VerilogEditor.ContextMenu"; 42 | const char EditorContextMenuId2[] = "VerilogProjectEditor.ContextMenu"; 43 | const char ToolsMenuId[] = "VerilogTools.ToolsMenu"; 44 | const char FindUsagesCmd[] = "VerilogEditor.FindUsages"; 45 | const char GotoOuterBlockCmd[] = "VerilogEditor.GotoOuterBlockCmd"; 46 | const char ReloadProjectCmd[] = "VerilogEditor.ReloadProjectCmd"; 47 | } 48 | } 49 | 50 | #endif // VLCONSTANTS_H 51 | -------------------------------------------------------------------------------- /VlEditor.mimetypes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Verilog project file 6 | 7 | 8 | 9 | 10 | Verilog source file 11 | 12 | 13 | 14 | 15 | 16 | 17 | Sdf file 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /VlHighlighter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlHighlighter.h" 21 | #include "VlModelManager.h" 22 | #include 23 | #include 24 | #include 25 | using namespace Vl; 26 | using namespace TextEditor; 27 | 28 | VerilogHighlighter::VerilogHighlighter(QTextDocument* parent) : 29 | SyntaxHighlighter(parent) 30 | { 31 | for( int i = 0; i < C_Max; i++ ) 32 | { 33 | d_format[i].setFontWeight(QFont::Normal); 34 | //d_format[i].setUnderlineStyle(QTextCharFormat::NoUnderline); 35 | d_format[i].setForeground(Qt::black); 36 | d_format[i].setBackground(Qt::transparent); 37 | } 38 | d_format[C_Num].setForeground(QColor(0, 153, 153)); 39 | d_format[C_Str].setForeground(QColor(208, 16, 64)); 40 | d_format[C_Cmt].setForeground(QColor(153, 153, 136)); 41 | d_format[C_Kw].setForeground(QColor(68, 85, 136)); 42 | d_format[C_Kw].setFontWeight(QFont::Bold); 43 | d_format[C_Op].setForeground(QColor(153, 0, 0)); 44 | d_format[C_Op].setFontWeight(QFont::Bold); 45 | d_format[C_Type].setForeground(QColor(153, 0, 115)); 46 | d_format[C_Type].setFontWeight(QFont::Bold); 47 | d_format[C_Pp].setForeground(QColor(0, 134, 179)); 48 | d_format[C_Pp].setFontWeight(QFont::Bold); 49 | 50 | d_format[C_Section].setForeground(QColor(0, 128, 0)); 51 | d_format[C_Section].setBackground(QColor(230, 255, 230)); 52 | //d_format[C_Section].setFontWeight(QFont::Bold); 53 | //d_format[C_Section].setFontUnderline(true); 54 | //d_format[C_Section].setUnderlineColor(QColor(0, 200, 0)); 55 | //d_format[C_Section].setFontOverline(true); 56 | } 57 | 58 | QTextCharFormat VerilogHighlighter::formatForCategory(int c) const 59 | { 60 | return d_format[c]; 61 | } 62 | 63 | void VerilogHighlighter::highlightBlock(const QString& text) 64 | { 65 | const int previousBlockState_ = previousBlockState(); 66 | int lexerState = 0, initialBraceDepth = 0; 67 | if (previousBlockState_ != -1) { 68 | lexerState = previousBlockState_ & 0xff; 69 | initialBraceDepth = previousBlockState_ >> 8; 70 | } 71 | 72 | int braceDepth = initialBraceDepth; 73 | int foldingIndent = initialBraceDepth; 74 | 75 | if (TextBlockUserData *userData = TextDocumentLayout::testUserData(currentBlock())) { 76 | userData->setFoldingIndent(0); 77 | userData->setFoldingStartIncluded(false); 78 | userData->setFoldingEndIncluded(false); 79 | } 80 | 81 | int start = 0; 82 | if( lexerState == 1 ) 83 | { 84 | // wir sind in einem Multi Line Comment 85 | // suche das Ende 86 | QTextCharFormat f = formatForCategory(C_Cmt); 87 | f.setProperty( TokenProp, int(Tok_Comment) ); 88 | int pos = text.indexOf("*/"); 89 | if( pos == -1 ) 90 | { 91 | // the whole block ist part of the comment 92 | setFormat( start, text.size(), f ); 93 | TextDocumentLayout::clearParentheses(currentBlock()); 94 | TextDocumentLayout::setFoldingIndent(currentBlock(), foldingIndent); 95 | setCurrentBlockState( (braceDepth << 8) | lexerState); 96 | return; 97 | }else 98 | { 99 | // End of Comment found 100 | pos += 2; 101 | setFormat( start, pos , f ); 102 | lexerState = 0; 103 | braceDepth--; 104 | start = pos; 105 | } 106 | } 107 | 108 | Parentheses parentheses; 109 | parentheses.reserve(20); 110 | 111 | PpLexer lex; 112 | lex.setIgnoreAttrs(false); 113 | lex.setPackAttrs(false); 114 | lex.setIgnoreComments(false); 115 | lex.setPackComments(false); 116 | lex.setSendMacroUsage(true); 117 | if( ModelManager::instance()->getLastUsed() ) 118 | lex.setCache( ModelManager::instance()->getLastUsed()->getFcache() ); 119 | 120 | const QList tokens = lex.tokens(text.mid(start)); 121 | for( int i = 0; i < tokens.size(); ++i ) 122 | { 123 | const Token &t = tokens.at(i); 124 | 125 | if( t.d_substituted ) 126 | continue; 127 | 128 | QTextCharFormat f; 129 | if( t.d_type == Tok_Comment ) 130 | f = formatForCategory(C_Cmt); // one line comment 131 | else if( t.d_type == Tok_Section ) 132 | { 133 | braceDepth++; 134 | f = formatForCategory(C_Section); 135 | //f.setFontOverline(true); 136 | // setExtraAdditionalFormats funktioniert nicht 137 | }else if( t.d_type == Tok_SectionEnd ) 138 | { 139 | braceDepth--; 140 | f = formatForCategory(C_Section); 141 | // f.setFontUnderline(true); 142 | }else if( t.d_type == Tok_Lcmt ) 143 | { 144 | braceDepth++; 145 | f = formatForCategory(C_Cmt); 146 | lexerState = 1; 147 | }else if( t.d_type == Tok_Rcmt ) 148 | { 149 | braceDepth--; 150 | f = formatForCategory(C_Cmt); 151 | lexerState = 0; 152 | }else if( t.d_type == Tok_Str ) 153 | f = formatForCategory(C_Str); 154 | else if( tokenIsNumber(t.d_type) ) 155 | f = formatForCategory(C_Num); 156 | else if( tokenIsDelimiter(t.d_type) ) 157 | { 158 | switch( t.d_type ) 159 | { 160 | case Tok_Lpar: 161 | case Tok_Lbrack: 162 | case Tok_Lbrace: 163 | //case Tok_Latt: 164 | parentheses.append(Parenthesis(Parenthesis::Opened, text[t.d_colNr-1], t.d_colNr-1 )); 165 | break; 166 | case Tok_Rpar: 167 | case Tok_Rbrack: 168 | case Tok_Rbrace: 169 | //case Tok_Ratt: 170 | parentheses.append(Parenthesis(Parenthesis::Closed, text[t.d_colNr-1], t.d_colNr-1 )); 171 | break; 172 | } 173 | if( t.d_type == Tok_LineCont ) 174 | f = formatForCategory(C_Pp); 175 | else 176 | //if( tokenIsOperator(t.d_type) ) 177 | f = formatForCategory(C_Op); 178 | // else if( tokenIsBracket(t.d_type) ) 179 | // f = formatForCategory(C_Brack); 180 | }else if( tokenIsReservedWord(t.d_type) ) 181 | { 182 | if( tokenIsBlockBegin(t.d_type) ) 183 | { 184 | parentheses.append(Parenthesis(Parenthesis::Opened, text[t.d_colNr-1], t.d_colNr-1 )); 185 | ++braceDepth; 186 | // if a folding block opens at the beginning of a line, treat the entire line 187 | // as if it were inside the folding block 188 | if ( i == 0 && ( t.d_type == Tok_begin || t.d_type == Tok_fork ) ) 189 | { 190 | ++foldingIndent; 191 | TextDocumentLayout::userData(currentBlock())->setFoldingStartIncluded(true); 192 | } 193 | }else if( tokenIsBlockEnd(t.d_type) ) 194 | { 195 | const int pos = t.d_colNr-1 + ::strlen(tokenToString(t.d_type))-1; 196 | parentheses.append(Parenthesis(Parenthesis::Closed, text[pos], pos )); 197 | --braceDepth; 198 | if (braceDepth < foldingIndent) { 199 | // unless we are at the end of the block, we reduce the folding indent 200 | if (i == tokens.size()-1 || tokens.at(i+1).d_type == Tok_Semi ) 201 | TextDocumentLayout::userData(currentBlock())->setFoldingEndIncluded(true); 202 | else 203 | foldingIndent = qMin(braceDepth, foldingIndent); 204 | } 205 | } 206 | if( tokenIsType(t.d_type) ) 207 | f = formatForCategory(C_Type); 208 | else 209 | f = formatForCategory(C_Kw); 210 | }else if( t.d_type == Tok_Ident ) 211 | f = formatForCategory(C_Ident); 212 | else if( t.d_type == Tok_SysName ) 213 | f = formatForCategory(C_Kw); 214 | else if( t.d_type == Tok_CoDi ) 215 | { 216 | Directive di = matchDirective(t.d_val); 217 | switch(di) 218 | { 219 | case Cd_ifdef: 220 | case Cd_ifndef: 221 | braceDepth++; 222 | break; 223 | case Cd_else: 224 | case Cd_elsif: 225 | foldingIndent--; 226 | break; 227 | case Cd_endif: 228 | braceDepth--; 229 | break; 230 | default: 231 | break; 232 | } 233 | 234 | f = formatForCategory(C_Pp); 235 | } 236 | 237 | if( f.isValid() ) 238 | { 239 | f.setProperty( TokenProp, int(t.d_type) ); 240 | setFormat( t.d_colNr-1, t.d_len, f ); 241 | } 242 | } 243 | 244 | TextDocumentLayout::setParentheses(currentBlock(), parentheses); 245 | // if the block is ifdefed out, we only store the parentheses, but 246 | 247 | // do not adjust the brace depth. 248 | if (TextDocumentLayout::ifdefedOut(currentBlock())) { 249 | braceDepth = initialBraceDepth; 250 | foldingIndent = initialBraceDepth; 251 | } 252 | 253 | TextDocumentLayout::setFoldingIndent(currentBlock(), foldingIndent); 254 | setCurrentBlockState((braceDepth << 8) | lexerState ); 255 | } 256 | 257 | 258 | 259 | -------------------------------------------------------------------------------- /VlHighlighter.h: -------------------------------------------------------------------------------- 1 | #ifndef VLHIGHLIGHTER_H 2 | #define VLHIGHLIGHTER_H 3 | 4 | /* 5 | * Copyright 2018 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | namespace Vl 27 | { 28 | class VerilogHighlighter : public TextEditor::SyntaxHighlighter 29 | { 30 | public: 31 | enum { TokenProp = QTextFormat::UserProperty }; 32 | explicit VerilogHighlighter(QTextDocument *parent = 0); 33 | 34 | protected: 35 | QTextCharFormat formatForCategory(int) const; 36 | 37 | // overrides 38 | void highlightBlock(const QString &text); 39 | 40 | private: 41 | enum Category { C_Num, C_Str, C_Kw, C_Type, C_Ident, C_Op, C_Pp, C_Cmt, C_Section, C_Brack, C_Max }; 42 | QTextCharFormat d_format[C_Max]; 43 | }; 44 | 45 | } 46 | 47 | #endif // VLHIGHLIGHTER_H 48 | -------------------------------------------------------------------------------- /VlHoverHandler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlHoverHandler.h" 21 | #include "VlModelManager.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | using namespace Vl; 35 | 36 | VerilogHoverHandler::VerilogHoverHandler() 37 | { 38 | 39 | } 40 | 41 | static inline bool isCond( Directive di ) 42 | { 43 | return di == Cd_ifdef || di == Cd_ifndef || di == Cd_elsif || di == Cd_undef; 44 | } 45 | 46 | static inline QByteArray escape( QByteArray str ) 47 | { 48 | return str.trimmed(); 49 | } 50 | 51 | static QString prettyPrint( const PpSymbols::Define& d ) 52 | { 53 | QString str; 54 | QTextStream out( &str, QIODevice::WriteOnly ); 55 | 56 | out << "`define " << d.d_name; 57 | if( !d.d_args.isEmpty() ) 58 | { 59 | out << "( "; 60 | out << d.d_args.join(", "); 61 | out << " ) "; 62 | }else 63 | out << " "; 64 | 65 | foreach( const Token& t, d.d_toks ) 66 | { 67 | if( t.d_type < TT_Specials ) 68 | out << t.getName(); 69 | else if( t.d_type == Tok_Str ) 70 | out << "\"" << escape(t.d_val) << "\""; 71 | else if( t.d_type == Tok_SysName ) 72 | out << "$" << t.d_val; 73 | else 74 | out << t.d_val; 75 | out << " "; 76 | } 77 | 78 | return str; 79 | } 80 | 81 | void VerilogHoverHandler::identifyMatch(TextEditor::TextEditorWidget* editorWidget, int pos) 82 | { 83 | QString text = editorWidget->extraSelectionTooltip(pos); 84 | 85 | if( !text.isEmpty() ) 86 | { 87 | setToolTip(text); 88 | return; 89 | } 90 | // else 91 | 92 | QTextCursor cur(editorWidget->document()); 93 | cur.setPosition(pos); 94 | 95 | const QString file = editorWidget->textDocument()->filePath().toString(); 96 | CrossRefModel* mdl = ModelManager::instance()->getModelForCurrentProjectOrDirPath(file); 97 | 98 | const int line = cur.blockNumber() + 1; 99 | const int col = cur.columnNumber() + 1; 100 | 101 | int tokPos; 102 | QList toks = CrossRefModel::findTokenByPos( cur.block().text(), col, &tokPos, 103 | mdl->getFcache()->supportSvExt(file) ); 104 | if( tokPos != -1 ) 105 | { 106 | const Token& t = toks[tokPos]; 107 | if( t.d_type == Tok_CoDi && matchDirective(t.d_val) == Cd_Invalid ) 108 | { 109 | PpSymbols::Define d = mdl->getSyms()->getSymbol( t.d_val ); 110 | if( !d.d_name.isEmpty() ) 111 | setToolTip( prettyPrint(d) ); 112 | }else if( t.d_type == Tok_Str && tokPos > 0 && toks[tokPos-1].d_type == Tok_CoDi && 113 | matchDirective(toks[tokPos-1].d_val) == Cd_include ) 114 | { 115 | const QString path = mdl->getIncs()->findPath( t.d_val, file ); 116 | if( !path.isEmpty() ) 117 | setToolTip( path ); 118 | }else if( t.d_type == Tok_Ident && tokPos > 0 && toks[tokPos-1].d_type == Tok_CoDi && 119 | isCond( matchDirective( toks[tokPos-1].d_val) ) ) 120 | { 121 | PpSymbols::Define d = mdl->getSyms()->getSymbol( t.d_val ); 122 | if( !d.d_name.isEmpty() ) 123 | setToolTip( prettyPrint(d) ); 124 | }else if( t.d_type == Tok_Ident ) 125 | { 126 | CrossRefModel::TreePath path = mdl->findSymbolBySourcePos( file, line, col ); 127 | if( path.isEmpty() ) 128 | return; 129 | CrossRefModel::IdentDeclRef decl = mdl->findDeclarationOfSymbol(path.first().data()); 130 | if( decl.data() == 0 ) 131 | return; 132 | // qDebug() << "declared" << decl->decl()->tok().d_sourcePath << decl->decl()->tok().d_lineNr; 133 | FileCache* fcache = ModelManager::instance()->getFileCache(); 134 | const QByteArray line = fcache->fetchTextLineFromFile( 135 | decl->decl()->tok().d_sourcePath, decl->decl()->tok().d_lineNr ); 136 | QTextStream out(&text); 137 | QStringList parts = CrossRefModel::qualifiedNameParts(path,true); 138 | for( int l = 0; l < parts.size(); l++ ) 139 | { 140 | if( l != 0 ) 141 | out << endl << QString(l*3,QChar(' ')) << QChar('.'); 142 | out << parts[l]; 143 | } 144 | int len = decl->decl()->tok().d_len; 145 | if( len == 0 ) 146 | len = -1; 147 | // TODO: für Ports in alter Delkaration nicht optimal 148 | out << endl << QString::fromLatin1(line.mid(decl->decl()->tok().d_colNr-1,len).simplified()) 149 | << " " << QString::fromLatin1(decl->tok().d_val); 150 | if( decl->decl()->tok().d_sourcePath != file ) 151 | out << endl << tr("declared in ") << QFileInfo(decl->decl()->tok().d_sourcePath).fileName(); 152 | setToolTip( text ); 153 | // NOTE: mit html funktioniert es nicht! 154 | } 155 | } 156 | } 157 | 158 | -------------------------------------------------------------------------------- /VlHoverHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef VLHOVERHANDLER_H 2 | #define VLHOVERHANDLER_H 3 | 4 | /* 5 | * Copyright 2018 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | 25 | namespace Vl 26 | { 27 | class VerilogHoverHandler : public TextEditor::BaseHoverHandler 28 | { 29 | public: 30 | VerilogHoverHandler(); 31 | void identifyMatch(TextEditor::TextEditorWidget *editorWidget, int pos); 32 | }; 33 | } 34 | 35 | #endif // VLHOVERHANDLER_H 36 | -------------------------------------------------------------------------------- /VlIcarusConfiguration.h: -------------------------------------------------------------------------------- 1 | #ifndef VLICARUSCONFIGURATION_H 2 | #define VLICARUSCONFIGURATION_H 3 | 4 | /* 5 | * Copyright 2018 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | class QLabel; 30 | class QCheckBox; 31 | 32 | namespace Vl 33 | { 34 | class IcarusBuildConfig : public ProjectExplorer::BuildConfiguration 35 | { 36 | Q_OBJECT 37 | public: 38 | static const char* ID; 39 | 40 | explicit IcarusBuildConfig(ProjectExplorer::Target *parent); 41 | 42 | ProjectExplorer::NamedWidget* createConfigWidget(); 43 | BuildType buildType() const; 44 | 45 | static ProjectExplorer::BuildConfiguration* create( ProjectExplorer::Target* parent, 46 | const ProjectExplorer::BuildInfo* info ); 47 | 48 | protected: 49 | IcarusBuildConfig(ProjectExplorer::Target *parent, Core::Id id); 50 | IcarusBuildConfig(ProjectExplorer::Target *parent, IcarusBuildConfig *source); 51 | friend class BuildConfigurationFactory; 52 | friend class IcarusBuildConfigWidget; 53 | }; 54 | 55 | class IcarusBuildConfigWidget : public ProjectExplorer::NamedWidget 56 | { 57 | Q_OBJECT 58 | 59 | public: 60 | IcarusBuildConfigWidget(IcarusBuildConfig *bc); 61 | protected slots: 62 | void buildDirectoryChanged(); 63 | void environmentChanged(); 64 | private: 65 | Utils::PathChooser* d_buildPath; 66 | IcarusBuildConfig* d_conf; 67 | }; 68 | 69 | class IcarusMakeStep : public ProjectExplorer::AbstractProcessStep 70 | { 71 | Q_OBJECT 72 | public: 73 | static const char* ID; 74 | 75 | explicit IcarusMakeStep(ProjectExplorer::BuildStepList *parent); 76 | 77 | bool init(); 78 | void run(QFutureInterface &fi); 79 | bool immutable() const { return false; } 80 | ProjectExplorer::BuildStepConfigWidget* createConfigWidget(); 81 | QVariantMap toMap() const; 82 | protected: 83 | QString makeCommand(const Utils::Environment &environment) const; 84 | bool fromMap(const QVariantMap &map); 85 | private: 86 | QString d_cmd; 87 | QString d_args; 88 | friend class IcarusMakeStepWidget; 89 | }; 90 | 91 | class IcarusMakeStepWidget : public ProjectExplorer::BuildStepConfigWidget 92 | { 93 | Q_OBJECT 94 | 95 | public: 96 | IcarusMakeStepWidget(IcarusMakeStep *makeStep); 97 | QString displayName() const; 98 | QString summaryText() const; 99 | 100 | private slots: 101 | void makeLineEditTextEdited(); 102 | void makeArgumentsLineEditTextEdited(); 103 | void updateMakeOverrrideLabel(); 104 | void updateDetails(); 105 | 106 | private: 107 | IcarusMakeStep* d_step; 108 | QString d_summary; 109 | QLabel* d_cmdLabel; 110 | QLineEdit* d_cmd; 111 | QLineEdit* d_args; 112 | }; 113 | 114 | class IcarusCleanStep : public ProjectExplorer::AbstractProcessStep 115 | { 116 | Q_OBJECT 117 | public: 118 | static const char* ID; 119 | 120 | explicit IcarusCleanStep(ProjectExplorer::BuildStepList *parent); 121 | 122 | bool init(); 123 | void run(QFutureInterface &fi); 124 | bool immutable() const { return true; } 125 | ProjectExplorer::BuildStepConfigWidget* createConfigWidget(); 126 | }; 127 | 128 | class IcarusCleanStepWidget : public ProjectExplorer::BuildStepConfigWidget 129 | { 130 | Q_OBJECT 131 | 132 | public: 133 | IcarusCleanStepWidget(IcarusCleanStep *makeStep); 134 | QString displayName() const; 135 | QString summaryText() const; 136 | }; 137 | 138 | class IcarusRunConfiguration : public ProjectExplorer::LocalApplicationRunConfiguration 139 | { 140 | Q_OBJECT 141 | public: 142 | static const char* ID; 143 | static const char* Name; 144 | 145 | virtual QWidget* createConfigurationWidget(); 146 | virtual QString executable() const; 147 | virtual ProjectExplorer::ApplicationLauncher::Mode runMode() const; 148 | virtual QString workingDirectory() const; 149 | virtual QString commandLineArguments() const; 150 | virtual void addToBaseEnvironment(Utils::Environment &env) const; 151 | QVariantMap toMap() const; 152 | 153 | protected: 154 | explicit IcarusRunConfiguration(ProjectExplorer::Target *target); 155 | explicit IcarusRunConfiguration(ProjectExplorer::Target *target, IcarusRunConfiguration *rc); 156 | virtual bool fromMap(const QVariantMap &map); 157 | friend class RunConfigurationFactory; 158 | friend class IcarusRunConfigWidget; 159 | private: 160 | QString d_cmd; 161 | bool d_terminal; 162 | }; 163 | 164 | class IcarusRunConfigWidget : public QWidget 165 | { 166 | Q_OBJECT 167 | public: 168 | IcarusRunConfigWidget( IcarusRunConfiguration* ); 169 | private slots: 170 | void cmdEdited(); 171 | void termChanged(); 172 | private: 173 | IcarusRunConfiguration* d_cfg; 174 | QLineEdit* d_cmd; 175 | QCheckBox* d_term; 176 | }; 177 | } 178 | 179 | #endif // VLICARUSCONFIGURATION_H 180 | -------------------------------------------------------------------------------- /VlIndenter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlIndenter.h" 21 | #include "VlHighlighter.h" 22 | #include 23 | #include 24 | using namespace Vl; 25 | 26 | static const int TAB_SIZE = 4; 27 | 28 | VerilogIndenter::VerilogIndenter() 29 | { 30 | 31 | } 32 | 33 | bool VerilogIndenter::isElectricCharacter(const QChar& ch) const 34 | { 35 | Q_UNUSED(ch); 36 | return false; 37 | } 38 | 39 | void VerilogIndenter::indentBlock(QTextDocument* doc, const QTextBlock& block, const QChar& typedChar, 40 | const TextEditor::TabSettings& tabSettings) 41 | { 42 | // aus QtCreator texteditor normalindenter adaptiert 43 | // TODO: später mal einen intelligenteren Indenter wie bei C++, ist aber nice to have. 44 | Q_UNUSED(typedChar) 45 | 46 | // At beginning: Leave as is. 47 | if (block == doc->begin()) 48 | return; 49 | 50 | const QTextBlock previous = block.previous(); 51 | const QString previousText = previous.text(); 52 | // Empty line indicates a start of a new paragraph. Leave as is. 53 | if (previousText.isEmpty() || previousText.trimmed().isEmpty()) 54 | return; 55 | 56 | // Just use previous line. 57 | // Skip blank characters when determining the indentation 58 | int i = 0; 59 | while (i < previousText.size()) { 60 | if (!previousText.at(i).isSpace()) { 61 | tabSettings.indentLine(block, tabSettings.columnAt(previousText, i)); 62 | break; 63 | } 64 | ++i; 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /VlIndenter.h: -------------------------------------------------------------------------------- 1 | #ifndef VLINDENTER_H 2 | #define VLINDENTER_H 3 | 4 | /* 5 | * Copyright 2018 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | 25 | namespace Vl 26 | { 27 | class VerilogIndenter : public TextEditor::Indenter 28 | { 29 | public: 30 | VerilogIndenter(); 31 | 32 | // overrides 33 | bool isElectricCharacter(const QChar &ch) const; 34 | void indentBlock(QTextDocument *document, 35 | const QTextBlock &block, 36 | const QChar &typedChar, 37 | const TextEditor::TabSettings &settings); 38 | }; 39 | } 40 | 41 | #endif // VLINDENTER_H 42 | -------------------------------------------------------------------------------- /VlModelManager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlModelManager.h" 21 | #include "VlConstants.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | using namespace Vl; 29 | 30 | ModelManager* ModelManager::d_inst = 0; 31 | 32 | ModelManager::ModelManager(QObject *parent) : QObject(parent),d_lastUsed(0) 33 | { 34 | d_fcache = new FileCache(this); 35 | d_inst = this; 36 | } 37 | 38 | ModelManager::~ModelManager() 39 | { 40 | // Lösche hier explizit damit nicht FileCache gelöscht wird während noch Threads laufen 41 | QHash::const_iterator i; 42 | for( i = d_models.begin(); i != d_models.end(); ++i ) 43 | delete i.value(); 44 | d_inst = 0; 45 | } 46 | 47 | CrossRefModel*ModelManager::getModelForFile(const QString& fileName) 48 | { 49 | if( fileName.isEmpty() ) 50 | return d_lastUsed; 51 | CrossRefModel*& m = d_models[fileName]; 52 | if( m == 0 ) 53 | { 54 | m = new CrossRefModel(this,d_fcache); 55 | connect( m, SIGNAL(sigModelUpdated()), this, SLOT(onModelUpdated()) ); 56 | d_paths[m] = fileName; 57 | } 58 | d_lastUsed = m; 59 | return m; 60 | } 61 | 62 | CrossRefModel*ModelManager::getModelForDir(const QString& dirPath, bool initIfEmpty ) 63 | { 64 | if( dirPath.isEmpty() ) 65 | return 0; 66 | QFileInfo info(dirPath); 67 | CrossRefModel* mdl = getModelForFile( info.path() ); 68 | if( initIfEmpty && mdl->isEmpty() ) 69 | { 70 | QDir dir = info.dir(); 71 | QStringList files = dir.entryList( QStringList() << QString("*.v") 72 | << QString("*.vl"), QDir::Files, QDir::Name ); 73 | for( int i = 0; i < files.size(); i++ ) 74 | files[i] = dir.absoluteFilePath(files[i]); 75 | mdl->updateFiles(files); 76 | } 77 | return mdl; 78 | } 79 | 80 | CrossRefModel*ModelManager::getModelForCurrentProject() 81 | { 82 | CrossRefModel* mdl = 0; 83 | ProjectExplorer::Project *currentProject = ProjectExplorer::ProjectTree::currentProject(); 84 | if( currentProject ) 85 | mdl = getModelForFile(currentProject->projectFilePath().toString()); 86 | if( mdl == 0 ) 87 | mdl = getLastUsed(); 88 | return mdl; 89 | } 90 | 91 | CrossRefModel*ModelManager::getModelForCurrentProjectOrDirPath(const QString& dirPath, bool initIfEmpty) 92 | { 93 | CrossRefModel* mdl = ModelManager::instance()->getModelForCurrentProject(); 94 | if( mdl == 0 ) 95 | mdl = ModelManager::instance()->getModelForDir(dirPath, initIfEmpty); 96 | return mdl; 97 | } 98 | 99 | QString ModelManager::getPathOf(CrossRefModel* m) const 100 | { 101 | return d_paths.value(m); 102 | } 103 | 104 | ModelManager*ModelManager::instance() 105 | { 106 | if( d_inst ) 107 | return d_inst; 108 | new ModelManager(); 109 | return d_inst; 110 | } 111 | 112 | void ModelManager::onModelUpdated() 113 | { 114 | // TODO: optional ein- oder ausschaltbar 115 | 116 | CrossRefModel* mdl = static_cast( sender() ); 117 | 118 | ProjectExplorer::TaskHub::clearTasks( Vl::Constants::TaskId ); 119 | 120 | typedef QPair FileLine; 121 | typedef QPair Message; 122 | typedef QMultiMap Lines; 123 | Lines lines; 124 | Errors::EntriesByFile errs = mdl->getErrs()->getErrors(); 125 | for( Errors::EntriesByFile::const_iterator j = errs.begin(); j != errs.end(); ++j ) 126 | { 127 | foreach (const Errors::Entry& e, j.value() ) 128 | { 129 | lines.insert( qMakePair( j.key(), e.d_line ), qMakePair( e.d_msg, true ) ); 130 | } 131 | } 132 | Errors::EntriesByFile wrns = mdl->getErrs()->getWarnings(); 133 | for( Errors::EntriesByFile::const_iterator j = wrns.begin(); j != wrns.end(); ++j ) 134 | { 135 | foreach (const Errors::Entry& e, j.value() ) 136 | { 137 | lines.insert( qMakePair( j.key(), e.d_line ), qMakePair( e.d_msg, false ) ); 138 | } 139 | } 140 | 141 | for( Lines::const_iterator i = lines.begin(); i != lines.end(); ++i ) 142 | { 143 | // TaskHub sortiert nicht selber 144 | ProjectExplorer::TaskHub::addTask( i.value().second ? ProjectExplorer::Task::Error : ProjectExplorer::Task::Warning, 145 | i.value().first, 146 | Vl::Constants::TaskId, 147 | Utils::FileName::fromString(i.key().first), 148 | i.key().second ); 149 | } 150 | } 151 | 152 | -------------------------------------------------------------------------------- /VlModelManager.h: -------------------------------------------------------------------------------- 1 | #ifndef VLMODELMANAGER_H 2 | #define VLMODELMANAGER_H 3 | 4 | /* 5 | * Copyright 2018 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace Vl 29 | { 30 | class ModelManager : public QObject 31 | { 32 | Q_OBJECT 33 | public: 34 | explicit ModelManager(QObject *parent = 0); 35 | ~ModelManager(); 36 | 37 | CrossRefModel* getModelForFile(const QString& fileName ); 38 | CrossRefModel* getModelForDir(const QString& dirPath , bool initIfEmpty = false); 39 | CrossRefModel* getModelForCurrentProject(); 40 | CrossRefModel* getModelForCurrentProjectOrDirPath(const QString& dirPath , bool initIfEmpty = false); 41 | CrossRefModel* getLastUsed() const { return d_lastUsed; } 42 | QString getPathOf(CrossRefModel*) const; 43 | 44 | FileCache* getFileCache() const { return d_fcache; } 45 | 46 | static ModelManager* instance(); 47 | 48 | protected slots: 49 | void onModelUpdated(); 50 | 51 | private: 52 | static ModelManager* d_inst; 53 | QHash d_models; // Project File -> Code Model 54 | QHash d_paths; 55 | CrossRefModel* d_lastUsed; 56 | FileCache* d_fcache; 57 | }; 58 | } 59 | 60 | #endif // VLMODELMANAGER_H 61 | -------------------------------------------------------------------------------- /VlModuleLocator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlModuleLocator.h" 21 | #include "VlModelManager.h" 22 | #include 23 | #include 24 | using namespace Vl; 25 | 26 | ModuleLocator::ModuleLocator() 27 | { 28 | setId("VerilogModules"); 29 | setDisplayName(tr("Verilog modules and UDPs in global namespace")); 30 | setShortcutString(QString(QLatin1Char('m'))); 31 | setIncludedByDefault(false); 32 | } 33 | 34 | QList ModuleLocator::matchesFor(QFutureInterface& future, 35 | const QString& entry) 36 | { 37 | Q_UNUSED(future); 38 | 39 | QList res; 40 | 41 | CrossRefModel* mdl = ModelManager::instance()->getModelForCurrentProject(); 42 | if( mdl == 0 ) 43 | return res; 44 | 45 | QDir path( ModelManager::instance()->getPathOf(mdl) ); 46 | 47 | CrossRefModel::IdentDeclRefList l = mdl->getGlobalNames(); 48 | 49 | QStringMatcher matcher(entry, Qt::CaseInsensitive); // ByteArrayMatcher is case sensitive instead 50 | 51 | QPixmap icon(":/verilogcreator/images/block.png"); 52 | foreach(const CrossRefModel::IdentDeclRef& id, l ) 53 | { 54 | const QString name = QString::fromLatin1(id->tok().d_val); 55 | if( matcher.indexIn( name ) != -1 ) 56 | { 57 | res << Core::LocatorFilterEntry( this, name, QVariant::fromValue(CrossRefModel::SymRef(id)),icon); 58 | res.last().extraInfo = path.relativeFilePath( id->tok().d_sourcePath ); 59 | } 60 | } 61 | return res; 62 | } 63 | 64 | void ModuleLocator::accept(Core::LocatorFilterEntry selection) const 65 | { 66 | CrossRefModel::SymRef sym = selection.internalData.value(); 67 | Core::EditorManager::openEditorAt( sym->tok().d_sourcePath, 68 | sym->tok().d_lineNr - 1, sym->tok().d_colNr + 0 ); 69 | } 70 | 71 | void ModuleLocator::refresh(QFutureInterface& future) 72 | { 73 | Q_UNUSED(future); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /VlModuleLocator.h: -------------------------------------------------------------------------------- 1 | #ifndef VLMODULELOCATOR_H 2 | #define VLMODULELOCATOR_H 3 | 4 | /* 5 | * Copyright 2019 Rochus Keller 6 | * 7 | * This file is part of the VerilogCreator plugin. 8 | * 9 | * The following is the license that applies to this copy of the 10 | * plugin. For a license to use the plugin under conditions 11 | * other than those described here, please email to me@rochus-keller.ch. 12 | * 13 | * GNU General Public License Usage 14 | * This file may be used under the terms of the GNU General Public 15 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 16 | * Foundation and appearing in the file LICENSE.GPL included in 17 | * the packaging of this file. Please review the following information 18 | * to ensure GNU General Public Licensing requirements will be met: 19 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 20 | * http://www.gnu.org/copyleft/gpl.html. 21 | */ 22 | 23 | #include 24 | 25 | namespace Vl 26 | { 27 | class ModuleLocator : public Core::ILocatorFilter 28 | { 29 | Q_OBJECT 30 | public: 31 | explicit ModuleLocator(); 32 | 33 | // overrides 34 | QList matchesFor(QFutureInterface &future, 35 | const QString &entry); 36 | void accept(Core::LocatorFilterEntry selection) const; 37 | void refresh(QFutureInterface &future); 38 | 39 | }; 40 | } 41 | 42 | #endif // VLMODULELOCATOR_H 43 | -------------------------------------------------------------------------------- /VlOutlineMdl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Rochus Keller 3 | * 4 | * This file is part of the VerilogCreator plugin. 5 | * 6 | * The following is the license that applies to this copy of the 7 | * plugin. For a license to use the plugin under conditions 8 | * other than those described here, please email to me@rochus-keller.ch. 9 | * 10 | * GNU General Public License Usage 11 | * This file may be used under the terms of the GNU General Public 12 | * License (GPL) versions 2.0 or 3.0 as published by the Free Software 13 | * Foundation and appearing in the file LICENSE.GPL included in 14 | * the packaging of this file. Please review the following information 15 | * to ensure GNU General Public Licensing requirements will be met: 16 | * http://www.fsf.org/licensing/licenses/info/GPLv2.html and 17 | * http://www.gnu.org/copyleft/gpl.html. 18 | */ 19 | 20 | #include "VlOutlineMdl.h" 21 | #include "VlModelManager.h" 22 | #include 23 | #include 24 | #include 25 | using namespace Vl; 26 | 27 | OutlineMdl1::OutlineMdl1(QObject *parent) : QAbstractItemModel(parent),d_crm(0) 28 | { 29 | 30 | } 31 | 32 | void OutlineMdl1::setFile(const QString& f) 33 | { 34 | if( d_file == f ) 35 | return; 36 | beginResetModel(); 37 | d_rows.clear(); 38 | if( d_crm ) 39 | disconnect( d_crm, SIGNAL(sigFileUpdated(QString)), this, SLOT( onCrmUpdated(QString) ) ); 40 | d_file = f; 41 | d_crm = ModelManager::instance()->getModelForCurrentProjectOrDirPath(f); 42 | fillTop(); 43 | if( d_crm ) 44 | connect( d_crm, SIGNAL(sigFileUpdated(QString)), this, SLOT( onCrmUpdated(QString) ) ); 45 | endResetModel(); 46 | } 47 | 48 | const CrossRefModel::Symbol*OutlineMdl1::getSymbol(const QModelIndex& index) const 49 | { 50 | if( !index.isValid() || d_crm == 0 ) 51 | return 0; 52 | const int id = index.internalId(); 53 | if( id == 0 ) 54 | return 0; 55 | Q_ASSERT( id <= d_rows.size() ); 56 | return d_rows[id-1].d_sym.data(); 57 | } 58 | 59 | QModelIndex OutlineMdl1::findSymbol(const CrossRefModel::Symbol* s) 60 | { 61 | if( s == 0 || s->tok().d_sourcePath != d_file ) 62 | return QModelIndex(); 63 | 64 | for( int i = 0; i < d_rows.size(); i++ ) 65 | { 66 | if( d_rows[i].d_sym.data() == s ) 67 | return createIndex( i+1, 0, (quint32)i+1 ); 68 | } 69 | return QModelIndex(); 70 | } 71 | 72 | QModelIndex OutlineMdl1::findSymbol(quint32 line, quint16 col) 73 | { 74 | for( int i = 0; i < d_rows.size(); i++ ) 75 | { 76 | if( d_rows[i].d_sym->tok().d_lineNr == line && d_rows[i].d_sym->tok().d_colNr <= col ) 77 | return createIndex( i+1, 0, (quint32)i+1 ); 78 | } 79 | return QModelIndex(); 80 | } 81 | 82 | QModelIndex OutlineMdl1::index(int row, int column, const QModelIndex& parent) const 83 | { 84 | if( parent.isValid() || row < 0 ) 85 | return QModelIndex(); 86 | 87 | return createIndex( row, column, (quint32)row ); 88 | } 89 | 90 | QModelIndex OutlineMdl1::parent(const QModelIndex& index) const 91 | { 92 | return QModelIndex(); 93 | } 94 | 95 | int OutlineMdl1::rowCount(const QModelIndex& parent) const 96 | { 97 | if( parent.isValid() ) 98 | return 0; 99 | else 100 | return d_rows.size() + 1; // +1 wegen 101 | } 102 | 103 | int OutlineMdl1::columnCount(const QModelIndex& parent) const 104 | { 105 | return 1; 106 | } 107 | 108 | 109 | QVariant OutlineMdl1::data(const QModelIndex& index, int role) const 110 | { 111 | if( !index.isValid() || d_crm == 0 ) 112 | return QVariant(); 113 | 114 | const int id = index.internalId(); 115 | if( id == 0 ) 116 | { 117 | switch (role) 118 | { 119 | case Qt::DisplayRole: 120 | if( !d_rows.isEmpty() ) 121 | return tr("