summary refs log tree commit diff stats
path: root/nimsuggest/tests
diff options
context:
space:
mode:
Diffstat (limited to 'nimsuggest/tests')
-rw-r--r--nimsuggest/tests/fixtures/mclass_macro.nim164
-rw-r--r--nimsuggest/tests/fixtures/mdep_v1.nim (renamed from nimsuggest/tests/dep_v1.nim)0
-rw-r--r--nimsuggest/tests/fixtures/mdep_v2.nim (renamed from nimsuggest/tests/dep_v2.nim)0
-rw-r--r--nimsuggest/tests/fixtures/mfakeassert.nim5
-rw-r--r--nimsuggest/tests/fixtures/minclude_import.nim15
-rw-r--r--nimsuggest/tests/fixtures/minclude_include.nim4
-rw-r--r--nimsuggest/tests/fixtures/minclude_types.nim6
-rw-r--r--nimsuggest/tests/fixtures/mstrutils.nim19
-rw-r--r--nimsuggest/tests/module_20265.nim6
-rw-r--r--nimsuggest/tests/t20265_1.nim8
-rw-r--r--nimsuggest/tests/t20265_2.nim8
-rw-r--r--nimsuggest/tests/t20440.nim7
-rw-r--r--nimsuggest/tests/t20440.nims1
-rw-r--r--nimsuggest/tests/t21185.nim18
-rw-r--r--nimsuggest/tests/t22448.nim11
-rw-r--r--nimsuggest/tests/tarrowcrash.nim20
-rw-r--r--nimsuggest/tests/tchk1.nim11
-rw-r--r--nimsuggest/tests/tchk2.nim35
-rw-r--r--nimsuggest/tests/tchk_compiles.nim8
-rw-r--r--nimsuggest/tests/tcon1.nim34
-rw-r--r--nimsuggest/tests/tconcept1.nim12
-rw-r--r--nimsuggest/tests/tconcept2.nim15
-rw-r--r--nimsuggest/tests/tdef1.nim10
-rw-r--r--nimsuggest/tests/tdef2.nim13
-rw-r--r--nimsuggest/tests/tdef_forward.nim13
-rw-r--r--nimsuggest/tests/tdef_let.nim7
-rw-r--r--nimsuggest/tests/tdot3.nim4
-rw-r--r--nimsuggest/tests/tdot4.nim22
-rw-r--r--nimsuggest/tests/tenum_field.nim17
-rw-r--r--nimsuggest/tests/tfatal1.nim15
-rw-r--r--nimsuggest/tests/tgeneric_highlight.nim7
-rw-r--r--nimsuggest/tests/tgenerics.nim18
-rw-r--r--nimsuggest/tests/tic.nim20
-rw-r--r--nimsuggest/tests/timport_highlight.nim12
-rw-r--r--nimsuggest/tests/tinclude.nim29
-rw-r--r--nimsuggest/tests/top_highlight.nim11
-rw-r--r--nimsuggest/tests/tqualified_highlight.nim2
-rw-r--r--nimsuggest/tests/tstrutils.nim10
-rw-r--r--nimsuggest/tests/tsug_enum.nim18
-rw-r--r--nimsuggest/tests/tsug_pragmas.nim40
-rw-r--r--nimsuggest/tests/tsug_recursive.nim8
-rw-r--r--nimsuggest/tests/tsug_regression.nim25
-rw-r--r--nimsuggest/tests/tsug_template.nim6
-rw-r--r--nimsuggest/tests/tsug_typedecl.nim26
-rw-r--r--nimsuggest/tests/ttempl_inst.nim13
-rw-r--r--nimsuggest/tests/ttemplate_highlight.nim (renamed from nimsuggest/tests/disabled_ttemplate_highlight.nim)0
-rw-r--r--nimsuggest/tests/ttype_decl.nim9
-rw-r--r--nimsuggest/tests/tuse.nim22
-rw-r--r--nimsuggest/tests/tuse_enum.nim15
-rw-r--r--nimsuggest/tests/tuse_structure.nim15
-rw-r--r--nimsuggest/tests/tv3.nim27
-rw-r--r--nimsuggest/tests/tv3_con.nim13
-rw-r--r--nimsuggest/tests/tv3_definition.nim9
-rw-r--r--nimsuggest/tests/tv3_forward_definition.nim23
-rw-r--r--nimsuggest/tests/tv3_generics.nim18
-rw-r--r--nimsuggest/tests/tv3_globalSymbols.nim14
-rw-r--r--nimsuggest/tests/tv3_import.nim7
-rw-r--r--nimsuggest/tests/tv3_outline.nim45
-rw-r--r--nimsuggest/tests/tv3_typeDefinition.nim32
-rw-r--r--nimsuggest/tests/twithin_macro.nim179
-rw-r--r--nimsuggest/tests/twithin_macro_prefix.nim170
61 files changed, 950 insertions, 401 deletions
diff --git a/nimsuggest/tests/fixtures/mclass_macro.nim b/nimsuggest/tests/fixtures/mclass_macro.nim
new file mode 100644
index 000000000..cfca0bf3f
--- /dev/null
+++ b/nimsuggest/tests/fixtures/mclass_macro.nim
@@ -0,0 +1,164 @@
+
+import macros
+
+macro class*(head, body: untyped): untyped =
+  # The macro is immediate, since all its parameters are untyped.
+  # This means, it doesn't resolve identifiers passed to it.
+
+  var typeName, baseName: NimNode
+
+  # flag if object should be exported
+  var exported: bool
+
+  if head.kind == nnkInfix and head[0].kind == nnkIdent and $head[0] == "of":
+    # `head` is expression `typeName of baseClass`
+    # echo head.treeRepr
+    # --------------------
+    # Infix
+    #   Ident !"of"
+    #   Ident !"Animal"
+    #   Ident !"RootObj"
+    typeName = head[1]
+    baseName = head[2]
+
+  elif head.kind == nnkInfix and head[0].kind == nnkIdent and
+       $head[0] == "*" and head[2].kind == nnkPrefix and
+       head[2][0].kind == nnkIdent and $head[2][0] == "of":
+    # `head` is expression `typeName* of baseClass`
+    # echo head.treeRepr
+    # --------------------
+    # Infix
+    #   Ident !"*"
+    #   Ident !"Animal"
+    #   Prefix
+    #     Ident !"of"
+    #     Ident !"RootObj"
+    typeName = head[1]
+    baseName = head[2][1]
+    exported = true
+
+  else:
+    quit "Invalid node: " & head.lispRepr
+
+  # The following prints out the AST structure:
+  #
+  # import macros
+  # dumptree:
+  #   type X = ref object of Y
+  #     z: int
+  # --------------------
+  # StmtList
+  #   TypeSection
+  #     TypeDef
+  #       Ident !"X"
+  #       Empty
+  #       RefTy
+  #         ObjectTy
+  #           Empty
+  #           OfInherit
+  #             Ident !"Y"
+  #           RecList
+  #             IdentDefs
+  #               Ident !"z"
+  #               Ident !"int"
+  #               Empty
+
+  # create a type section in the result
+  result = newNimNode(nnkStmtList)
+  result.add(
+    if exported:
+      # mark `typeName` with an asterisk
+      quote do:
+        type `typeName`* = ref object of `baseName`
+    else:
+      quote do:
+        type `typeName` = ref object of `baseName`
+  )
+
+  # echo treeRepr(body)
+  # --------------------
+  # StmtList
+  #   VarSection
+  #     IdentDefs
+  #       Ident !"name"
+  #       Ident !"string"
+  #       Empty
+  #     IdentDefs
+  #       Ident !"age"
+  #       Ident !"int"
+  #       Empty
+  #   MethodDef
+  #     Ident !"vocalize"
+  #     Empty
+  #     Empty
+  #     FormalParams
+  #       Ident !"string"
+  #     Empty
+  #     Empty
+  #     StmtList
+  #       StrLit ...
+  #   MethodDef
+  #     Ident !"age_human_yrs"
+  #     Empty
+  #     Empty
+  #     FormalParams
+  #       Ident !"int"
+  #     Empty
+  #     Empty
+  #     StmtList
+  #       DotExpr
+  #         Ident !"this"
+  #         Ident !"age"
+
+  # var declarations will be turned into object fields
+  var recList = newNimNode(nnkRecList)
+
+  # expected name of constructor
+  let ctorName = newIdentNode("new" & $typeName)
+
+  # Iterate over the statements, adding `this: T`
+  # to the parameters of functions, unless the
+  # function is a constructor
+  for node in body.children:
+    case node.kind:
+
+      of nnkMethodDef, nnkProcDef:
+        # check if it is the ctor proc
+        if node.name.kind != nnkAccQuoted and node.name.basename == ctorName:
+          # specify the return type of the ctor proc
+          node.params[0] = typeName
+        else:
+          # inject `self: T` into the arguments
+          node.params.insert(1, newIdentDefs(ident("self"), typeName))
+        result.add(node)
+
+      of nnkVarSection:
+        # variables get turned into fields of the type.
+        for n in node.children:
+          recList.add(n)
+
+      else:
+        result.add(node)
+
+  # Inspect the tree structure:
+  #
+  # echo result.treeRepr
+  # --------------------
+  # StmtList
+  #   TypeSection
+  #     TypeDef
+  #       Ident !"Animal"
+  #       Empty
+  #       RefTy
+  #         ObjectTy
+  #           Empty
+  #           OfInherit
+  #             Ident !"RootObj"
+  #           Empty   <= We want to replace this
+  # MethodDef
+  # ...
+
+  result[0][0][2][0][2] = recList
+
+  # Lets inspect the human-readable version of the output
+  #echo repr(result)
diff --git a/nimsuggest/tests/dep_v1.nim b/nimsuggest/tests/fixtures/mdep_v1.nim
index eae230e85..eae230e85 100644
--- a/nimsuggest/tests/dep_v1.nim
+++ b/nimsuggest/tests/fixtures/mdep_v1.nim
diff --git a/nimsuggest/tests/dep_v2.nim b/nimsuggest/tests/fixtures/mdep_v2.nim
index ab39721c4..ab39721c4 100644
--- a/nimsuggest/tests/dep_v2.nim
+++ b/nimsuggest/tests/fixtures/mdep_v2.nim
diff --git a/nimsuggest/tests/fixtures/mfakeassert.nim b/nimsuggest/tests/fixtures/mfakeassert.nim
new file mode 100644
index 000000000..765831ba7
--- /dev/null
+++ b/nimsuggest/tests/fixtures/mfakeassert.nim
@@ -0,0 +1,5 @@
+# Template for testing defs
+
+template fakeAssert*(cond: untyped, msg: string = "") =
+  ## template to allow def lookup testing
+  if not cond: quit(1)
diff --git a/nimsuggest/tests/fixtures/minclude_import.nim b/nimsuggest/tests/fixtures/minclude_import.nim
new file mode 100644
index 000000000..5fa9e5142
--- /dev/null
+++ b/nimsuggest/tests/fixtures/minclude_import.nim
@@ -0,0 +1,15 @@
+# Creates an awkward set of dependencies between this, import, and include.
+# This pattern appears in the compiler, compiler/(sem|ast|semexprs).nim.
+
+import mfakeassert
+import minclude_types
+
+proc say*(g: Greet): string =
+  fakeAssert(true, "always works")
+  g.greeting & ", " & g.subject & "!"
+
+include minclude_include
+
+proc say*(): string =
+  fakeAssert(1 + 1 == 2, "math works")
+  say(create())
diff --git a/nimsuggest/tests/fixtures/minclude_include.nim b/nimsuggest/tests/fixtures/minclude_include.nim
new file mode 100644
index 000000000..23f9892cc
--- /dev/null
+++ b/nimsuggest/tests/fixtures/minclude_include.nim
@@ -0,0 +1,4 @@
+# this file is included and relies on imports within the include
+
+proc create*(greeting: string = "Hello", subject: string = "World"): Greet =
+  Greet(greeting: greeting, subject: subject)
diff --git a/nimsuggest/tests/fixtures/minclude_types.nim b/nimsuggest/tests/fixtures/minclude_types.nim
new file mode 100644
index 000000000..3e85ee540
--- /dev/null
+++ b/nimsuggest/tests/fixtures/minclude_types.nim
@@ -0,0 +1,6 @@
+# types used by minclude_* (import or include), to find with def in include
+
+type
+  Greet* = object
+    greeting*: string
+    subject*: string
\ No newline at end of file
diff --git a/nimsuggest/tests/fixtures/mstrutils.nim b/nimsuggest/tests/fixtures/mstrutils.nim
new file mode 100644
index 000000000..d6f25571b
--- /dev/null
+++ b/nimsuggest/tests/fixtures/mstrutils.nim
@@ -0,0 +1,19 @@
+import mfakeassert
+
+func rereplace*(s, sub: string; by: string = ""): string {.used.} =
+  ## competes for priority in suggestion, here first, but never used in test
+
+  fakeAssert(true, "always works")
+  result = by
+
+func replace*(s, sub: string; by: string = ""): string =
+  ## this is a test version of strutils.replace, it simply returns `by`
+
+  fakeAssert("".len == 0, "empty string is empty")
+  result = by
+
+func rerereplace*(s, sub: string; by: string = ""): string {.used.} =
+  ## isn't used and appears last, lowest priority
+
+  fakeAssert(false, "never works")
+  result = by
diff --git a/nimsuggest/tests/module_20265.nim b/nimsuggest/tests/module_20265.nim
new file mode 100644
index 000000000..24b7d10c9
--- /dev/null
+++ b/nimsuggest/tests/module_20265.nim
@@ -0,0 +1,6 @@
+type A* = tuple
+  a: int
+  b: int
+
+var x*: A = (a: 2, b: 10)
+var y* = (a: 2, b: 10)
diff --git a/nimsuggest/tests/t20265_1.nim b/nimsuggest/tests/t20265_1.nim
new file mode 100644
index 000000000..553b3d545
--- /dev/null
+++ b/nimsuggest/tests/t20265_1.nim
@@ -0,0 +1,8 @@
+discard """
+$nimsuggest --tester $file
+>sug $1
+sug;;skField;;a;;int;;*module_20265.nim;;6;;10;;"";;100;;None
+sug;;skField;;b;;int;;*module_20265.nim;;6;;16;;"";;100;;None
+"""
+import module_20265
+y.#[!]#
diff --git a/nimsuggest/tests/t20265_2.nim b/nimsuggest/tests/t20265_2.nim
new file mode 100644
index 000000000..33edf2d9a
--- /dev/null
+++ b/nimsuggest/tests/t20265_2.nim
@@ -0,0 +1,8 @@
+discard """
+$nimsuggest --tester $file
+>sug $1
+sug;;skField;;a;;int;;*module_20265.nim;;2;;2;;"";;100;;None
+sug;;skField;;b;;int;;*module_20265.nim;;3;;2;;"";;100;;None
+"""
+import module_20265
+x.#[!]#
diff --git a/nimsuggest/tests/t20440.nim b/nimsuggest/tests/t20440.nim
new file mode 100644
index 000000000..0456aa074
--- /dev/null
+++ b/nimsuggest/tests/t20440.nim
@@ -0,0 +1,7 @@
+when not defined(js):
+  {.fatal: "Crash".}
+echo 4
+
+discard """
+$nimsuggest --v3 --tester $file
+"""
diff --git a/nimsuggest/tests/t20440.nims b/nimsuggest/tests/t20440.nims
new file mode 100644
index 000000000..1336be3d4
--- /dev/null
+++ b/nimsuggest/tests/t20440.nims
@@ -0,0 +1 @@
+switch("backend", "js")
diff --git a/nimsuggest/tests/t21185.nim b/nimsuggest/tests/t21185.nim
new file mode 100644
index 000000000..bf5a0e3cc
--- /dev/null
+++ b/nimsuggest/tests/t21185.nim
@@ -0,0 +1,18 @@
+
+# Reduced case of 21185. Issue was first parameter being static
+proc foo(x: static[int]) = discard
+
+type
+  Person = object
+    name: string
+    age: int
+
+let p = Person()
+p.#[!]#
+
+discard """
+$nimsuggest --tester --v3 --maxresults:2 $file
+>sug $1
+sug;;skField;;age;;int;;$file;;8;;4;;"";;100;;None
+sug;;skField;;name;;string;;$file;;7;;4;;"";;100;;None
+"""
diff --git a/nimsuggest/tests/t22448.nim b/nimsuggest/tests/t22448.nim
new file mode 100644
index 000000000..8664bbbc3
--- /dev/null
+++ b/nimsuggest/tests/t22448.nim
@@ -0,0 +1,11 @@
+proc fn(a: static float) = discard
+proc fn(a: int) = discard
+
+let x = 1
+fn(x)
+
+discard """
+$nimsuggest --tester --v3 $file
+>chk $file
+chk;;skUnknown;;;;Hint;;*
+"""
diff --git a/nimsuggest/tests/tarrowcrash.nim b/nimsuggest/tests/tarrowcrash.nim
new file mode 100644
index 000000000..a303e88f5
--- /dev/null
+++ b/nimsuggest/tests/tarrowcrash.nim
@@ -0,0 +1,20 @@
+# issue #24179
+
+import sugar
+
+type
+    Parser[T] = object
+    
+proc eatWhile[T](p: Parser[T], predicate: T -> bool): seq[T] =
+    return @[]
+
+proc skipWs(p: Parser[char]) =
+    discard p.eatWhile((c: char) => c == 'a')
+#[!]#
+    
+discard """
+$nimsuggest --tester $file
+>chk $1
+chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tarrowcrash.nim [Processing]";;0
+chk;;skUnknown;;;;Hint;;$file;;11;;5;;"\'skipWs\' is declared but not used [XDeclaredButNotUsed]";;0
+"""
diff --git a/nimsuggest/tests/tchk1.nim b/nimsuggest/tests/tchk1.nim
index 2b60ed094..be6115c1c 100644
--- a/nimsuggest/tests/tchk1.nim
+++ b/nimsuggest/tests/tchk1.nim
@@ -15,14 +15,13 @@ proc main =
 
 #[!]#
 discard """
-disabled:true
 $nimsuggest --tester $file
 >chk $1
-chk;;skUnknown;;;;Hint;;???;;-1;;-1;;"tchk1 [Processing]";;0
-chk;;skUnknown;;;;Error;;$file;;12;;0;;"identifier expected, but found \'keyword template\'";;0
-chk;;skUnknown;;;;Error;;$file;;14;;0;;"complex statement requires indentation";;0
-chk;;skUnknown;;;;Error;;$file;;12;;0;;"implementation of \'foo\' expected";;0
+chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tchk1.nim [Processing]";;0
+chk;;skUnknown;;;;Error;;$file;;12;;0;;"identifier expected, but got \'keyword template\'";;0
+chk;;skUnknown;;;;Error;;$file;;14;;0;;"nestable statement requires indentation";;0
 chk;;skUnknown;;;;Error;;$file;;17;;0;;"invalid indentation";;0
+chk;;skUnknown;;;;Error;;$file;;12;;0;;"implementation of \'foo\' expected";;0
 chk;;skUnknown;;;;Hint;;$file;;12;;9;;"\'foo\' is declared but not used [XDeclaredButNotUsed]";;0
-chk;;skUnknown;;;;Hint;;$file;;14;;5;;"\'tchk1.main()[declared in tchk1.nim(14, 5)]\' is declared but not used [XDeclaredButNotUsed]";;0
+chk;;skUnknown;;;;Hint;;$file;;14;;5;;"\'main\' is declared but not used [XDeclaredButNotUsed]";;0
 """
diff --git a/nimsuggest/tests/tchk2.nim b/nimsuggest/tests/tchk2.nim
new file mode 100644
index 000000000..f5404368d
--- /dev/null
+++ b/nimsuggest/tests/tchk2.nim
@@ -0,0 +1,35 @@
+# bug #22794
+type O = object
+
+proc `=destroy`(x: O) = discard
+proc `=trace`(x: var O; env: pointer) = discard
+proc `=copy`(a: var O; b: O) = discard
+proc `=dup`(a: O): O {.nodestroy.} = a
+proc `=sink`(a: var O; b: O) = discard
+
+
+# bug #23316
+type SomeSturct = object
+
+proc `=destroy`(x: SomeSturct) =
+  echo "SomeSturct destroyed"
+
+# bug #23867
+type ObjStr = object
+  s: string
+
+let ostr = ObjStr() # <-- nimsuggest crashes
+discard ostr
+
+type ObjSeq = object
+  s: seq[int]
+
+let oseq = ObjSeq() # <-- nimsuggest crashes
+discard oseq
+
+#[!]#
+discard """
+$nimsuggest --tester $file
+>chk $1
+chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tchk2.nim [Processing]";;0
+"""
diff --git a/nimsuggest/tests/tchk_compiles.nim b/nimsuggest/tests/tchk_compiles.nim
new file mode 100644
index 000000000..c8a3daac4
--- /dev/null
+++ b/nimsuggest/tests/tchk_compiles.nim
@@ -0,0 +1,8 @@
+discard compiles(2 + "hello")
+
+#[!]#
+discard """
+$nimsuggest --tester $file
+>chk $1
+chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tchk_compiles.nim [Processing]";;0
+"""
diff --git a/nimsuggest/tests/tcon1.nim b/nimsuggest/tests/tcon1.nim
index 262dd5151..627e7f400 100644
--- a/nimsuggest/tests/tcon1.nim
+++ b/nimsuggest/tests/tcon1.nim
@@ -1,13 +1,43 @@
+## Test Invocation `con`text in various situations
+
+## various of this proc are used as the basis for these tests
 proc test(s: string; a: int) = discard
