rewrite suggest.nim for suggestionResultHook
This commit is contained in:
parent
49b953f318
commit
518db9eb7e
1 changed files with 108 additions and 41 deletions
|
|
@ -20,52 +20,119 @@ const
|
||||||
sectionContext = "con"
|
sectionContext = "con"
|
||||||
sectionUsage = "use"
|
sectionUsage = "use"
|
||||||
|
|
||||||
|
type
|
||||||
|
Section = enum sug, def, con, use
|
||||||
|
Suggest = object
|
||||||
|
section: Section
|
||||||
|
qualifiedPath: seq[string]
|
||||||
|
filePath: string
|
||||||
|
line: int # Starts at 1
|
||||||
|
column: int # Starts at 0
|
||||||
|
doc: string # Not escaped (yet)
|
||||||
|
symkind: TSymKind
|
||||||
|
forth: string # XXX TODO object on symkind
|
||||||
|
|
||||||
|
var
|
||||||
|
suggestionResultHook*: proc (result: Suggest) {.closure.}
|
||||||
|
|
||||||
#template sectionSuggest(): expr = "##begin\n" & getStackTrace() & "##end\n"
|
#template sectionSuggest(): expr = "##begin\n" & getStackTrace() & "##end\n"
|
||||||
|
|
||||||
template origModuleName(m: PSym): string = m.name.s
|
template origModuleName(m: PSym): string = m.name.s
|
||||||
|
|
||||||
proc symToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string =
|
proc parseSection(s: string): Section =
|
||||||
result = section
|
case s:
|
||||||
result.add(sep)
|
of "sug": result = sug
|
||||||
|
of "con": result = con
|
||||||
|
of "use": result = use
|
||||||
|
of "def": result = def
|
||||||
|
else: raise newException(ERecoverableError, "Answer type incorrect")
|
||||||
|
|
||||||
|
proc parseSymKind(s: string): TSymKind =
|
||||||
|
case s:
|
||||||
|
of "skDynLib": result = skDynLib
|
||||||
|
of "skParam": result = skParam
|
||||||
|
of "skGenericParam": result = skGenericParam
|
||||||
|
of "skTemp": result = skTemp
|
||||||
|
of "skModule": result = skModule
|
||||||
|
of "skType": result = skType
|
||||||
|
of "skVar": result = skVar
|
||||||
|
of "skLet": result = skLet
|
||||||
|
of "skConst": result = skConst
|
||||||
|
of "skResult": result = skResult
|
||||||
|
of "skProc": result = skProc
|
||||||
|
of "skMethod": result = skMethod
|
||||||
|
of "skIterator": result = skIterator
|
||||||
|
of "skClosureIterator": result = skClosureIterator
|
||||||
|
of "skConverter": result = skConverter
|
||||||
|
of "skMacro": result = skMacro
|
||||||
|
of "skTemplate": result = skTemplate
|
||||||
|
of "skField": result = skField
|
||||||
|
of "skEnumField": result = skEnumField
|
||||||
|
of "skForVar": result = skForVar
|
||||||
|
of "skLabel": result = skLabel
|
||||||
|
of "skStub": result = skStub
|
||||||
|
of "skPackage": result = skPackage
|
||||||
|
of "skAlias": result = skAlias
|
||||||
|
else: raise newException(ERecoverableError, "TSymKind not found")
|
||||||
|
|
||||||
|
proc symToSuggest(s: PSym, isLocal: bool, section: string, li: TLineInfo): Suggest =
|
||||||
|
result.section = parseSection(section)
|
||||||
if optIdeTerse in gGlobalOptions:
|
if optIdeTerse in gGlobalOptions:
|
||||||
if s.kind in routineKinds:
|
if s.kind in routineKinds:
|
||||||
result.add renderTree(s.ast, {renderNoBody, renderNoComments,
|
result.symkind = parseSymKind(renderTree(s.ast, {renderNoBody, renderNoComments,
|
||||||
renderDocComments, renderNoPragmas})
|
renderDocComments, renderNoPragmas}))
|
||||||
else:
|
else:
|
||||||
result.add s.name.s
|
result.symkind = parseSymKind(s.name.s)
|
||||||
result.add(sep)
|
result.filePath = toFullPath(li)
|
||||||
result.add(toFullPath(li))
|
result.line = toLinenumber(li)
|
||||||
result.add(sep)
|
result.column = toColumn(li)
|
||||||
result.add($toLinenumber(li))
|
|
||||||
result.add(sep)
|
|
||||||
result.add($toColumn(li))
|
|
||||||
else:
|
else:
|
||||||
result.add($s.kind)
|
result.symkind = s.kind
|
||||||
result.add(sep)
|
result.qualifiedPath = @[]
|
||||||
if not isLocal and s.kind != skModule:
|
if not isLocal and s.kind != skModule:
|
||||||
let ow = s.owner
|
let ow = s.owner
|
||||||
if ow.kind != skModule and ow.owner != nil:
|
if ow.kind != skModule and ow.owner != nil:
|
||||||
let ow2 = ow.owner
|
let ow2 = ow.owner
|
||||||
result.add(ow2.origModuleName)
|
result.qualifiedPath.add(ow2.origModuleName)
|
||||||
result.add('.')
|
result.qualifiedPath.add(ow.origModuleName)
|
||||||
result.add(ow.origModuleName)
|
result.qualifiedPath.add(s.name.s)
|
||||||
result.add('.')
|
|
||||||
result.add(s.name.s)
|
|
||||||
result.add(sep)
|
|
||||||
if s.typ != nil:
|
|
||||||
result.add(typeToString(s.typ))
|
|
||||||
result.add(sep)
|
|
||||||
result.add(toFullPath(li))
|
|
||||||
result.add(sep)
|
|
||||||
result.add($toLinenumber(li))
|
|
||||||
result.add(sep)
|
|
||||||
result.add($toColumn(li))
|
|
||||||
result.add(sep)
|
|
||||||
when not defined(noDocgen):
|
|
||||||
result.add(s.extractDocComment.escape)
|
|
||||||
|
|
||||||
proc symToStr(s: PSym, isLocal: bool, section: string): string =
|
if s.typ != nil:
|
||||||
result = symToStr(s, isLocal, section, s.info)
|
result.forth = typeToString(s.typ)
|
||||||
|
else:
|
||||||
|
result.forth = ""
|
||||||
|
result.filePath = toFullPath(li)
|
||||||
|
result.line = toLinenumber(li)
|
||||||
|
result.column = toColumn(li)
|
||||||
|
when not defined(noDocgen):
|
||||||
|
result.doc = s.extractDocComment
|
||||||
|
|
||||||
|
proc `$`(suggest: Suggest): string =
|
||||||
|
result = $suggest.section
|
||||||
|
result.add(sep)
|
||||||
|
result.add($suggest.symkind)
|
||||||
|
result.add(sep)
|
||||||
|
result.add(suggest.qualifiedPath.join("."))
|
||||||
|
result.add(sep)
|
||||||
|
result.add(suggest.forth)
|
||||||
|
result.add(sep)
|
||||||
|
result.add(suggest.filePath)
|
||||||
|
result.add(sep)
|
||||||
|
result.add($suggest.line)
|
||||||
|
result.add(sep)
|
||||||
|
result.add($suggest.column)
|
||||||
|
result.add(sep)
|
||||||
|
when not defined(noDocgen):
|
||||||
|
result.add(suggest.doc.escape)
|
||||||
|
|
||||||
|
proc symToSuggest(s: PSym, isLocal: bool, section: string): Suggest =
|
||||||
|
result = symToSuggest(s, isLocal, section, s.info)
|
||||||
|
|
||||||
|
proc suggestResult(s: Suggest) =
|
||||||
|
if not isNil(suggestionResultHook):
|
||||||
|
suggestionResultHook(s)
|
||||||
|
else:
|
||||||
|
suggestWriteln($(s))
|
||||||
|
|
||||||
proc filterSym(s: PSym): bool {.inline.} =
|
proc filterSym(s: PSym): bool {.inline.} =
|
||||||
result = s.kind != skModule
|
result = s.kind != skModule
|
||||||
|
|
@ -84,7 +151,7 @@ proc fieldVisible*(c: PContext, f: PSym): bool {.inline.} =
|
||||||
|
|
||||||
proc suggestField(c: PContext, s: PSym, outputs: var int) =
|
proc suggestField(c: PContext, s: PSym, outputs: var int) =
|
||||||
if filterSym(s) and fieldVisible(c, s):
|
if filterSym(s) and fieldVisible(c, s):
|
||||||
suggestWriteln(symToStr(s, isLocal=true, sectionSuggest))
|
suggestResult(symToSuggest(s, isLocal=true, sectionSuggest))
|
||||||
inc outputs
|
inc outputs
|
||||||
|
|
||||||
template wholeSymTab(cond, section: expr) {.immediate.} =
|
template wholeSymTab(cond, section: expr) {.immediate.} =
|
||||||
|
|
@ -97,7 +164,7 @@ template wholeSymTab(cond, section: expr) {.immediate.} =
|
||||||
for item in entries:
|
for item in entries:
|
||||||
let it {.inject.} = item
|
let it {.inject.} = item
|
||||||
if cond:
|
if cond:
|
||||||
suggestWriteln(symToStr(it, isLocal = isLocal, section))
|
suggestResult(symToSuggest(it, isLocal = isLocal, section))
|
||||||
inc outputs
|
inc outputs
|
||||||
|
|
||||||
proc suggestSymList(c: PContext, list: PNode, outputs: var int) =
|
proc suggestSymList(c: PContext, list: PNode, outputs: var int) =
|
||||||
|
|
@ -166,7 +233,7 @@ proc suggestEverything(c: PContext, n: PNode, outputs: var int) =
|
||||||
if scope == c.topLevelScope: isLocal = false
|
if scope == c.topLevelScope: isLocal = false
|
||||||
for it in items(scope.symbols):
|
for it in items(scope.symbols):
|
||||||
if filterSym(it):
|
if filterSym(it):
|
||||||
suggestWriteln(symToStr(it, isLocal = isLocal, sectionSuggest))
|
suggestResult(symToSuggest(it, isLocal = isLocal, sectionSuggest))
|
||||||
inc outputs
|
inc outputs
|
||||||
if scope == c.topLevelScope: break
|
if scope == c.topLevelScope: break
|
||||||
|
|
||||||
|
|
@ -181,12 +248,12 @@ proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) =
|
||||||
# all symbols accessible, because we are in the current module:
|
# all symbols accessible, because we are in the current module:
|
||||||
for it in items(c.topLevelScope.symbols):
|
for it in items(c.topLevelScope.symbols):
|
||||||
if filterSym(it):
|
if filterSym(it):
|
||||||
suggestWriteln(symToStr(it, isLocal=false, sectionSuggest))
|
suggestResult(symToSuggest(it, isLocal=false, sectionSuggest))
|
||||||
inc outputs
|
inc outputs
|
||||||
else:
|
else:
|
||||||
for it in items(n.sym.tab):
|
for it in items(n.sym.tab):
|
||||||
if filterSym(it):
|
if filterSym(it):
|
||||||
suggestWriteln(symToStr(it, isLocal=false, sectionSuggest))
|
suggestResult(symToSuggest(it, isLocal=false, sectionSuggest))
|
||||||
inc outputs
|
inc outputs
|
||||||
else:
|
else:
|
||||||
# fallback:
|
# fallback:
|
||||||
|
|
@ -263,16 +330,16 @@ var
|
||||||
proc findUsages(info: TLineInfo; s: PSym) =
|
proc findUsages(info: TLineInfo; s: PSym) =
|
||||||
if usageSym == nil and isTracked(info, s.name.s.len):
|
if usageSym == nil and isTracked(info, s.name.s.len):
|
||||||
usageSym = s
|
usageSym = s
|
||||||
suggestWriteln(symToStr(s, isLocal=false, sectionUsage))
|
suggestResult(symToSuggest(s, isLocal=false, sectionUsage))
|
||||||
elif s == usageSym:
|
elif s == usageSym:
|
||||||
if lastLineInfo != info:
|
if lastLineInfo != info:
|
||||||
suggestWriteln(symToStr(s, isLocal=false, sectionUsage, info))
|
suggestResult(symToSuggest(s, isLocal=false, sectionUsage, info))
|
||||||
lastLineInfo = info
|
lastLineInfo = info
|
||||||
|
|
||||||
proc findDefinition(info: TLineInfo; s: PSym) =
|
proc findDefinition(info: TLineInfo; s: PSym) =
|
||||||
if s.isNil: return
|
if s.isNil: return
|
||||||
if isTracked(info, s.name.s.len):
|
if isTracked(info, s.name.s.len):
|
||||||
suggestWriteln(symToStr(s, isLocal=false, sectionDef))
|
suggestResult(symToSuggest(s, isLocal=false, sectionDef))
|
||||||
suggestQuit()
|
suggestQuit()
|
||||||
|
|
||||||
proc ensureIdx[T](x: var T, y: int) =
|
proc ensureIdx[T](x: var T, y: int) =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue