rewrite suggest.nim for suggestionResultHook

This commit is contained in:
Simon Hafner
2015-04-22 06:10:47 +05:00
parent 49b953f318
commit 518db9eb7e

View File

@@ -20,52 +20,119 @@ const
sectionContext = "con"
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 origModuleName(m: PSym): string = m.name.s
proc symToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string =
result = section
result.add(sep)
proc parseSection(s: string): Section =
case s:
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 s.kind in routineKinds:
result.add renderTree(s.ast, {renderNoBody, renderNoComments,
renderDocComments, renderNoPragmas})
result.symkind = parseSymKind(renderTree(s.ast, {renderNoBody, renderNoComments,
renderDocComments, renderNoPragmas}))
else:
result.add s.name.s
result.add(sep)
result.add(toFullPath(li))
result.add(sep)
result.add($toLinenumber(li))
result.add(sep)
result.add($toColumn(li))
result.symkind = parseSymKind(s.name.s)
result.filePath = toFullPath(li)
result.line = toLinenumber(li)
result.column = toColumn(li)
else:
result.add($s.kind)
result.add(sep)
result.symkind = s.kind
result.qualifiedPath = @[]
if not isLocal and s.kind != skModule:
let ow = s.owner
if ow.kind != skModule and ow.owner != nil:
let ow2 = ow.owner
result.add(ow2.origModuleName)
result.add('.')
result.add(ow.origModuleName)
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)
result.qualifiedPath.add(ow2.origModuleName)
result.qualifiedPath.add(ow.origModuleName)
result.qualifiedPath.add(s.name.s)
proc symToStr(s: PSym, isLocal: bool, section: string): string =
result = symToStr(s, isLocal, section, s.info)
if s.typ != nil:
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.} =
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) =
if filterSym(s) and fieldVisible(c, s):
suggestWriteln(symToStr(s, isLocal=true, sectionSuggest))
suggestResult(symToSuggest(s, isLocal=true, sectionSuggest))
inc outputs
template wholeSymTab(cond, section: expr) {.immediate.} =
@@ -97,7 +164,7 @@ template wholeSymTab(cond, section: expr) {.immediate.} =
for item in entries:
let it {.inject.} = item
if cond:
suggestWriteln(symToStr(it, isLocal = isLocal, section))
suggestResult(symToSuggest(it, isLocal = isLocal, section))
inc outputs
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
for it in items(scope.symbols):
if filterSym(it):
suggestWriteln(symToStr(it, isLocal = isLocal, sectionSuggest))
suggestResult(symToSuggest(it, isLocal = isLocal, sectionSuggest))
inc outputs
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:
for it in items(c.topLevelScope.symbols):
if filterSym(it):
suggestWriteln(symToStr(it, isLocal=false, sectionSuggest))
suggestResult(symToSuggest(it, isLocal=false, sectionSuggest))
inc outputs
else:
for it in items(n.sym.tab):
if filterSym(it):
suggestWriteln(symToStr(it, isLocal=false, sectionSuggest))
suggestResult(symToSuggest(it, isLocal=false, sectionSuggest))
inc outputs
else:
# fallback:
@@ -263,16 +330,16 @@ var
proc findUsages(info: TLineInfo; s: PSym) =
if usageSym == nil and isTracked(info, s.name.s.len):
usageSym = s
suggestWriteln(symToStr(s, isLocal=false, sectionUsage))
suggestResult(symToSuggest(s, isLocal=false, sectionUsage))
elif s == usageSym:
if lastLineInfo != info:
suggestWriteln(symToStr(s, isLocal=false, sectionUsage, info))
suggestResult(symToSuggest(s, isLocal=false, sectionUsage, info))
lastLineInfo = info
proc findDefinition(info: TLineInfo; s: PSym) =
if s.isNil: return
if isTracked(info, s.name.s.len):
suggestWriteln(symToStr(s, isLocal=false, sectionDef))
suggestResult(symToSuggest(s, isLocal=false, sectionDef))
suggestQuit()
proc ensureIdx[T](x: var T, y: int) =