+
+## This overload should be used to ensure the lower airity `test` doesn't match
+proc test(s: string; a: string, b: int) = discard
+
+## similar signature but different name to ensure `con` doesn't get greedy
 proc testB(a, b: string) = discard
+
+# with a param already specified
 test("hello here", #[!]#)
+
+# as first param
 testB(#[!]#
 
+# dot expressions
+"from behind".test(#[!]#
+
+# two params matched, so disqualify the lower airity `test`
+# TODO: this doesn't work, because dot exprs, overloads, etc aren't currently
+#       handled by suggest.suggestCall. sigmatch.partialMatch by way of
+#       sigmatch.matchesAux. Doesn't use the operand before the dot as part of
+#       the formal parameters. Changing this is tricky because it's used by
+#       the proper compilation sem pass and that's a big change all in one go.
+"and again".test("more", #[!]#
+
 
 discard """
 $nimsuggest --tester $file
 >con $1
-con;;skProc;;tcon1.test;;proc (s: string, a: int);;$file;;1;;5;;"";;100
+con;;skProc;;tcon1.test;;proc (s: string, a: int);;$file;;4;;5;;"";;100
+con;;skProc;;tcon1.test;;proc (s: string, a: string, b: int);;$file;;7;;5;;"";;100
 >con $2
-con;;skProc;;tcon1.testB;;proc (a: string, b: string);;$file;;2;;5;;"";;100
+con;;skProc;;tcon1.testB;;proc (a: string, b: string);;$file;;10;;5;;"";;100
+>con $3
+con;;skProc;;tcon1.test;;proc (s: string, a: string, b: int);;$file;;7;;5;;"";;100
+con;;skProc;;tcon1.test;;proc (s: string, a: int);;$file;;4;;5;;"";;100
+>con $4
+con;;skProc;;tcon1.test;;proc (s: string, a: int);;$file;;4;;5;;"";;100
+con;;skProc;;tcon1.test;;proc (s: string, a: string, b: int);;$file;;7;;5;;"";;100
 """
diff --git a/nimsuggest/tests/tconcept1.nim b/nimsuggest/tests/tconcept1.nim
new file mode 100644
index 000000000..d81cd8120
--- /dev/null
+++ b/nimsuggest/tests/tconcept1.nim
@@ -0,0 +1,12 @@
+SomeNumber = concept
+
+#[!]#
+discard """
+$nimsuggest --tester $file
+>chk $1
+chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tconcept1.nim [Processing]";;0
+chk;;skUnknown;;;;Error;;$file;;1;;13;;"the \'concept\' keyword is only valid in \'type\' sections";;0
+chk;;skUnknown;;;;Error;;$file;;1;;13;;"invalid indentation";;0
+chk;;skUnknown;;;;Error;;$file;;1;;13;;"expression expected, but found \'keyword concept\'";;0
+chk;;skUnknown;;;;Error;;$file;;1;;0;;"\'SomeNumber\' cannot be assigned to";;0
+"""
diff --git a/nimsuggest/tests/tconcept2.nim b/nimsuggest/tests/tconcept2.nim
new file mode 100644
index 000000000..7f7d147f5
--- /dev/null
+++ b/nimsuggest/tests/tconcept2.nim
@@ -0,0 +1,15 @@
+  SomeNumber = concept a, type T
+    a.int is int
+    int.to(T) is type(a)
+
+#[!]#
+discard """
+$nimsuggest --tester $file
+>chk $1
+chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tconcept2.nim [Processing]";;0
+chk;;skUnknown;;;;Error;;$file;;1;;2;;"invalid indentation";;0
+chk;;skUnknown;;;;Error;;$file;;1;;15;;"the \'concept\' keyword is only valid in \'type\' sections";;0
+chk;;skUnknown;;;;Error;;$file;;1;;15;;"invalid indentation";;0
+chk;;skUnknown;;;;Error;;$file;;1;;15;;"expression expected, but found \'keyword concept\'";;0
+chk;;skUnknown;;;;Error;;$file;;1;;2;;"\'SomeNumber\' cannot be assigned to";;0
+"""
diff --git a/nimsuggest/tests/tdef1.nim b/nimsuggest/tests/tdef1.nim
index 2cd040ea1..49265bbc1 100644
--- a/nimsuggest/tests/tdef1.nim
+++ b/nimsuggest/tests/tdef1.nim
@@ -1,12 +1,14 @@
 discard """
 $nimsuggest --tester $file
 >def $1
-def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, locks: 0.};;$file;;9;;5;;"Return hello";;100
->def $1
-def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, locks: 0.};;$file;;9;;5;;"Return hello";;100
+def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;11;;5;;"Return hello";;100
+>def $2
+def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;11;;5;;"Return hello";;100
+>def $2
+def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;11;;5;;"Return hello";;100
 """
 
-proc hello(): string =
+proc hel#[!]#lo(): string =
   ## Return hello
   "Hello"
 
diff --git a/nimsuggest/tests/tdef2.nim b/nimsuggest/tests/tdef2.nim
new file mode 100644
index 000000000..299b83a3d
--- /dev/null
+++ b/nimsuggest/tests/tdef2.nim
@@ -0,0 +1,13 @@
+# Test def with template and boundaries for the cursor
+
+import fixtures/mstrutils
+
+discard """
+$nimsuggest --tester $file
+>def $path/fixtures/mstrutils.nim:6:4
+def;;skTemplate;;mfakeassert.fakeAssert;;template (cond: untyped, msg: string);;*fixtures/mfakeassert.nim;;3;;9;;"template to allow def lookup testing";;100
+>def $path/fixtures/mstrutils.nim:12:3
+def;;skTemplate;;mfakeassert.fakeAssert;;template (cond: untyped, msg: string);;*fixtures/mfakeassert.nim;;3;;9;;"template to allow def lookup testing";;100
+>def $path/fixtures/mstrutils.nim:18:11
+def;;skTemplate;;mfakeassert.fakeAssert;;template (cond: untyped, msg: string);;*fixtures/mfakeassert.nim;;3;;9;;"template to allow def lookup testing";;100
+"""
diff --git a/nimsuggest/tests/tdef_forward.nim b/nimsuggest/tests/tdef_forward.nim
new file mode 100644
index 000000000..9bdd8b21d
--- /dev/null
+++ b/nimsuggest/tests/tdef_forward.nim
@@ -0,0 +1,13 @@
+discard """
+$nimsuggest --tester $file
+>def $1
+def;;skProc;;tdef_forward.hello;;proc (): string;;$file;;8;;5;;"";;100
+def;;skProc;;tdef_forward.hello;;proc (): string;;$file;;12;;5;;"";;100
+"""
+
+proc hello(): string
+
+hel#[!]#lo()
+
+proc hello(): string =
+  "Hello"
diff --git a/nimsuggest/tests/tdef_let.nim b/nimsuggest/tests/tdef_let.nim
new file mode 100644
index 000000000..3e9456d2f
--- /dev/null
+++ b/nimsuggest/tests/tdef_let.nim
@@ -0,0 +1,7 @@
+discard """
+$nimsuggest --tester $file
+>def $1
+def;;skLet;;tdef_let.intVar;;int;;$file;;7;;4;;"";;100
+"""
+
+let int#[!]#Var = 10
diff --git a/nimsuggest/tests/tdot3.nim b/nimsuggest/tests/tdot3.nim
index 15fc1cd1c..30dd60591 100644
--- a/nimsuggest/tests/tdot3.nim
+++ b/nimsuggest/tests/tdot3.nim
@@ -9,14 +9,14 @@ proc main(f: Foo) =
 # this way, the line numbers more often stay the same
 
 discard """
-!copy dep_v1.nim dep.nim
+!copy fixtures/mdep_v1.nim dep.nim
 $nimsuggest --tester $file
 >sug $1
 sug;;skField;;x;;int;;*dep.nim;;8;;4;;"";;100;;None
 sug;;skField;;y;;int;;*dep.nim;;8;;8;;"";;100;;None
 sug;;skProc;;tdot3.main;;proc (f: Foo);;$file;;5;;5;;"";;100;;None
 
-!copy dep_v2.nim dep.nim
+!copy fixtures/mdep_v2.nim dep.nim
 >mod $path/dep.nim
 >sug $1
 sug;;skField;;x;;int;;*dep.nim;;8;;4;;"";;100;;None
diff --git a/nimsuggest/tests/tdot4.nim b/nimsuggest/tests/tdot4.nim
index 762534310..f2c6c765f 100644
--- a/nimsuggest/tests/tdot4.nim
+++ b/nimsuggest/tests/tdot4.nim
@@ -1,17 +1,21 @@
-discard """
-disabled:true
-$nimsuggest --tester --maxresults:2 $file
->sug $1
-sug;;skProc;;tdot4.main;;proc (inp: string): string;;$file;;10;;5;;"";;100;;None
-sug;;skProc;;strutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe, locks: 0.};;$lib/pure/strutils.nim;;1506;;5;;"Replaces `sub` in `s` by the string `by`.";;100;;None
-"""
+# Test that already used suggestions are prioritized
 
-import strutils
+from system import string, echo
+import fixtures/mstrutils
 
 proc main(inp: string): string =
   # use replace here and see if it occurs in the result, it should gain
   # priority:
   result = inp.replace(" ", "a").replace("b", "c")
 
-
 echo "string literal here".#[!]#
+
+# priority still tested, but limit results to avoid failures from other output
+discard """
+$nimsuggest --tester --maxresults:2 $file
+>sug $1
+sug;;skProc;;tdot4.main;;proc (inp: string): string;;$file;;6;;5;;"";;100;;None
+sug;;skFunc;;mstrutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe, raises: <inferred> [].};;*fixtures/mstrutils.nim;;9;;5;;"this is a test version of strutils.replace, it simply returns `by`";;100;;None
+"""
+
+# TODO - determine appropriate behaviour for further suggest output and test it
diff --git a/nimsuggest/tests/tenum_field.nim b/nimsuggest/tests/tenum_field.nim
new file mode 100644
index 000000000..4ceb3e021
--- /dev/null
+++ b/nimsuggest/tests/tenum_field.nim
@@ -0,0 +1,17 @@
+discard """
+$nimsuggest --tester $file
+>sug $1
+>sug $2
+sug;;skConst;;tenum_field.BarFoo;;int literal(1);;$file;;10;;6;;"";;100;;Prefix
+"""
+
+proc something() = discard
+
+const BarFoo = 1
+
+type
+  Foo = enum
+    # Test that typing the name doesn't give suggestions
+    somethi#[!]#
+    # Test that the right hand side still gets suggestions
+    another = BarFo#[!]#
diff --git a/nimsuggest/tests/tfatal1.nim b/nimsuggest/tests/tfatal1.nim
new file mode 100644
index 000000000..19778f22e
--- /dev/null
+++ b/nimsuggest/tests/tfatal1.nim
@@ -0,0 +1,15 @@
+{.warning: "I'm a warning!".}
+{.error: "I'm an error!".}
+{.fatal: "I'm a fatal error!".}
+{.error: "I'm an error after fatal error!".}
+
+#[!]#
+discard """
+$nimsuggest --tester $file
+>chk $1
+chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/tfatal1.nim [Processing]";;0
+chk;;skUnknown;;;;Warning;;$file;;1;;9;;"I\'m a warning! [User]";;0
+chk;;skUnknown;;;;Error;;$file;;2;;7;;"I\'m an error!";;0
+chk;;skUnknown;;;;Error;;$file;;3;;7;;"fatal error: I\'m a fatal error!";;0
+chk;;skUnknown;;;;Error;;$file;;4;;7;;"I\'m an error after fatal error!";;0
+"""
diff --git a/nimsuggest/tests/tgeneric_highlight.nim b/nimsuggest/tests/tgeneric_highlight.nim
index 334323613..c7291d08b 100644
--- a/nimsuggest/tests/tgeneric_highlight.nim
+++ b/nimsuggest/tests/tgeneric_highlight.nim
@@ -7,14 +7,7 @@ $nimsuggest --tester $file
 >highlight $1
 highlight;;skType;;1;;7;;3
 highlight;;skProc;;1;;0;;6
-highlight;;skProc;;1;;0;;6
-highlight;;skType;;1;;7;;3
-highlight;;skProc;;1;;0;;6
-highlight;;skType;;2;;14;;3
-highlight;;skProc;;2;;7;;6
-highlight;;skProc;;2;;7;;6
 highlight;;skType;;2;;14;;3
 highlight;;skProc;;2;;7;;6
-highlight;;skTemplate;;3;;0;;8
 highlight;;skType;;3;;9;;3
 """
diff --git a/nimsuggest/tests/tgenerics.nim b/nimsuggest/tests/tgenerics.nim
new file mode 100644
index 000000000..7f490321c
--- /dev/null
+++ b/nimsuggest/tests/tgenerics.nim
@@ -0,0 +1,18 @@
+type
+  Hello[T] = object
+    value: T
+
+proc printHelloValue[T](hello: Hello[T]) =
+  echo hello.value
+
+proc main() =
+  let a = Hello[float]()
+  p#[!]#rintHelloValue(a)
+
+main()
+
+discard """
+$nimsuggest --tester $file
+>def $1
+def;;skProc;;tgenerics.printHelloValue;;proc (hello: Hello[printHelloValue.T]);;$file;;5;;5;;"";;100
+"""
diff --git a/nimsuggest/tests/tic.nim b/nimsuggest/tests/tic.nim
new file mode 100644
index 000000000..26e644f83
--- /dev/null
+++ b/nimsuggest/tests/tic.nim
@@ -0,0 +1,20 @@
+import std/[appdirs, assertions, cmdline, compilesettings, decls, 
+  dirs, editdistance, effecttraits, enumerate, enumutils, envvars, 
+  exitprocs, files, formatfloat, genasts, importutils, 
+  isolation, jsonutils, logic, monotimes, objectdollar, 
+  oserrors, outparams, packedsets, paths, private, setutils, sha1, 
+  socketstreams, stackframes, staticos, strbasics, symlinks, syncio, 
+  sysatomics, sysrand, tasks, tempfiles, time_t, typedthreads, varints, 
+  vmutils, widestrs, with, wordwrap, wrapnils]
+
+proc test(a: string, b:string) = discard
+proc test(a: int) = discard
+
+test(#[!]#
+
+discard """
+$nimsuggest --v3 --ic:off --tester $file 
+>con $1
+con;;skProc;;tic.test;;proc (a: string, b: string);;$file;;10;;5;;"";;100
+con;;skProc;;tic.test;;proc (a: int);;$file;;11;;5;;"";;100
+"""
\ No newline at end of file
diff --git a/nimsuggest/tests/timport_highlight.nim b/nimsuggest/tests/timport_highlight.nim
new file mode 100644
index 000000000..043f87d98
--- /dev/null
+++ b/nimsuggest/tests/timport_highlight.nim
@@ -0,0 +1,12 @@
+import std/paths
+import json as J
+import std/[os,streams]#[!]#
+
+discard """
+$nimsuggest --tester $file
+>highlight $1
+highlight;;skModule;;1;;11;;5
+highlight;;skModule;;2;;7;;4
+highlight;;skModule;;3;;12;;2
+highlight;;skModule;;3;;15;;7
+"""
diff --git a/nimsuggest/tests/tinclude.nim b/nimsuggest/tests/tinclude.nim
index 0fda43911..f5cbabf05 100644
--- a/nimsuggest/tests/tinclude.nim
+++ b/nimsuggest/tests/tinclude.nim
@@ -1,8 +1,25 @@
+# import that has an include:
+# * def calls must work into and out of includes
+# * outline calls on the import must show included members
+import fixtures/minclude_import
+
+proc go() =
+  discard create().say()
+
+go()
+
 discard """
-disabled:true
-$nimsuggest --tester compiler/nim.nim
->def compiler/semexprs.nim:25:50
-def;;skType;;ast.PSym;;PSym;;*ast.nim;;707;;2;;"";;100
->def compiler/semexprs.nim:25:50
-def;;skType;;ast.PSym;;PSym;;*ast.nim;;707;;2;;"";;100
+$nimsuggest --tester $file
+>def $path/tinclude.nim:7:14
+def;;skProc;;minclude_import.create;;proc (greeting: string, subject: string): Greet{.noSideEffect, gcsafe, raises: <inferred> [].};;*fixtures/minclude_include.nim;;3;;5;;"";;100
+>def $path/fixtures/minclude_include.nim:3:71
+def;;skType;;minclude_types.Greet;;Greet;;*fixtures/minclude_types.nim;;4;;2;;"";;100
+>def $path/fixtures/minclude_include.nim:3:71
+def;;skType;;minclude_types.Greet;;Greet;;*fixtures/minclude_types.nim;;4;;2;;"";;100
+>outline $path/fixtures/minclude_import.nim
+outline;;skProc;;minclude_import.say;;*fixtures/minclude_import.nim;;7;;5;;"";;100
+outline;;skProc;;minclude_import.create;;*fixtures/minclude_include.nim;;3;;5;;"";;100
+outline;;skProc;;minclude_import.say;;*fixtures/minclude_import.nim;;13;;5;;"";;100
 """
+
+# TODO test/fix if the first `def` is not first or repeated we get no results
diff --git a/nimsuggest/tests/top_highlight.nim b/nimsuggest/tests/top_highlight.nim
new file mode 100644
index 000000000..c3f6bb61d
--- /dev/null
+++ b/nimsuggest/tests/top_highlight.nim
@@ -0,0 +1,11 @@
+import json
+
+%*{}#[!]#
+
+discard """
+$nimsuggest --tester $file
+>highlight $1
+highlight;;skModule;;1;;7;;4
+highlight;;skMacro;;3;;0;;2
+highlight;;skMacro;;3;;0;;2
+"""
diff --git a/nimsuggest/tests/tqualified_highlight.nim b/nimsuggest/tests/tqualified_highlight.nim
index 3b521ecc1..b83669e72 100644
--- a/nimsuggest/tests/tqualified_highlight.nim
+++ b/nimsuggest/tests/tqualified_highlight.nim
@@ -10,5 +10,5 @@ highlight;;skProc;;1;;7;;4
 highlight;;skTemplate;;2;;7;;4
 highlight;;skTemplate;;2;;7;;4
 highlight;;skTemplate;;2;;7;;4
-highlight;;skProc;;3;;8;;1
+highlight;;skFunc;;3;;8;;1
 """
diff --git a/nimsuggest/tests/tstrutils.nim b/nimsuggest/tests/tstrutils.nim
deleted file mode 100644
index 9462c3d99..000000000
--- a/nimsuggest/tests/tstrutils.nim
+++ /dev/null
@@ -1,10 +0,0 @@
-discard """
-disabled:true
-$nimsuggest --tester lib/pure/strutils.nim
->def lib/pure/strutils.nim:2529:6
-def;;skTemplate;;system.doAssert;;proc (cond: bool, msg: string): typed;;*/lib/system.nim;;*;;9;;"same as `assert` but is always turned on and not affected by the\x0A``--assertions`` command line switch.";;100
-"""
-
-# Line 2529 in strutils.nim is doAssert and this is unlikely to change
-# soon since there are a whole lot of doAsserts there.
-
diff --git a/nimsuggest/tests/tsug_enum.nim b/nimsuggest/tests/tsug_enum.nim
new file mode 100644
index 000000000..97a225f16
--- /dev/null
+++ b/nimsuggest/tests/tsug_enum.nim
@@ -0,0 +1,18 @@
+## suggestions for enums
+
+type
+  LogLevel {.pure.} = enum
+    debug, log, warn, error
+  
+  FooBar = enum
+    fbFoo, fbBar
+
+echo fbFoo, fbBar
+
+echo LogLevel.deb#[!]#
+
+discard """
+$nimsuggest --tester $file
+>sug $1
+sug;;skEnumField;;debug;;LogLevel;;*nimsuggest/tests/tsug_enum.nim;;5;;4;;"";;100;;Prefix
+"""
\ No newline at end of file
diff --git a/nimsuggest/tests/tsug_pragmas.nim b/nimsuggest/tests/tsug_pragmas.nim
new file mode 100644
index 000000000..ce9c4e8f8
--- /dev/null
+++ b/nimsuggest/tests/tsug_pragmas.nim
@@ -0,0 +1,40 @@
+template fooBar1() {.pragma.}
+proc fooBar2() = discard
+macro fooBar3(x: untyped) = discard
+{.pragma: fooBar4 fooBar3.}
+
+proc test1() {.fooBar#[!]#.} = discard
+
+var test2 {.fooBar#[!]#.} = 9
+
+type
+  Person {.fooBar#[!]#.} = object
+    hello {.fooBar#[!]#.}: string
+  Callback = proc () {.fooBar#[!]#.}
+
+# Check only macros/templates/pragmas are suggested
+discard """
+$nimsuggest --tester $file
+>sug $1
+sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix
+sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix
+sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;3;;6;;"";;50;;Prefix
+>sug $2
+sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix
+sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix
+sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;3;;6;;"";;50;;Prefix
+>sug $3
+sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix
+sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix
+sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;3;;6;;"";;50;;Prefix
+>sug $4
+sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix
+sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix
+sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;3;;6;;"";;50;;Prefix
+>sug $5
+sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix
+sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix
+sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;3;;6;;"";;50;;Prefix
+"""
+
+
diff --git a/nimsuggest/tests/tsug_recursive.nim b/nimsuggest/tests/tsug_recursive.nim
new file mode 100644
index 000000000..97ee5ca01
--- /dev/null
+++ b/nimsuggest/tests/tsug_recursive.nim
@@ -0,0 +1,8 @@
+discard """
+$nimsuggest --tester $file
+>sug $1
+sug;;skProc;;tsug_recursive.fooBar;;proc ();;$file;;7;;5;;"";;100;;Prefix
+"""
+
+proc fooBar() =
+  fooBa#[!]#
diff --git a/nimsuggest/tests/tsug_regression.nim b/nimsuggest/tests/tsug_regression.nim
index 1b23da806..2aff3fe94 100644
--- a/nimsuggest/tests/tsug_regression.nim
+++ b/nimsuggest/tests/tsug_regression.nim
@@ -7,23 +7,28 @@ type X = object
 proc main =
   # bug #52
   var
-    set0 = initSet[int]()
-    set1 = initSet[X]()
-    set2 = initSet[ref int]()
+    set0 = initHashSet[int]()
+    set1 = initHashSet[X]()
+    set2 = initHashSet[ref int]()
 
     map0 = initTable[int, int]()
     map1 = initOrderedTable[string, int]()
     cfg = loadConfig("file")
   map0.#[!]#
 
+# the maxresults are limited as it seems there is sort or some other
+# instability that causes the suggestions to slightly differ between 32 bit
+# and 64 bit versions of nimsuggest
+
 discard """
 disabled:true
-$nimsuggest --tester $file
+$nimsuggest --tester --maxresults:4 $file
 >sug $1
-sug;;skProc;;tables.getOrDefault;;proc (t: Table[getOrDefault.A, getOrDefault.B], key: A): B;;$lib/pure/collections/tables.nim;;178;;5;;"";;100;;None
-sug;;skProc;;tables.hasKey;;proc (t: Table[hasKey.A, hasKey.B], key: A): bool;;$lib/pure/collections/tables.nim;;233;;5;;"returns true iff `key` is in the table `t`.";;100;;None
-sug;;skProc;;tables.add;;proc (t: var Table[add.A, add.B], key: A, val: B);;$lib/pure/collections/tables.nim;;309;;5;;"puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.";;100;;None
-sug;;skIterator;;tables.allValues;;iterator (t: Table[allValues.A, allValues.B], key: A): B{.inline.};;$lib/pure/collections/tables.nim;;225;;9;;"iterates over any value in the table `t` that belongs to the given `key`.";;100;;None
-sug;;skProc;;tables.clear;;proc (t: var Table[clear.A, clear.B]);;$lib/pure/collections/tables.nim;;121;;5;;"Resets the table so that it is empty.";;100;;None
-*
+sug;;skProc;;tables.hasKey;;proc (t: Table[hasKey.A, hasKey.B], key: A): bool;;*/lib/pure/collections/tables.nim;;374;;5;;"Returns true *";;100;;None
+sug;;skProc;;tables.clear;;proc (t: var Table[clear.A, clear.B]);;*/lib/pure/collections/tables.nim;;567;;5;;"Resets the table so that it is empty*";;100;;None
+sug;;skProc;;tables.contains;;proc (t: Table[contains.A, contains.B], key: A): bool;;*/lib/pure/collections/tables.nim;;*;;5;;"Alias of *";;100;;None
+sug;;skProc;;tables.del;;proc (t: var Table[del.A, del.B], key: A);;*/lib/pure/collections/tables.nim;;*;;5;;"*";;100;;None
 """
+
+# TODO enable the tests
+# TODO: test/fix suggestion sorting - deprecated suggestions should rank lower
diff --git a/nimsuggest/tests/tsug_template.nim b/nimsuggest/tests/tsug_template.nim
index 0f258fcc6..da494d279 100644
--- a/nimsuggest/tests/tsug_template.nim
+++ b/nimsuggest/tests/tsug_template.nim
@@ -6,7 +6,7 @@ tmp#[!]#
 discard """
 $nimsuggest --tester $file
 >sug $1
-sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe, locks: 0.};;$file;;2;;6;;"";;0;;Prefix
-sug;;skConverter;;tsug_template.tmpc;;converter ();;$file;;3;;10;;"";;0;;Prefix
-sug;;skTemplate;;tsug_template.tmpa;;template ();;$file;;1;;9;;"";;0;;Prefix
+sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;2;;6;;"";;100;;Prefix
+sug;;skConverter;;tsug_template.tmpc;;converter ();;$file;;3;;10;;"";;100;;Prefix
+sug;;skTemplate;;tsug_template.tmpa;;template ();;$file;;1;;9;;"";;100;;Prefix
 """
diff --git a/nimsuggest/tests/tsug_typedecl.nim b/nimsuggest/tests/tsug_typedecl.nim
new file mode 100644
index 000000000..2a510929d
--- /dev/null
+++ b/nimsuggest/tests/tsug_typedecl.nim
@@ -0,0 +1,26 @@
+# suggestions for type declarations
+
+from system import string, int, bool
+
+type
+  super = int
+  someType = bool
+
+let str = "hello"
+
+proc main() =
+  let a: s#[!]#
+
+# This output show seq, even though that's not imported. This is due to the
+# entire symbol table, regardless of import visibility is currently being
+# scanned. This is hardly ideal, but changing it with the current level of test
+# coverage is unwise as it might break more than it fixes.
+
+discard """
+$nimsuggest --tester $file
+>sug $1
+sug;;skType;;tsug_typedecl.someType;;someType;;*nimsuggest/tests/tsug_typedecl.nim;;7;;2;;"";;100;;Prefix
+sug;;skType;;tsug_typedecl.super;;super;;*nimsuggest/tests/tsug_typedecl.nim;;6;;2;;"";;100;;Prefix
+sug;;skType;;system.string;;string;;*lib/system/basic_types.nim;;*;;*;;*;;100;;Prefix
+sug;;skType;;system.seq;;seq;;*lib/system.nim;;*;;*;;*;;100;;Prefix
+"""
diff --git a/nimsuggest/tests/ttempl_inst.nim b/nimsuggest/tests/ttempl_inst.nim
new file mode 100644
index 000000000..5f5b10fe9
--- /dev/null
+++ b/nimsuggest/tests/ttempl_inst.nim
@@ -0,0 +1,13 @@
+template foo() =
+  {.warning: "foo".}
+  
+foo()
+
+#[!]#
+discard """
+$nimsuggest --tester $file
+>chk $1
+chk;;skUnknown;;;;Hint;;???;;0;;-1;;">> (toplevel): import(dirty): tests/ttempl_inst.nim [Processing]";;0
+chk;;skUnknown;;;;Hint;;$file;;4;;3;;"template/generic instantiation from here";;0
+chk;;skUnknown;;;;Warning;;$file;;2;;11;;"foo [User]";;0
+"""
diff --git a/nimsuggest/tests/disabled_ttemplate_highlight.nim b/nimsuggest/tests/ttemplate_highlight.nim
index 2cbac3be5..2cbac3be5 100644
--- a/nimsuggest/tests/disabled_ttemplate_highlight.nim
+++ b/nimsuggest/tests/ttemplate_highlight.nim
diff --git a/nimsuggest/tests/ttype_decl.nim b/nimsuggest/tests/ttype_decl.nim
index e66d39a1c..61d8c26cd 100644
--- a/nimsuggest/tests/ttype_decl.nim
+++ b/nimsuggest/tests/ttype_decl.nim
@@ -1,15 +1,16 @@
 discard """
-disabled:true
 $nimsuggest --tester --maxresults:3 $file
 >sug $1
-sug;;skType;;ttype_decl.Other;;Other;;$file;;10;;2;;"";;0;;None
-sug;;skType;;system.int;;int;;$lib/system.nim;;25;;2;;"";;0;;None
-sug;;skType;;system.string;;string;;$lib/system.nim;;48;;2;;"";;0;;None
+sug;;skType;;ttype_decl.Other;;Other;;$file;;10;;2;;"";;100;;None
+sug;;skType;;system.int;;int;;*lib/system/basic_types.nim;;2;;2;;"";;100;;None
+sug;;skType;;system.string;;string;;*lib/system/basic_types.nim;;23;;2;;"";;100;;None
 """
 import strutils
 type
   Other = object ## My other object.
   Foo = #[!]#
+  OldOne {.deprecated.} = object
+    x: int
 
 proc main(f: Foo) =
 
diff --git a/nimsuggest/tests/tuse.nim b/nimsuggest/tests/tuse.nim
new file mode 100644
index 000000000..7c1d1ad0c
--- /dev/null
+++ b/nimsuggest/tests/tuse.nim
@@ -0,0 +1,22 @@
+# basic tests for use
+
+# bug #58
+proc someOtherProc() =
+  discard
+
+someOtherProc()
+
+proc #[!]#someProc*() =
+  discard
+
+#[!]#someProc()
+
+discard """
+$nimsuggest --tester $file
+>use $1
+def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;9;;5;;"";;100
+use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;12;;0;;"";;100
+>use $2
+def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;9;;5;;"";;100
+use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;12;;0;;"";;100
+"""
diff --git a/nimsuggest/tests/tuse_enum.nim b/nimsuggest/tests/tuse_enum.nim
new file mode 100644
index 000000000..8a40a8348
--- /dev/null
+++ b/nimsuggest/tests/tuse_enum.nim
@@ -0,0 +1,15 @@
+discard """
+$nimsuggest --tester $file
+>use $1
+def;;skEnumField;;tuse_enum.Colour.Red;;Colour;;$file;;10;;4;;"";;100
+use;;skEnumField;;tuse_enum.Colour.Red;;Colour;;$file;;14;;8;;"";;100
+"""
+
+type
+  Colour = enum
+    Red
+    Green
+    Blue
+
+discard #[!]#Red
+
diff --git a/nimsuggest/tests/tuse_structure.nim b/nimsuggest/tests/tuse_structure.nim
new file mode 100644
index 000000000..f65ab9060
--- /dev/null
+++ b/nimsuggest/tests/tuse_structure.nim
@@ -0,0 +1,15 @@
+# tests for use and structures
+
+type
+  Foo* = ref object of RootObj
+    bar*: string
+
+proc test(f: Foo) =
+  echo f.#[!]#bar
+
+discard """
+$nimsuggest --tester $file
+>use $1
+def	skField	tuse_structure.Foo.bar	string	$file	5	4	""	100
+use	skField	tuse_structure.Foo.bar	string	$file	8	9	""	100
+"""
diff --git a/nimsuggest/tests/tv3.nim b/nimsuggest/tests/tv3.nim
new file mode 100644
index 000000000..80e51e364
--- /dev/null
+++ b/nimsuggest/tests/tv3.nim
@@ -0,0 +1,27 @@
+# tests v3
+
+type
+  Foo* = ref object of RootObj
+    bar*: string
+
+proc test(f: Foo) =
+  echo f.ba#[!]#r
+
+#[!]#
+
+discard """
+$nimsuggest --v3 --tester $file
+>use $1
+def	skField	tv3.Foo.bar	string	$file	5	4	""	100
+use	skField	tv3.Foo.bar	string	$file	8	9	""	100
+>def $1
+def	skField	tv3.Foo.bar	string	$file	5	4	""	100
+>sug $1
+sug	skField	bar	string	$file	5	4	""	100	Prefix
+>globalSymbols test
+def	skProc	tv3.test	proc (f: Foo){.gcsafe, raises: <inferred> [].}	$file	7	5	""	100
+>globalSymbols Foo
+def	skType	tv3.Foo	Foo	$file	4	2	""	100
+>def $2
+>use $2
+"""
diff --git a/nimsuggest/tests/tv3_con.nim b/nimsuggest/tests/tv3_con.nim
new file mode 100644
index 000000000..4714c366b
--- /dev/null
+++ b/nimsuggest/tests/tv3_con.nim
@@ -0,0 +1,13 @@
+# tests v3
+
+proc test(a: string, b:string) = discard
+proc test(a: int) = discard
+
+test(#[!]#
+
+discard """
+$nimsuggest --v3 --tester $file
+>con $1
+con;;skProc;;tv3_con.test;;proc (a: string, b: string);;$file;;3;;5;;"";;100
+con;;skProc;;tv3_con.test;;proc (a: int);;$file;;4;;5;;"";;100
+"""
diff --git a/nimsuggest/tests/tv3_definition.nim b/nimsuggest/tests/tv3_definition.nim
new file mode 100644
index 000000000..03684b7cd
--- /dev/null
+++ b/nimsuggest/tests/tv3_definition.nim
@@ -0,0 +1,9 @@
+
+let foo = 30
+let bar = foo + fo#[!]#o + foo
+
+discard """
+$nimsuggest --v3 --tester $file
+>def $1
+def	skLet	tv3_definition.foo	int	$file	2	4	""	100
+"""
diff --git a/nimsuggest/tests/tv3_forward_definition.nim b/nimsuggest/tests/tv3_forward_definition.nim
new file mode 100644
index 000000000..7a16ea331
--- /dev/null
+++ b/nimsuggest/tests/tv3_forward_definition.nim
@@ -0,0 +1,23 @@
+proc de#[!]#mo(): int
+
+proc de#[!]#mo(): int = 5
+
+let a = de#[!]#mo()
+
+discard """
+$nimsuggest --v3 --tester $file
+>use $1
+use	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	1	5	""	100
+def	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	3	5	""	100
+use	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	5	8	""	100
+>use $2
+use	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	1	5	""	100
+def	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	3	5	""	100
+use	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	5	8	""	100
+>declaration $1
+declaration	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	3	5	""	100
+>declaration $2
+declaration	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	1	5	""	100
+>declaration $3
+declaration	skProc	tv3_forward_definition.demo	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	1	5	""	100
+"""
diff --git a/nimsuggest/tests/tv3_generics.nim b/nimsuggest/tests/tv3_generics.nim
new file mode 100644
index 000000000..2bfb2ca1d
--- /dev/null
+++ b/nimsuggest/tests/tv3_generics.nim
@@ -0,0 +1,18 @@
+type
+  Hello[T] = object
+    value: T
+
+proc printHelloValue[T](hello: Hello[T]) =
+  echo hello.value
+
+proc main() =
+  let a = Hello[float]()
+  p#[!]#rintHelloValue(a)
+
+main()
+
+discard """
+$nimsuggest --v3 --tester $file
+>def $1
+def;;skProc;;tv3_generics.printHelloValue;;proc (hello: Hello[printHelloValue.T]);;$file;;5;;5;;"";;100
+"""
diff --git a/nimsuggest/tests/tv3_globalSymbols.nim b/nimsuggest/tests/tv3_globalSymbols.nim
new file mode 100644
index 000000000..c3bb9933b
--- /dev/null
+++ b/nimsuggest/tests/tv3_globalSymbols.nim
@@ -0,0 +1,14 @@
+# Tests the order of the matches
+proc Btoken(): int = 5
+proc tokenA(): int = 5
+proc token(): int = 5
+proc BBtokenA(): int = 5
+
+discard """
+$nimsuggest --v3 --tester $file
+>globalSymbols token
+def	skProc	tv3_globalSymbols.token	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	4	5	""	100
+def	skProc	tv3_globalSymbols.tokenA	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	3	5	""	100
+def	skProc	tv3_globalSymbols.Btoken	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	2	5	""	100
+def	skProc	tv3_globalSymbols.BBtokenA	proc (): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	5	5	""	100
+"""
diff --git a/nimsuggest/tests/tv3_import.nim b/nimsuggest/tests/tv3_import.nim
new file mode 100644
index 000000000..3c128f85b
--- /dev/null
+++ b/nimsuggest/tests/tv3_import.nim
@@ -0,0 +1,7 @@
+import tv#[!]#3
+
+discard """
+$nimsuggest --v3 --tester $file
+>def $1
+def	skModule	tv3		*/tv3.nim	1	0	""	100
+"""
diff --git a/nimsuggest/tests/tv3_outline.nim b/nimsuggest/tests/tv3_outline.nim
new file mode 100644
index 000000000..518620c87
--- /dev/null
+++ b/nimsuggest/tests/tv3_outline.nim
@@ -0,0 +1,45 @@
+# tests v3 outline
+
+type
+  Foo* = ref object of RootObj
+    bar*: string
+  FooEnum = enum value1, value2
+  FooPrivate = ref object of RootObj
+    barPrivate: string
+
+macro m(arg: untyped): untyped = discard
+template t(arg: untyped): untyped = discard
+proc p(): void = discard
+iterator i(): int = discard
+converter c(s: string): int = discard
+method m(f: Foo): void = discard
+func f(): void = discard
+
+let a = 1
+var b = 2
+const con = 2
+
+proc outer(): void =
+  proc inner() = discard
+
+proc procWithLocal(): void =
+  let local = 10
+
+discard """
+$nimsuggest --v3 --tester $file
+>outline $file
+outline	skType	tv3_outline.Foo	Foo	$file	4	2	""	100	5	16
+outline	skType	tv3_outline.FooEnum	FooEnum	$file	6	2	""	100	6	31
+outline	skEnumField	tv3_outline.FooEnum.value1	FooEnum	$file	6	17	""	100	6	23
+outline	skEnumField	tv3_outline.FooEnum.value2	FooEnum	$file	6	25	""	100	6	31
+outline	skType	tv3_outline.FooPrivate	FooPrivate	$file	7	2	""	100	8	22
+outline	skMacro	tv3_outline.m	macro (arg: untyped): untyped{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	10	6	""	100	10	40
+outline	skTemplate	tv3_outline.t	template (arg: untyped): untyped	$file	11	9	""	100	11	43
+outline	skProc	tv3_outline.p	proc (){.noSideEffect, gcsafe, raises: <inferred> [].}	$file	12	5	""	100	12	24
+outline	skConverter	tv3_outline.c	converter (s: string): int{.noSideEffect, gcsafe, raises: <inferred> [].}	$file	14	10	""	100	14	37
+outline	skFunc	tv3_outline.f	proc (){.noSideEffect, gcsafe, raises: <inferred> [].}	$file	16	5	""	100	16	24
+outline	skConst	tv3_outline.con	int literal(2)	$file	20	6	""	100	20	13
+outline	skProc	tv3_outline.outer	proc (){.noSideEffect, gcsafe, raises: <inferred> [].}	$file	22	5	""	100	23	24
+outline	skProc	tv3_outline.outer.inner	proc (){.noSideEffect, gcsafe, raises: <inferred> [].}	$file	23	7	""	100	23	24
+outline	skProc	tv3_outline.procWithLocal	proc (){.noSideEffect, gcsafe, raises: <inferred> [].}	$file	25	5	""	100	26	16
+"""
diff --git a/nimsuggest/tests/tv3_typeDefinition.nim b/nimsuggest/tests/tv3_typeDefinition.nim
new file mode 100644
index 000000000..f86d12cc6
--- /dev/null
+++ b/nimsuggest/tests/tv3_typeDefinition.nim
@@ -0,0 +1,32 @@
+# tests v3
+
+type
+  Foo* = ref object of RootObj
+    bar*: string
+
+proc test(ff: Foo) =
+  echo f#[!]#f.bar
+
+type
+  Fo#[!]#o2* = ref object of RootObj
+
+type
+  FooGeneric[T] = ref object of RootObj
+    bar*: T
+
+let fooGeneric = FooGeneric[string]()
+echo fo#[!]#oGeneric.bar
+
+# bad type
+echo unde#[!]#fined
+
+discard """
+$nimsuggest --v3 --tester $file
+>type $1
+type	skType	tv3_typeDefinition.Foo	Foo	$file	4	2	""	100
+>type $2
+type	skType	tv3_typeDefinition.Foo2	Foo2	$file	11	2	""	100
+>type $3
+type	skType	tv3_typeDefinition.FooGeneric	FooGeneric	$file	14	2	""	100
+>type $4
+"""
diff --git a/nimsuggest/tests/twithin_macro.nim b/nimsuggest/tests/twithin_macro.nim
index 9c36ffd0f..98d58381f 100644
--- a/nimsuggest/tests/twithin_macro.nim
+++ b/nimsuggest/tests/twithin_macro.nim
@@ -1,166 +1,5 @@
-
-import macros
-
-macro class*(head, body: untyped): untyped =
-  # The macro is immediate, since all its parameters are untyped.
-  # This means, it doesn't resolve identifiers passed to it.
-
-  var typeName, baseName: NimNode
-
-  # flag if object should be exported
-  var exported: bool
-
-  if head.kind == nnkInfix and head[0].ident == !"of":
-    # `head` is expression `typeName of baseClass`
-    # echo head.treeRepr
-    # --------------------
-    # Infix
-    #   Ident !"of"
-    #   Ident !"Animal"
-    #   Ident !"RootObj"
-    typeName = head[1]
-    baseName = head[2]
-
-  elif head.kind == nnkInfix and head[0].ident == !"*" and
-       head[2].kind == nnkPrefix and head[2][0].ident == !"of":
-    # `head` is expression `typeName* of baseClass`
-    # echo head.treeRepr
-    # --------------------
-    # Infix
-    #   Ident !"*"
-    #   Ident !"Animal"
-    #   Prefix
-    #     Ident !"of"
-    #     Ident !"RootObj"
-    typeName = head[1]
-    baseName = head[2][1]
-    exported = true
-
-  else:
-    quit "Invalid node: " & head.lispRepr
-
-  # The following prints out the AST structure:
-  #
-  # import macros
-  # dumptree:
-  #   type X = ref object of Y
-  #     z: int
-  # --------------------
-  # StmtList
-  #   TypeSection
-  #     TypeDef
-  #       Ident !"X"
-  #       Empty
-  #       RefTy
-  #         ObjectTy
-  #           Empty
-  #           OfInherit
-  #             Ident !"Y"
-  #           RecList
-  #             IdentDefs
-  #               Ident !"z"
-  #               Ident !"int"
-  #               Empty
-
-  # create a type section in the result
-  result =
-    if exported:
-      # mark `typeName` with an asterisk
-      quote do:
-        type `typeName`* = ref object of `baseName`
-    else:
-      quote do:
-        type `typeName` = ref object of `baseName`
-
-  # echo treeRepr(body)
-  # --------------------
-  # StmtList
-  #   VarSection
-  #     IdentDefs
-  #       Ident !"name"
-  #       Ident !"string"
-  #       Empty
-  #     IdentDefs
-  #       Ident !"age"
-  #       Ident !"int"
-  #       Empty
-  #   MethodDef
-  #     Ident !"vocalize"
-  #     Empty
-  #     Empty
-  #     FormalParams
-  #       Ident !"string"
-  #     Empty
-  #     Empty
-  #     StmtList
-  #       StrLit ...
-  #   MethodDef
-  #     Ident !"age_human_yrs"
-  #     Empty
-  #     Empty
-  #     FormalParams
-  #       Ident !"int"
-  #     Empty
-  #     Empty
-  #     StmtList
-  #       DotExpr
-  #         Ident !"this"
-  #         Ident !"age"
-
-  # var declarations will be turned into object fields
-  var recList = newNimNode(nnkRecList)
-
-  # expected name of constructor
-  let ctorName = newIdentNode("new" & $typeName)
-
-  # Iterate over the statements, adding `this: T`
-  # to the parameters of functions, unless the
-  # function is a constructor
-  for node in body.children:
-    case node.kind:
-
-      of nnkMethodDef, nnkProcDef:
-        # check if it is the ctor proc
-        if node.name.kind != nnkAccQuoted and node.name.basename == ctorName:
-          # specify the return type of the ctor proc
-          node.params[0] = typeName
-        else:
-          # inject `self: T` into the arguments
-          node.params.insert(1, newIdentDefs(ident("self"), typeName))
-        result.add(node)
-
-      of nnkVarSection:
-        # variables get turned into fields of the type.
-        for n in node.children:
-          recList.add(n)
-
-      else:
-        result.add(node)
-
-  # Inspect the tree structure:
-  #
-  # echo result.treeRepr
-  # --------------------
-  # StmtList
-  #   TypeSection
-  #     TypeDef
-  #       Ident !"Animal"
-  #       Empty
-  #       RefTy
-  #         ObjectTy
-  #           Empty
-  #           OfInherit
-  #             Ident !"RootObj"
-  #           Empty   <= We want to replace this
-  # MethodDef
-  # ...
-
-  result[0][0][2][0][2] = recList
-
-  # Lets inspect the human-readable version of the output
-  #echo repr(result)
-
-# ---
+from system import string, int, seq, `&`, `$`, `*`, `@`, echo, add, items, RootObj
+import fixtures/mclass_macro
 
 class Animal of RootObj:
   var name: string
@@ -202,13 +41,11 @@ echo r.age_human_yrs()
 echo r
 
 discard """
-disabled:true
-$nimsuggest --tester $file
+$nimsuggest --tester --maxresults:5 $file
 >sug $1
-sug;;skField;;age;;int;;$file;;167;;6;;"";;100;;None
-sug;;skField;;name;;string;;$file;;166;;6;;"";;100;;None
-sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100;;None
-sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string;;$file;;168;;9;;"";;100;;None
-sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;184;;9;;"";;100;;None
-sug;;skMacro;;twithin_macro.class;;proc (head: untyped, body: untyped): untyped{.gcsafe, locks: <unknown>.};;$file;;4;;6;;"";;50;;None*
+sug;;skField;;age;;int;;$file;;6;;6;;"";;100;;None
+sug;;skField;;name;;string;;$file;;5;;6;;"";;100;;None
+sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int{.raises: <inferred> [].};;$file;;8;;9;;"";;100;;None
+sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string{.raises: <inferred> [].};;$file;;7;;9;;"";;100;;None
+sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;23;;9;;"";;100;;None
 """
diff --git a/nimsuggest/tests/twithin_macro_prefix.nim b/nimsuggest/tests/twithin_macro_prefix.nim
index 1402b762a..e89c8b942 100644
--- a/nimsuggest/tests/twithin_macro_prefix.nim
+++ b/nimsuggest/tests/twithin_macro_prefix.nim
@@ -1,166 +1,5 @@
-
-import macros
-
-macro class*(head, body: untyped): untyped =
-  # The macro is immediate, since all its parameters are untyped.
-  # This means, it doesn't resolve identifiers passed to it.
-
-  var typeName, baseName: NimNode
-
-  # flag if object should be exported
-  var exported: bool
-
-  if head.kind == nnkInfix and head[0].ident == !"of":
-    # `head` is expression `typeName of baseClass`
-    # echo head.treeRepr
-    # --------------------
-    # Infix
-    #   Ident !"of"
-    #   Ident !"Animal"
-    #   Ident !"RootObj"
-    typeName = head[1]
-    baseName = head[2]
-
-  elif head.kind == nnkInfix and head[0].ident == !"*" and
-       head[2].kind == nnkPrefix and head[2][0].ident == !"of":
-    # `head` is expression `typeName* of baseClass`
-    # echo head.treeRepr
-    # --------------------
-    # Infix
-    #   Ident !"*"
-    #   Ident !"Animal"
-    #   Prefix
-    #     Ident !"of"
-    #     Ident !"RootObj"
-    typeName = head[1]
-    baseName = head[2][1]
-    exported = true
-
-  else:
-    quit "Invalid node: " & head.lispRepr
-
-  # The following prints out the AST structure:
-  #
-  # import macros
-  # dumptree:
-  #   type X = ref object of Y
-  #     z: int
-  # --------------------
-  # StmtList
-  #   TypeSection
-  #     TypeDef
-  #       Ident !"X"
-  #       Empty
-  #       RefTy
-  #         ObjectTy
-  #           Empty
-  #           OfInherit
-  #             Ident !"Y"
-  #           RecList
-  #             IdentDefs
-  #               Ident !"z"
-  #               Ident !"int"
-  #               Empty
-
-  # create a type section in the result
-  result =
-    if exported:
-      # mark `typeName` with an asterisk
-      quote do:
-        type `typeName`* = ref object of `baseName`
-    else:
-      quote do:
-        type `typeName` = ref object of `baseName`
-
-  # echo treeRepr(body)
-  # --------------------
-  # StmtList
-  #   VarSection
-  #     IdentDefs
-  #       Ident !"name"
-  #       Ident !"string"
-  #       Empty
-  #     IdentDefs
-  #       Ident !"age"
-  #       Ident !"int"
-  #       Empty
-  #   MethodDef
-  #     Ident !"vocalize"
-  #     Empty
-  #     Empty
-  #     FormalParams
-  #       Ident !"string"
-  #     Empty
-  #     Empty
-  #     StmtList
-  #       StrLit ...
-  #   MethodDef
-  #     Ident !"age_human_yrs"
-  #     Empty
-  #     Empty
-  #     FormalParams
-  #       Ident !"int"
-  #     Empty
-  #     Empty
-  #     StmtList
-  #       DotExpr
-  #         Ident !"this"
-  #         Ident !"age"
-
-  # var declarations will be turned into object fields
-  var recList = newNimNode(nnkRecList)
-
-  # expected name of constructor
-  let ctorName = newIdentNode("new" & $typeName)
-
-  # Iterate over the statements, adding `this: T`
-  # to the parameters of functions, unless the
-  # function is a constructor
-  for node in body.children:
-    case node.kind:
-
-      of nnkMethodDef, nnkProcDef:
-        # check if it is the ctor proc
-        if node.name.kind != nnkAccQuoted and node.name.basename == ctorName:
-          # specify the return type of the ctor proc
-          node.params[0] = typeName
-        else:
-          # inject `self: T` into the arguments
-          node.params.insert(1, newIdentDefs(ident("self"), typeName))
-        result.add(node)
-
-      of nnkVarSection:
-        # variables get turned into fields of the type.
-        for n in node.children:
-          recList.add(n)
-
-      else:
-        result.add(node)
-
-  # Inspect the tree structure:
-  #
-  # echo result.treeRepr
-  # --------------------
-  # StmtList
-  #   TypeSection
-  #     TypeDef
-  #       Ident !"Animal"
-  #       Empty
-  #       RefTy
-  #         ObjectTy
-  #           Empty
-  #           OfInherit
-  #             Ident !"RootObj"
-  #           Empty   <= We want to replace this
-  # MethodDef
-  # ...
-
-  result[0][0][2][0][2] = recList
-
-  # Lets inspect the human-readable version of the output
-  #echo repr(result)
-
-# ---
+from system import string, int, seq, `&`, `$`, `*`, `@`, echo, add, RootObj
+import fixtures/mclass_macro
 
 class Animal of RootObj:
   var name: string
@@ -202,9 +41,8 @@ echo r.age_human_yrs()
 echo r
 
 discard """
-disabled:true
 $nimsuggest --tester $file
 >sug $1
-sug;;skField;;age;;int;;$file;;167;;6;;"";;100;;Prefix
-sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100;;Prefix
+sug;;skField;;age;;int;;$file;;6;;6;;"";;100;;Prefix
+sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int{.raises: <inferred> [].};;$file;;8;;9;;"";;100;;Prefix
 """