Skip to content

Commit

Permalink
Only suggest symbols that could be pragmas when typing a pragma (nim-…
Browse files Browse the repository at this point in the history
…lang#23040)

Currently pragmas just fall through to `suggestSentinel` and show
everything which isn't very useful. Now it filters for symbols that
could be pragmas (templates with `{.pragma.}`, macros, user pragmas) and
only shows them
  • Loading branch information
ire4ever1190 authored Dec 7, 2023
1 parent 4fdc6c4 commit 0a70944
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 3 deletions.
5 changes: 5 additions & 0 deletions compiler/pragmas.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import
wordrecg, ropes, options, extccomp, magicsys, trees,
types, lookups, lineinfos, pathutils, linter, modulepaths

from sigmatch import trySuggestPragmas

import std/[os, math, strutils]

when defined(nimPreviewSlimSystem):
Expand Down Expand Up @@ -119,6 +121,7 @@ const

proc invalidPragma*(c: PContext; n: PNode) =
localError(c.config, n.info, "invalid pragma: " & renderTree(n, {renderNoComments}))

proc illegalCustomPragma*(c: PContext, n: PNode, s: PSym) =
var msg = "cannot attach a custom pragma to '" & s.name.s & "'"
if s != nil:
Expand Down Expand Up @@ -790,6 +793,8 @@ proc semCustomPragma(c: PContext, n: PNode, sym: PSym): PNode =
invalidPragma(c, n)
return n

trySuggestPragmas(c, callNode[0])

let r = c.semOverloadedCall(c, callNode, n, {skTemplate}, {efNoUndeclared})
if r.isNil or sfCustomPragma notin r[0].sym.flags:
invalidPragma(c, n)
Expand Down
4 changes: 4 additions & 0 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@ proc semVarMacroPragma(c: PContext, a: PNode, n: PNode): PNode =
let it = pragmas[i]
let key = if it.kind in nkPragmaCallKinds and it.len >= 1: it[0] else: it

trySuggestPragmas(c, key)

if isPossibleMacroPragma(c, it, key):
# we transform ``var p {.m, rest.}`` into ``m(do: var p {.rest.})`` and
# let the semantic checker deal with it:
Expand Down Expand Up @@ -1741,6 +1743,8 @@ proc semProcAnnotation(c: PContext, prc: PNode;
let it = n[i]
let key = if it.kind in nkPragmaCallKinds and it.len >= 1: it[0] else: it

trySuggestPragmas(c, key)

if isPossibleMacroPragma(c, it, key):
# we transform ``proc p {.m, rest.}`` into ``m(do: proc p {.rest.})`` and
# let the semantic checker deal with it:
Expand Down
2 changes: 1 addition & 1 deletion compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1741,10 +1741,10 @@ proc applyTypeSectionPragmas(c: PContext; pragmas, operand: PNode): PNode =
result = nil
for p in pragmas:
let key = if p.kind in nkPragmaCallKinds and p.len >= 1: p[0] else: p

if p.kind == nkEmpty or whichPragma(p) != wInvalid:
discard "builtin pragma"
else:
trySuggestPragmas(c, key)
let ident = considerQuotedIdent(c, key)
if strTableGet(c.userPragmas, ident) != nil:
discard "User-defined pragma"
Expand Down
37 changes: 35 additions & 2 deletions compiler/suggest.nim
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ proc symToSuggest*(g: ModuleGraph; s: PSym, isLocal: bool, section: IdeCmd, info
inTypeContext: bool; scope: int;
useSuppliedInfo = false,
endLine: uint16 = 0,
endCol = 0): Suggest =
endCol = 0, extractDocs = true): Suggest =
new(result)
result.section = section
result.quality = quality
Expand Down Expand Up @@ -165,7 +165,8 @@ proc symToSuggest*(g: ModuleGraph; s: PSym, isLocal: bool, section: IdeCmd, info
else:
result.forth = ""
when defined(nimsuggest) and not defined(noDocgen) and not defined(leanCompiler):
result.doc = extractDocComment(g, s)
if extractDocs:
result.doc = extractDocComment(g, s)
if s.kind == skModule and s.ast.len != 0 and section != ideHighlight:
result.filePath = toFullPath(g.config, s.ast[0].info)
result.line = 1
Expand Down Expand Up @@ -746,6 +747,38 @@ proc suggestEnum*(c: PContext; n: PNode; t: PType) =
produceOutput(outputs, c.config)
if outputs.len > 0: suggestQuit()

proc suggestPragmas*(c: PContext, n: PNode) =
## Suggests anything that might be a pragma
## - template that has {.pragma.}
## - macros
## - user pragmas
let info = n.info
var outputs: Suggestions = @[]
# First filter for template/macros
wholeSymTab(filterSym(it, n, pm) and
(sfCustomPragma in it.flags or it.kind == skMacro),
ideSug)

# Now show suggestions for user pragmas
for pragma in c.userPragmas:
var pm = default(PrefixMatch)
if filterSym(pragma, n, pm):
outputs &= symToSuggest(c.graph, pragma, isLocal=true, ideSug, info,
pragma.getQuality, pm, c.inTypeContext > 0, 0,
extractDocs=false)

produceOutput(outputs, c.config)
if outputs.len > 0:
suggestQuit()

template trySuggestPragmas*(c: PContext, n: PNode) =
## Runs [suggestPragmas] when compiling nimsuggest and
## we are querying the node
when defined(nimsuggest):
let tmp = n
if c.config.ideCmd == ideSug and exactEquals(c.config.m.trackPos, tmp.info):
suggestPragmas(c, tmp)

proc suggestSentinel*(c: PContext) =
if c.config.ideCmd != ideSug or c.module.position != c.config.m.trackPos.fileIndex.int32: return
if c.compilesContextId > 0: return
Expand Down
40 changes: 40 additions & 0 deletions nimsuggest/tests/tsug_pragmas.nim
Original file line number Diff line number Diff line change
@@ -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.};;$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.};;$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.};;$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.};;$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.};;$file;;3;;6;;"";;50;;Prefix
"""


0 comments on commit 0a70944

Please sign in to comment.