mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
Only suggest symbols that could be pragmas when typing a pragma (#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
This commit is contained in:
@@ -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):
|
||||
@@ -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:
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
40
nimsuggest/tests/tsug_pragmas.nim
Normal file
40
nimsuggest/tests/tsug_pragmas.nim
Normal file
@@ -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
|
||||
"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user