From 1dfea2a36273865c5355f679bc824561c7b3de57 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Wed, 12 Jun 2013 23:34:29 +0200 Subject: [PATCH 01/10] Lists available idetools caas switches. --- doc/advopt.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/advopt.txt b/doc/advopt.txt index 3b6fafd0f3..fc3e1e4e66 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -19,6 +19,10 @@ Advanced commands: --context list possible invokation context --usages list all usages of the symbol at position --eval evaluates an expression + //serve start the compiler as a service mode (CAAS) + --server.type:TYPE either stdin or tcp + --server.port:PORT port for tcp mode, by default 6000 + --server.address:HOST binds to that address, by default "" Advanced options: -m, --mainmodule:FILE set the project main module From d18d6ba019a512d579592b476aa8fec844879267 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Tue, 11 Jun 2013 22:14:31 +0200 Subject: [PATCH 02/10] Starts idetools specific documentation. --- doc/idetools.txt | 467 +++++++++++++++++++++++++++++++++++++++++++++++ doc/nimrodc.txt | 8 + web/nimrod.ini | 2 +- 3 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 doc/idetools.txt diff --git a/doc/idetools.txt b/doc/idetools.txt new file mode 100644 index 0000000000..0ae29e8240 --- /dev/null +++ b/doc/idetools.txt @@ -0,0 +1,467 @@ +================================ + Nimrod IDE Integration Guide +================================ + +:Author: Britney Spears +:Version: |nimrodversion| + +.. contents:: + + +Nimrod differs from many other compilers in that it is really fast, +and being so fast makes it suited to provide external queries for +text editors about the source code being written. Through the +``idetools`` command of `the compiler `_, any IDE can +query a ``.nim`` source file and obtain useful information like +definition of symbols or suggestions for completion. + +This document will guide you through the available options. If you +want to look at practical examples of idetools support you can look +at the test files found in ``tests/caas/*.txt`` or `various editor +integrations `_ +already available. + + +Idetools invokation +=================== + +Specifying the location of the query +------------------------------------ + +All of the available idetools commands require you to specify a +query location through the ``--track`` or ``--trackDirty`` switches. +The general idetools invokations are:: + + nimrod idetools --track:FILE,LINE,COL proj.nim + +Or:: + + nimrod idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL proj.nim + +``proj.nim`` + This is the main *project* filename. Most of the time you will + pass in the same as **FILE**, but for bigger projects this is + the file which is used as main entry point for the program, the + one which users compile to generate a final binary. + +```` + This would be any of the other idetools available options, like + ``--def`` or ``--suggest`` explained in the following sections. + +``COL`` + An integer with the column you are going to query. For the + compiler columns start at zero, so the first column will be + **0** and the last in an 80 column terminal will be **79**. + +``LINE`` + An integer with the line you are going to query. For the compiler + lines start at **1**. + +``FILE`` + The file you want to perform the query on. Usually you will + pass in the same value as **proj.nim**. + +``DIRTY_FILE`` + The **FILE** paramater is enough for static analysis, but IDEs + tend to have *unsaved buffers* where the user may still be in + the middle of typing a line. In such situations the IDE can + save the current contents to a temporary file and then use the + ``--trackDirty`` switch. + + Dirty files are likely to contain errors and they are usually + compiled partially only to the point needed to service the + idetool request. The compiler discriminates them to ensure that + **a)** they won't be cached and **b)** they won't invalidate + the cached contents of the original module. + + The other reason is that the dirty file can appear anywhere on + disk (e.g. in tmpfs), but it must be treated as having a path + matching the original module when it comes to usage of relative + paths, etc. Queries, however, will refer to the dirty module + name in their answers instead of the normal filename. + + +Definitions +----------- + +The ``--def`` idetools switch performs a query about the definition +of a specific symbol. If available, idetools will answer with the +type, source file, line/column information and other accessory data +if available like a docstring. With this information an IDE can +provide the typical *Jump to definition* where a user puts the +cursor on a symbol or uses the mouse to select it and is redirected +to the place where the symbol is located. + +Since Nimrod is implemented in Nimrod, one of the nice things of +this feature is that any user with an IDE supporting it can quickly +jump around the standard library implementation and see exactly +what a proc does, learning about the language and seeing real life +examples of how to write/implement specific features. + +Idetools will always answer with a single definition or none if it +can't find any valid symbol matching the position of the query. + + +Suggestions +----------- + +The ``--suggest`` idetools switch performs a query about possible +completion symbols at some point in the file. IDEs can easily provide +an autocompletion feature where the IDE scans the current file (and +related ones, if it knows about the language being edited and follows +includes/imports) and when the user starts typing something a +completion box with different options appears. + +However such features are not context sensitive and work simply on +string matching, which can be problematic in Nimrod especially due +to the case insensitiveness of the language (plus underscores as +separators!). + +The typical usage scenario for this option is to call it after the +user has typed the dot character for `the object oriented call +syntax `_. + + +Invokation context +------------------ + +The ``--context`` idetools switch is very similar to the suggestions +switch, but instead of being used after the user has typed a dot +character, this one is meant to be used after the user has typed +an opening brace to start typing parameters. + + +Symbol usages +------------- + +The ``--usages`` idetools switch lists all usages of the symbol at +a position. IDEs can use this to find all the places in the file +where the symbol is used and offer the user to rename it in all +places at the same time. Again, a pure string based search and +replace may catch symbols out of the scope of a funcion/loop. + +For this kind of query the IDE will most likely ignore all the +type/signature info provided by idetools and concentrate on the +filename, line and column position of the multiple returned answers. + + +Expression evaluation +--------------------- + +This feature is still under development. In the future it will allow +an IDE to evaluate an expression in the context of the currently +running/debugged user project. + + +Compiler as a service (CAAS) +============================ + +The ocasional use of idetools is acceptable for things like +definitions, where the user puts the cursor on a symbol or double +clicks it and after a second or two the IDE displays where that +symbol is defined. Such latencies would be terrible for features +like symbol suggestion, plus why wait at all if we can avoid it? + +The idetools command can be run as a compiler service, where you +first launch the compiler and it will stay online as a server, +accepting queries in a telnet like fashion. The advantage of staying +on is that for many queries the compiler can cache the results of +the compilation, and subsequent queries should be fast in the +millisecond range, thus being responsive enough for IDEs. + +If you want to start the server using stdin/stdout as communication +you need to type:: + + nimrod serve --server.type:stdin proj.nim + +If you want to start the server using tcp and a port, you need to type:: + + nimrod serve --server.type:tcp --server.port:6000 \ + --server.address:hostname proj.nim + +In both cases the server will start up and await further commands. +The syntax of the commands you can now send to the server is +practically the same as running the nimrod compiler on the commandline, +you only need to remove the name of the compiler since you are +already talking to it. The server will answer with as many lines +of text it thinks necessary plus an empty line to indicate the end +of the answer. + +You can find examples of client/server communication in the idetools +tests found in ``tests/caas/*.txt``. + + +Parsing idetools output +======================= + +Idetools outputs is always returned on single lines separated by +tab characters (``\t``). The values of each column are: + +1. Three characters indicating the type of returned answer (e.g. + def for definition, ``sug`` for suggestion, etc). +2. Type of the symbol. This can be ``skProc``, ``skLet``, and just + about any of the enums defined in the module ``compiler/ast.nim``. +3. Full qualitifed path of the symbol. If you are querying a symbol + defined in the ``proj.nim`` file, this would have the form + ``proj.symbolName``. +4. Type/signature. For variables and enums this will contain the + type of the symbol, for procs, methods and templates this will + contain the full unique signature (e.g. ``proc (TFile)``). +5. Full path to the file containing the symbol. +6. Line where the symbol is located in the file. Lines start to + count at **1**. +7. Column where the symbol is located in the file. Columns start + to count at **0**. +8. Docstring for the symbol if available or the empty string. To + differentiate the docstring from end of answer in server mode, + the docstring is always provided enclosed in double quotes, and + if the docstring spans multiple lines, all following lines of the + docstring will start with a blank space to align visually with + the starting quote. + + Also, you won't find raw ``\n`` characters breaking the one + answer per line format. Instead you will need to parse sequences + in the form ``\xHH``, where *HH* is a hexadecimal value (e.g. + newlines generate the sequence ``\x0A``). + +The following sections define the expected output for each kind of +symbol for which idetools returns valid output. + + +skConst +------- + +| **Third column**: module + [n scope nesting] + const name. +| **Fourth column**: the type of the const value. +| **Docstring**: always the empty string. + +.. code-block:: nimrod + const SOME_SEQUENCE = @[1, 2] + --> col 2: $MODULE.SOME_SEQUENCE + col 3: seq[int] + col 7: "" + + +skEnumField +----------- + +| **Third column**: module + [n scope nesting] + enum type + enum field name. +| **Fourth column**: enum type grouping other enum fields. +| **Docstring**: always the empty string. + +.. code-block:: nimrod + Open(filename, fmWrite) + --> col 2: system.TFileMode.fmWrite + col 3: TFileMode + col 7: "" + + +skForVar +-------- + +| **Third column**: module + [n scope nesting] + var name. +| **Fourth column**: type of the var. +| **Docstring**: always the empty string. + +.. code-block:: nimrod + proc looper(filename = "tests.nim") = + for letter in filename: + echo letter + --> col 2: $MODULE.looper.letter + col 3: char + col 7: "" + + +skIterator +---------- + +The fourth column will be the empty string if the iterator is being +defined, since at that point in the file the parser hasn't processed +the full line yet. The signature will be returned complete in +posterior instances of the iterator. + +| **Third column**: module + [n scope nesting] + iterator name. +| **Fourth column**: signature of the iterator including return type. +| **Docstring**: docstring if available. + +.. code-block:: nimrod + let + text = "some text" + letters = toSeq(runes(text)) + --> col 2: unicode.runes + col 3: iterator (string): TRune + col 7: "iterates over any unicode character of the string `s`." + + +skLet +----- + +| **Third column**: module + [n scope nesting] + let name. +| **Fourth column**: the type of the let variable. +| **Docstring**: always the empty string. + +.. code-block:: nimrod + let + text = "some text" + --> col 2: $MODULE.text + col 3: TaintedString + col 7: "" + + +skMethod +-------- + +The fourth column will be the empty string if the method is being +defined, since at that point in the file the parser hasn't processed +the full line yet. The signature will be returned complete in +posterior instances of the method. + +Methods imply `dynamic dispatch `_ and +idetools performs a static analysis on the code. For this reason +idetools may not return the definition of the correct method you +are querying because it may be impossible to know until the code +is executed. It will try to return the method which covers the most +possible cases (i.e. for variations of different classes in a +hierarchy it will prefer methods using the base class). + +While at the language level a method is differentiated from others +by the parameters and return value, the signature of the method +returned by idetools returns also the pragmas for the method. + +Note that at the moment the word ``proc`` is returned for the +signature of the found method instead of the expected ``method``. +This may change in the future. + +| **Third column**: module + [n scope nesting] + method name. +| **Fourth column**: signature of the method including return type. +| **Docstring**: docstring if available. + +.. code-block:: nimrod + method eval(e: PExpr): int = quit "to override!" + method eval(e: PLiteral): int = e.x + method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b) + echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) + --> col 2: $MODULE.eval + col 3: proc (PPlusExpr): int + col 7: "" + + +skParam +------- + +| **Third column**: module + [n scope nesting] + param name. +| **Fourth column**: the type of the parameter. +| **Docstring**: always the empty string. + +.. code-block:: nimrod + proc reader(filename = "tests.nim") = + let text = readFile(filename) + --> col 2: $MODULE.reader.filename + col 3: string + col 7: "" + + +skProc +------ + +The fourth column will be the empty string if the proc is being +defined, since at that point in the file the parser hasn't processed +the full line yet. The signature will be returned complete in +posterior instances of the proc. + +While at the language level a proc is differentiated from others +by the parameters and return value, the signature of the proc +returned by idetools returns also the pragmas for the proc. + +| **Third column**: module + [n scope nesting] + proc name. +| **Fourth column**: signature of the proc including return type. +| **Docstring**: docstring if available. + +.. code-block:: nimrod + Open(filename, fmWrite) + --> col 2: system.Open + col 3: proc (var TFile, string, TFileMode, int): bool + col 7: + "Opens a file named `filename` with given `mode`. + + Default mode is readonly. Returns true iff the file could be opened. + This throws no exception if the file could not be opened." + + +skResult +-------- + +| **Third column**: module + [n scope nesting] + result. +| **Fourth column**: the type of the result. +| **Docstring**: always the empty string. + +.. code-block:: nimrod + proc getRandomValue() : int = + return 4 + --> col 2: $MODULE.getRandomValue.result + col 3: int + col 7: "" + + +skTemplate +---------- + +The fourth column will be the empty string if the template is being +defined, since at that point in the file the parser hasn't processed +the full line yet. The signature will be returned complete in +posterior instances of the template. + +| **Third column**: module + [n scope nesting] + template name. +| **Fourth column**: signature of the template including return type. +| **Docstring**: docstring if available. + +.. code-block:: nimrod + let + text = "some text" + letters = toSeq(runes(text)) + --> col 2: sequtils.toSeq + col 3: proc (expr): expr + col 7: + "Transforms any iterator into a sequence. + + Example: + + .. code-block:: nimrod + let + numeric = @[1, 2, 3, 4, 5, 6, 7, 8, 9] + odd_numbers = toSeq(filter(numeric) do (x: int) -> bool: + if x mod 2 == 1: + result = true) + assert odd_numbers == @[1, 3, 5, 7, 9]" + + +skType +------ + +| **Third column**: module + [n scope nesting] + type name. +| **Fourth column**: the type. +| **Docstring**: always the empty string. + +.. code-block:: nimrod + proc writeTempFile() = + var output: TFile + --> col 2: system.TFile + col 3: TFile + col 7: "" + + +skVar +----- + +| **Third column**: module + [n scope nesting] + var name. +| **Fourth column**: the type of the var. +| **Docstring**: always the empty string. + +.. code-block:: nimrod + proc writeTempFile() = + var output: TFile + output.open("/tmp/somefile", fmWrite) + output.write("test") + --> col 2: $MODULE.writeTempFile.output + col 3: TFile + col 7: "" diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index 339cee3823..889fb2ced0 100644 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -443,6 +443,14 @@ in C/C++). **Note**: This pragma will not exist for the LLVM backend. +Nimrod idetools integration +======================= + +Nimrod provides language integration with external IDEs through the +idetools command. See the documentation of `idetools `_ +for further information. + + Nimrod interactive mode ======================= diff --git a/web/nimrod.ini b/web/nimrod.ini index d9c6cb786d..94f196c643 100644 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -37,7 +37,7 @@ UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson.""" [Documentation] doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview;filters;trmacros" -doc: "tools;c2nim;niminst;nimgrep;gc;estp" +doc: "tools;c2nim;niminst;nimgrep;gc;estp;idetools" pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst;gc" srcdoc2: "system.nim;impure/graphics;wrappers/sdl" srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned" From d2def332fd6d290bd74cb1e491b3c8f8f09d894a Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 16 Jun 2013 13:00:24 +0200 Subject: [PATCH 03/10] Adds $SILENT replacement to reduce test output verbosity. --- tests/caas/basic-recompile.txt | 6 ++-- tests/caas/compile-suggest.txt | 4 +-- tests/caas/compile-then-def.txt | 8 +++-- tests/caas/def-def-compile.txt | 8 +++-- tests/caas/def-then-compile.txt | 5 ++-- tests/caas/idetools_api.txt | 36 +++++++++++------------ tests/caas/issue_416_template_shift.txt | 10 +++---- tests/caas/issue_452_export_shift.txt | 10 +++---- tests/caas/issue_477_dynamic_dispatch.txt | 2 +- tests/caas/suggest-compile.txt | 4 +-- tests/caasdriver.nim | 3 ++ 11 files changed, 52 insertions(+), 44 deletions(-) diff --git a/tests/caas/basic-recompile.txt b/tests/caas/basic-recompile.txt index d869944b95..620e0c059e 100644 --- a/tests/caas/basic-recompile.txt +++ b/tests/caas/basic-recompile.txt @@ -1,10 +1,10 @@ main.nim -> c +> c --verbosity:0 --hints:on SuccessX -> c # The "Processing" string will be found always in proc mode since each # compilation command will generate it. We need to test it only in Caas mode to # verify the server is not recompiling again the file. +CaasRun > c --verbosity:0 --hints:on CaasRun ! Processing -SuccessX +CaasRun SuccessX diff --git a/tests/caas/compile-suggest.txt b/tests/caas/compile-suggest.txt index 6170603470..378320014d 100644 --- a/tests/caas/compile-suggest.txt +++ b/tests/caas/compile-suggest.txt @@ -1,7 +1,7 @@ main.nim -> c +> c --verbosity:0 --hints:on SuccessX -> idetools --trackDirty:main_dirty.nim,$TESTNIM,12,7 --suggest +> idetools --trackDirty:main_dirty.nim,$TESTNIM,12,7 --suggest $SILENT skField\tx skField\ty diff --git a/tests/caas/compile-then-def.txt b/tests/caas/compile-then-def.txt index 66ff293469..72ba46b044 100644 --- a/tests/caas/compile-then-def.txt +++ b/tests/caas/compile-then-def.txt @@ -1,9 +1,11 @@ main.nim -> c +> c --verbosity:0 --hints:on SuccessX -> idetools --track:$TESTNIM,5,18 --def + +> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on strutils.toUpper ! SuccessX -> idetools --track:$TESTNIM,5,18 --def + +> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on strutils.toUpper ! SuccessX diff --git a/tests/caas/def-def-compile.txt b/tests/caas/def-def-compile.txt index 12ba7e993c..21d5ea962d 100644 --- a/tests/caas/def-def-compile.txt +++ b/tests/caas/def-def-compile.txt @@ -1,10 +1,12 @@ main.nim -> idetools --track:$TESTNIM,5,18 --def +> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on strutils.toUpper ! SuccessX -> idetools --track:$TESTNIM,5,18 --def + +> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on strutils.toUpper ! SuccessX -> c + +> c --verbosity:0 --hints:on SuccessX diff --git a/tests/caas/def-then-compile.txt b/tests/caas/def-then-compile.txt index e44af7f63e..2214bf02c1 100644 --- a/tests/caas/def-then-compile.txt +++ b/tests/caas/def-then-compile.txt @@ -1,7 +1,8 @@ main.nim -> idetools --track:$TESTNIM,5,18 --def +> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on strutils.toUpper ! SuccessX -> c + +> c --verbosity:0 --hints:on SuccessX diff --git a/tests/caas/idetools_api.txt b/tests/caas/idetools_api.txt index bc1dc6a5f4..c4c22399e8 100644 --- a/tests/caas/idetools_api.txt +++ b/tests/caas/idetools_api.txt @@ -1,44 +1,44 @@ idetools_api.nim -> c +> c --verbosity:0 --hints:on SuccessX -> idetools --track:$TESTNIM,4,11 --def +> idetools --track:$TESTNIM,4,11 --def $SILENT def\tskType\tsystem.TFile\tTFile -> idetools --track:$TESTNIM,5,7 --def +> idetools --track:$TESTNIM,5,7 --def $SILENT def\tskProc\tsystem.Open\tproc \(var TFile, string, TFileMode, int\): bool -> idetools --track:$TESTNIM,5,21 --def +> idetools --track:$TESTNIM,5,21 --def $SILENT def\tskProc\tsystem.\&\tproc \(string, string\): string\{.noSideEffect.\} -> idetools --track:$TESTNIM,5,38 --def +> idetools --track:$TESTNIM,5,38 --def $SILENT def\tskEnumField\tsystem.TFileMode.fmWrite\tTFileMode -> idetools --track:$TESTNIM,7,6 --def +> idetools --track:$TESTNIM,7,6 --def $SILENT def\tskProc\tsystem.Close\tproc \(TFile\) -> idetools --track:$TESTNIM,12,23 --def +> idetools --track:$TESTNIM,12,23 --def $SILENT def\tskIterator\tunicode.runes\titerator \(string\): TRune -> idetools --track:$TESTNIM,12,15 --def +> idetools --track:$TESTNIM,12,15 --def $SILENT def\tskTemplate\tsequtils.toSeq\tproc \(expr\): expr -> idetools --track:$TESTNIM,15,7 --def +> idetools --track:$TESTNIM,15,7 --def $SILENT # ProcRun mode will fail the next line, because the type is returned empty. def\tskConst\t$MODULE.SOME_SEQUENCE\tseq\[int\]\t -> idetools --track:$TESTNIM,15,23 --def +> idetools --track:$TESTNIM,15,23 --def $SILENT def\tskProc\tsystem.@\tproc \(array\[IDX, T\]\): seq\[T\]\{.noSideEffect.\} -> idetools --track:$TESTNIM,17,3 --def +> idetools --track:$TESTNIM,17,3 --def $SILENT # ProcRun mode will fail the next line, because the type is returned empty. def\tskType\t$MODULE.bad_string\tbad_string\t -> idetools --track:$TESTNIM,11,24 --def +> idetools --track:$TESTNIM,11,24 --def $SILENT def\tskParam\t$MODULE.test_iterators.filename\tstring -> idetools --track:$TESTNIM,6,5 --def +> idetools --track:$TESTNIM,6,5 --def $SILENT def\tskVar\t$MODULE.test_enums.o\tTFile -> idetools --track:$TESTNIM,12,34 --def +> idetools --track:$TESTNIM,12,34 --def $SILENT def\tskLet\t$MODULE.test_iterators.input\tTaintedString -> idetools --track:$TESTNIM,13,35 --def +> idetools --track:$TESTNIM,13,35 --def $SILENT def\tskForVar\t$MODULE.test_iterators.letter\tTRune -> idetools --track:$TESTNIM,23,3 --def +> idetools --track:$TESTNIM,23,3 --def $SILENT def\tskResult\t$MODULE.adder.result\tint -> idetools --track:$TESTNIM,19,6 --def +> idetools --track:$TESTNIM,19,6 --def $SILENT # ProcRun mode will fail the next line, because the type is returned empty. def\tskField\t$MODULE.TPerson.name\tbad_string\t -> idetools --track:$TESTNIM,43,7 --def +> idetools --track:$TESTNIM,43,7 --def $SILENT def\tskMethod\t$MODULE.eval\tproc \(PPlusExpr\): int\t diff --git a/tests/caas/issue_416_template_shift.txt b/tests/caas/issue_416_template_shift.txt index 951a21612a..b1f47c1ac6 100644 --- a/tests/caas/issue_416_template_shift.txt +++ b/tests/caas/issue_416_template_shift.txt @@ -1,14 +1,14 @@ issue_416_template_shift.nim -> c +> c --verbosity:0 --hints:on SuccessX -> idetools --track:$TESTNIM,12,28 --def +> idetools --track:$TESTNIM,12,28 --def $SILENT def\tskType\tsystem.string\tstring -> idetools --track:$TESTNIM,12,35 --def +> idetools --track:$TESTNIM,12,35 --def $SILENT def\tskLet\t$MODULE.failtest.input\tTaintedString # The following fail because they seem shifted one colum to the right. -> idetools --track:$TESTNIM,12,16 --def +> idetools --track:$TESTNIM,12,16 --def $SILENT def\tskTemplate\tsequtils.toSeq\tproc \(expr\): expr -> idetools --track:$TESTNIM,12,22 --def +> idetools --track:$TESTNIM,12,22 --def $SILENT def\tskIterator\tunicode.runes\titerator \(string\): TRune diff --git a/tests/caas/issue_452_export_shift.txt b/tests/caas/issue_452_export_shift.txt index 56ba0b74f7..4676ed71e2 100644 --- a/tests/caas/issue_452_export_shift.txt +++ b/tests/caas/issue_452_export_shift.txt @@ -1,11 +1,11 @@ issue_452_export_shift.nim -> c +> c --verbosity:0 --hints:on SuccessX -> idetools --track:$TESTNIM,2,2 --def +> idetools --track:$TESTNIM,2,2 --def $SILENT def\tskConst\t$MODULE.VERSION_STR1\tstring -> idetools --track:$TESTNIM,3,2 --def +> idetools --track:$TESTNIM,3,2 --def $SILENT def\tskConst\t$MODULE.VERSION_STR2\tstring -> idetools --track:$TESTNIM,7,5 --def +> idetools --track:$TESTNIM,7,5 --def $SILENT def\tskProc\t$MODULE.forward1\tproc \(\): string\t -> idetools --track:$TESTNIM,8,5 --def +> idetools --track:$TESTNIM,8,5 --def $SILENT def\tskProc\t$MODULE.forward2\tproc \(\): string\t diff --git a/tests/caas/issue_477_dynamic_dispatch.txt b/tests/caas/issue_477_dynamic_dispatch.txt index 068a9d022b..12fd750deb 100644 --- a/tests/caas/issue_477_dynamic_dispatch.txt +++ b/tests/caas/issue_477_dynamic_dispatch.txt @@ -1,5 +1,5 @@ issue_477_dynamic_dispatch.nim > c --run SuccessX -> idetools --track:issue_477_dynamic_dispatch.nim,19,5 --def +> idetools --track:issue_477_dynamic_dispatch.nim,19,5 --def $SILENT def\tskMethod\tissue_477_dynamic_dispatch.collide\tproc \(TUnit, TThing\)\{.inline.\} diff --git a/tests/caas/suggest-compile.txt b/tests/caas/suggest-compile.txt index ac61872361..66ae795ed6 100644 --- a/tests/caas/suggest-compile.txt +++ b/tests/caas/suggest-compile.txt @@ -1,7 +1,7 @@ main.nim -> idetools --trackDirty:main_dirty.nim,$TESTNIM,12,7 --suggest +> idetools --trackDirty:main_dirty.nim,$TESTNIM,12,7 --suggest $SILENT skField\tx skField\ty -> c +> c --verbosity:0 --hints:on SuccessX diff --git a/tests/caasdriver.nim b/tests/caasdriver.nim index cd27839c78..f6f3d4e384 100644 --- a/tests/caasdriver.nim +++ b/tests/caasdriver.nim @@ -59,6 +59,8 @@ const modes = [CaasRun, ProcRun, SymbolProcRun] filenameReplaceVar = "$TESTNIM" moduleReplaceVar = "$MODULE" + silentReplaceVar = "$SILENT" + silentReplaceText = "--verbosity:0 --hints:off" var TesterDir = getAppDir() @@ -67,6 +69,7 @@ var proc replaceVars(session: var TNimrodSession, text: string): string = result = text.replace(filenameReplaceVar, session.filename) result = result.replace(moduleReplaceVar, session.modname) + result = result.replace(silentReplaceVar, silentReplaceText) proc startNimrodSession(project, script: string, mode: TRunMode): TNimrodSession = From b15f585273092f05145dd5b3fec5e83e27fbe45a Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 16 Jun 2013 13:18:09 +0200 Subject: [PATCH 04/10] Adds idetoos testcase to verify returned signatures. At the moment too many of them return proc. --- .gitignore | 2 +- tests/caas/its_full_of_procs.nim | 29 +++++++++++++++++++++++++++++ tests/caas/its_full_of_procs.txt | 20 ++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/caas/its_full_of_procs.nim create mode 100644 tests/caas/its_full_of_procs.txt diff --git a/.gitignore b/.gitignore index a52319eff0..dcb94935f5 100644 --- a/.gitignore +++ b/.gitignore @@ -173,7 +173,7 @@ examples/cross_calculator/android/tags /tests/caas/issue_416_template_shift /tests/caas/issue_452_export_shift /tests/caas/issue_477_dynamic_dispatch +/tests/caas/its_full_of_procs /tests/caas/main /tests/caasdriver /tools/nimgrep -no changes added to commit (use "git add" and/or "git commit -a") diff --git a/tests/caas/its_full_of_procs.nim b/tests/caas/its_full_of_procs.nim new file mode 100644 index 0000000000..45347490c0 --- /dev/null +++ b/tests/caas/its_full_of_procs.nim @@ -0,0 +1,29 @@ +import unicode, sequtils + +# This example shows that idetools returns proc as signature for everything +# which can be called. While a clever person would use the second column to +# differentiate betwen procs, methods and others, why does the output contain +# incorrect information? + +type + TThing = object of TObject + TUnit = object of TThing + x: int + +method collide(a, b: TThing) {.inline.} = + quit "to override!" + +method collide(a: TThing, b: TUnit) {.inline.} = + echo "1" + +method collide(a: TUnit, b: TThing) {.inline.} = + echo "2" + +var + a, b: TUnit + +let + input = readFile("its_full_of_procs.nim") + letters = toSeq(runes(string(input))) + +collide(a, b) # output: 2 diff --git a/tests/caas/its_full_of_procs.txt b/tests/caas/its_full_of_procs.txt new file mode 100644 index 0000000000..31a2d3baaa --- /dev/null +++ b/tests/caas/its_full_of_procs.txt @@ -0,0 +1,20 @@ +its_full_of_procs.nim + +> idetools --track:$TESTNIM,26,15 --def $SILENT +skProc +proc \( + +> idetools --track:$TESTNIM,27,21 --def $SILENT +skIterator +iterator \( +!proc \( + +> idetools --track:$TESTNIM,29,0 --def $SILENT +skMethod +method \( +!proc \( + +> idetools --track:$TESTNIM,27,15 --def $SILENT +skTemplate +template \( +!proc \( From 25f45cace14f9b48f4b7ada3ace4c4f430d703a6 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 16 Jun 2013 13:42:36 +0200 Subject: [PATCH 05/10] Adds idetools test to check declaration proc signatures. --- .gitignore | 1 + tests/caas/forward_declarations.nim | 15 +++++++++++++++ tests/caas/forward_declarations.txt | 9 +++++++++ 3 files changed, 25 insertions(+) create mode 100644 tests/caas/forward_declarations.nim create mode 100644 tests/caas/forward_declarations.txt diff --git a/.gitignore b/.gitignore index dcb94935f5..06a6e7d9f9 100644 --- a/.gitignore +++ b/.gitignore @@ -168,6 +168,7 @@ examples/cross_calculator/android/tags /testresults.html /testresults.json /tests/caas/SymbolProcRun.*/ +/tests/caas/forward_declarations /tests/caas/idetools_api /tests/caas/imported /tests/caas/issue_416_template_shift diff --git a/tests/caas/forward_declarations.nim b/tests/caas/forward_declarations.nim new file mode 100644 index 0000000000..177d82f20b --- /dev/null +++ b/tests/caas/forward_declarations.nim @@ -0,0 +1,15 @@ +# This example shows that idetools returns an empty signature for a forward +# declared proc in proc/symproc runs, but correctly returns the full signature +# in caas mode. + +proc echoHello(text: string) + +proc testForward() = + echo "T" + echoHello("T") + +proc echoHello(text: string) = + echo "Hello Mr." & text + +when isMainModule: + testForward() diff --git a/tests/caas/forward_declarations.txt b/tests/caas/forward_declarations.txt new file mode 100644 index 0000000000..b1695b9c7a --- /dev/null +++ b/tests/caas/forward_declarations.txt @@ -0,0 +1,9 @@ +forward_declarations.nim + +> idetools --track:$TESTNIM,9,5 --def $SILENT +skProc +proc \(string\) + +> idetools --track:$TESTNIM,5,9 --def $SILENT +skProc +proc \(string\) From 1f8c5c37d38f4f4a8f9651e5a6ca699fc08ba53d Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 16 Jun 2013 21:43:34 +0200 Subject: [PATCH 06/10] Adds idetools test to verify --usages, reuses testcase. --- tests/caas/forward_usages.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/caas/forward_usages.txt diff --git a/tests/caas/forward_usages.txt b/tests/caas/forward_usages.txt new file mode 100644 index 0000000000..05ef517dc2 --- /dev/null +++ b/tests/caas/forward_usages.txt @@ -0,0 +1,17 @@ +forward_declarations.nim + +> c --verbosity:0 --hints:on +SuccessX + +# None of the following return three instances of the echoHello proc, the first +# being the forward declaration, the second being the usage inside testForward, +# and the third being the actual implementation. + +> idetools --track:$TESTNIM,5,5 --usages $SILENT +skProc.*\n.*skProc.*\n.*skProc + +> idetools --track:$TESTNIM,9,5 --usages $SILENT +skProc.*\n.*skProc.*\n.*skProc + +> idetools --track:$TESTNIM,11,5 --usages $SILENT +skProc.*\n.*skProc.*\n.*skProc From a1da2b713bccbf9555f087caeb4e093e445952f5 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 16 Jun 2013 22:35:54 +0200 Subject: [PATCH 07/10] Adds idetools hierarchy nesting test. --- .gitignore | 1 + tests/caas/absurd_nesting.nim | 29 +++++++++++++++++++++++++++++ tests/caas/absurd_nesting.txt | 29 +++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 tests/caas/absurd_nesting.nim create mode 100644 tests/caas/absurd_nesting.txt diff --git a/.gitignore b/.gitignore index 06a6e7d9f9..03e7c35cc4 100644 --- a/.gitignore +++ b/.gitignore @@ -168,6 +168,7 @@ examples/cross_calculator/android/tags /testresults.html /testresults.json /tests/caas/SymbolProcRun.*/ +/tests/caas/absurd_nesting /tests/caas/forward_declarations /tests/caas/idetools_api /tests/caas/imported diff --git a/tests/caas/absurd_nesting.nim b/tests/caas/absurd_nesting.nim new file mode 100644 index 0000000000..136d65cc7a --- /dev/null +++ b/tests/caas/absurd_nesting.nim @@ -0,0 +1,29 @@ +# Tries to test the full ownership path generated by idetools. + +proc lev1(t1: string) = + var temp = t1 + for i in 0..len(temp)-1: + temp[i] = chr(int(temp[i]) + 1) + + proc lev2(t2: string) = + var temp = t2 + for i in 0..len(temp)-1: + temp[i] = chr(int(temp[i]) + 1) + + proc lev3(t3: string) = + var temp = t3 + for i in 0..len(temp)-1: + temp[i] = chr(int(temp[i]) + 1) + + proc lev4(t4: string) = + var temp = t4 + for i in 0..len(temp)-1: + temp[i] = chr(int(temp[i]) + 1) + + echo temp & "(lev4)" + lev4(temp & "(lev3)") + lev3(temp & "(lev2)") + lev2(temp & "(lev1)") + +when isMainModule: + lev1("abcd") diff --git a/tests/caas/absurd_nesting.txt b/tests/caas/absurd_nesting.txt new file mode 100644 index 0000000000..986e348360 --- /dev/null +++ b/tests/caas/absurd_nesting.txt @@ -0,0 +1,29 @@ +absurd_nesting.nim + +> c --verbosity:0 --hints:on +SuccessX + +> idetools --track:$TESTNIM,6,6 --def $SILENT +skVar\tabsurd_nesting.lev1.temp\tstring + +> idetools --track:$TESTNIM,21,13 --def $SILENT +skVar\tabsurd_nesting.lev1.lev2.lev3.lev4.temp\tstring + +> idetools --track:$TESTNIM,6,27 --def $SILENT +skForVar\tabsurd_nesting.lev1.i\tint + +> idetools --track:$TESTNIM,21,33 --def $SILENT +skForVar\tabsurd_nesting.lev1.lev1.lev3.lev4.i\tint + +> idetools --track:$TESTNIM,24,8 --def $SILENT +skProc\tabsurd_nesting.lev1.lev1.lev3.lev4\tproc \(string\) + +> idetools --track:$TESTNIM,4,13 --def $SILENT +skParam\tabsurd_nesting.lev1.t1\tstring + +> idetools --track:$TESTNIM,4,13 --def $SILENT +skParam\tabsurd_nesting.lev1.t1\tstring + +> idetools --track:$TESTNIM,19,19 --def $SILENT +skParam\tabsurd_nesting.lev1.lev2.lev3.lev4.t4\tstring + From 5b1caed806e017b39c9dd447fde00085fe5aab09 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Tue, 18 Jun 2013 21:01:12 +0200 Subject: [PATCH 08/10] Replaces relative file slurping with hardcoded array. --- lib/packages/docutils/highlite.nim | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index 21dd1543a6..f4b2f5867e 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -44,7 +44,17 @@ const "Assembler", "Preprocessor", "Directive", "Command", "Rule", "Hyperlink", "Label", "Reference", "Other"] - nimrodKeywords = slurp("doc/keywords.txt").split + # The following list comes from doc/keywords.txt, make sure it is + # synchronized with this array. + nimrodKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", + "break", "case", "cast", "const", "continue", "converter", "discard", + "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", + "finally", "for", "from", "generic", "if", "import", "in", "include", + "interface", "is", "isnot", "iterator", "lambda", "let", "macro", "method", + "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", + "ptr", "raise", "ref", "return", "shared", "shl", "shr", "static", + "template", "try", "tuple", "type", "var", "when", "while", "with", + "without", "xor", "yield"] proc getSourceLanguage*(name: string): TSourceLanguage = for i in countup(succ(low(TSourceLanguage)), high(TSourceLanguage)): From 4c7607e074de9272f3e7f3b5e0d40c6ee5c8259c Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Tue, 18 Jun 2013 21:42:53 +0200 Subject: [PATCH 09/10] Adds previous slurping as runnable testcase. --- lib/packages/docutils/highlite.nim | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index f4b2f5867e..b1b6c41e22 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -45,7 +45,7 @@ const "Label", "Reference", "Other"] # The following list comes from doc/keywords.txt, make sure it is - # synchronized with this array. + # synchronized with this array by running the module itself as a test case. nimrodKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", "break", "case", "cast", "const", "continue", "converter", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", @@ -545,3 +545,16 @@ proc getNextToken*(g: var TGeneralTokenizer, lang: TSourceLanguage) = of langC: cNextToken(g) of langJava: javaNextToken(g) +when isMainModule: + var keywords: seq[string] + # Try to work running in both the subdir or at the root. + for filename in ["doc/keywords.txt", "../../../doc/keywords.txt"]: + except: echo filename, " not found" + let input = string(readFile(filename)) + keywords = input.split() + break + doAssert (not keywords.isNil, "Couldn't read any keywords.txt file!") + doAssert keywords.len == nimrodKeywords.len, "No matching lengths" + for i in 0..keywords.len-1: + echo keywords[i], " == ", nimrodKeywords[i] + doAssert keywords[i] == nimrodKeywords[i], "Unexpected keyword" From 579d0f6f411170e7b96b40ce5d5b7377da1cfb4f Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Tue, 18 Jun 2013 22:18:44 +0200 Subject: [PATCH 10/10] Adds highlite to tests suite. --- lib/packages/docutils/highlite.nim | 2 +- tests/specials.nim | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index b1b6c41e22..69da2bba84 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -556,5 +556,5 @@ when isMainModule: doAssert (not keywords.isNil, "Couldn't read any keywords.txt file!") doAssert keywords.len == nimrodKeywords.len, "No matching lengths" for i in 0..keywords.len-1: - echo keywords[i], " == ", nimrodKeywords[i] + #echo keywords[i], " == ", nimrodKeywords[i] doAssert keywords[i] == nimrodKeywords[i], "Unexpected keyword" diff --git a/tests/specials.nim b/tests/specials.nim index 156a289d26..9ced66bbb9 100644 --- a/tests/specials.nim +++ b/tests/specials.nim @@ -194,6 +194,8 @@ proc runSpecialTests(r: var TResults, options: string) = for t in os.walkFiles("tests/patterns/t*.nim"): runSingleTest(r, t, options) + for t in ["lib/packages/docutils/highlite"]: + runSingleTest(r, t, options) proc rejectSpecialTests(r: var TResults, options: string) = rejectThreadTests(r, options)