mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 05:23:20 +00:00
Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -168,12 +168,14 @@ 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
|
||||
/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")
|
||||
|
||||
@@ -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
|
||||
|
||||
467
doc/idetools.txt
Normal file
467
doc/idetools.txt
Normal file
@@ -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 <nimrodc.html>`_, 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 <https://github.com/Araq/Nimrod/wiki/Editor-Support>`_
|
||||
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 <switches> proj.nim
|
||||
|
||||
Or::
|
||||
|
||||
nimrod idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL <switches> 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.
|
||||
|
||||
``<switches>``
|
||||
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 <tut2.html#method-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 <tut2.html#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: ""
|
||||
@@ -458,6 +458,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 <idetools.html>`_
|
||||
for further information.
|
||||
|
||||
|
||||
Nimrod interactive mode
|
||||
=======================
|
||||
|
||||
|
||||
@@ -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 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",
|
||||
"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)):
|
||||
@@ -535,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"
|
||||
|
||||
29
tests/caas/absurd_nesting.nim
Normal file
29
tests/caas/absurd_nesting.nim
Normal file
@@ -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")
|
||||
29
tests/caas/absurd_nesting.txt
Normal file
29
tests/caas/absurd_nesting.txt
Normal file
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
15
tests/caas/forward_declarations.nim
Normal file
15
tests/caas/forward_declarations.nim
Normal file
@@ -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()
|
||||
9
tests/caas/forward_declarations.txt
Normal file
9
tests/caas/forward_declarations.txt
Normal file
@@ -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\)
|
||||
17
tests/caas/forward_usages.txt
Normal file
17
tests/caas/forward_usages.txt
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.\}
|
||||
|
||||
29
tests/caas/its_full_of_procs.nim
Normal file
29
tests/caas/its_full_of_procs.nim
Normal file
@@ -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
|
||||
20
tests/caas/its_full_of_procs.txt
Normal file
20
tests/caas/its_full_of_procs.txt
Normal file
@@ -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 \(
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user