first implementation of suggest
This commit is contained in:
parent
5c7e3efbc3
commit
f7b2d71790
12 changed files with 54 additions and 25 deletions
|
|
@ -32,5 +32,7 @@ else:
|
||||||
|
|
||||||
# initialization:
|
# initialization:
|
||||||
# disable auto-complete:
|
# disable auto-complete:
|
||||||
discard readline.bind_key('\t'.ord, readline.abort)
|
proc doNothing(a, b: cint): cint {.cdecl, procvar.} = nil
|
||||||
|
|
||||||
|
discard readline.bind_key('\t'.ord, doNothing)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -677,7 +677,18 @@ proc OpenScope(tab: var TSymTab) =
|
||||||
Inc(tab.tos)
|
Inc(tab.tos)
|
||||||
|
|
||||||
proc RawCloseScope(tab: var TSymTab) =
|
proc RawCloseScope(tab: var TSymTab) =
|
||||||
Dec(tab.tos) #tab.stack[tab.tos] := nil;
|
Dec(tab.tos)
|
||||||
|
|
||||||
|
iterator items*(tab: TStrTable): PSym =
|
||||||
|
var it: TTabIter
|
||||||
|
var s = InitTabIter(it, tab)
|
||||||
|
while s != nil:
|
||||||
|
yield s
|
||||||
|
s = NextIter(it, tab)
|
||||||
|
|
||||||
|
iterator items*(tab: TSymTab): PSym =
|
||||||
|
for i in countdown(tab.tos-1, 0):
|
||||||
|
for it in items(tab.stack[i]): yield it
|
||||||
|
|
||||||
proc hasEmptySlot(data: TIdPairSeq): bool =
|
proc hasEmptySlot(data: TIdPairSeq): bool =
|
||||||
for h in countup(0, high(data)):
|
for h in countup(0, high(data)):
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists,
|
os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists,
|
||||||
wordrecg
|
wordrecg, parseutils
|
||||||
|
|
||||||
proc writeCommandLineUsage*()
|
proc writeCommandLineUsage*()
|
||||||
|
|
||||||
|
|
@ -78,7 +78,8 @@ Advanced commands:
|
||||||
module dependency graph
|
module dependency graph
|
||||||
listDef list all defined conditionals and exit
|
listDef list all defined conditionals and exit
|
||||||
check checks the project for syntax and semantic
|
check checks the project for syntax and semantic
|
||||||
parse parses a single file (for debugging Nimrod)
|
suggest list all possible symbols at position;
|
||||||
|
use with --track option
|
||||||
Advanced options:
|
Advanced options:
|
||||||
-w, --warnings:on|off turn all warnings on|off
|
-w, --warnings:on|off turn all warnings on|off
|
||||||
--warning[X]:on|off turn specific warning X on|off
|
--warning[X]:on|off turn specific warning X on|off
|
||||||
|
|
@ -105,6 +106,7 @@ Advanced options:
|
||||||
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
||||||
--index:FILE use FILE to generate a documenation index file
|
--index:FILE use FILE to generate a documenation index file
|
||||||
--putenv:key=value set an environment variable
|
--putenv:key=value set an environment variable
|
||||||
|
--track:FILE,LINE,COLUMN track a file position for 'suggest'
|
||||||
--listCmd list the commands used to execute external programs
|
--listCmd list the commands used to execute external programs
|
||||||
--parallelBuild=0|1|... perform a parallel build
|
--parallelBuild=0|1|... perform a parallel build
|
||||||
value = number of processors (0 for auto-detect)
|
value = number of processors (0 for auto-detect)
|
||||||
|
|
@ -289,6 +291,16 @@ proc addPathRec(dir: string, info: TLineInfo) =
|
||||||
Message(info, hintPath, p)
|
Message(info, hintPath, p)
|
||||||
lists.PrependStr(options.searchPaths, p)
|
lists.PrependStr(options.searchPaths, p)
|
||||||
|
|
||||||
|
proc track(arg: string, info: TLineInfo) =
|
||||||
|
var a = arg.split(',')
|
||||||
|
if a.len != 3: LocalError(info, errTokenExpected, "FILE,LINE,COLMUN")
|
||||||
|
var line, column: int
|
||||||
|
if parseUtils.parseInt(a[1], line) <= 0:
|
||||||
|
LocalError(info, errInvalidNumber, a[1])
|
||||||
|
if parseUtils.parseInt(a[2], column) <= 0:
|
||||||
|
LocalError(info, errInvalidNumber, a[2])
|
||||||
|
msgs.addCheckpoint(newLineInfo(a[0], line, column))
|
||||||
|
|
||||||
proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||||
var
|
var
|
||||||
theOS: TSystemOS
|
theOS: TSystemOS
|
||||||
|
|
@ -481,6 +493,9 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||||
of wCC:
|
of wCC:
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
setCC(arg)
|
setCC(arg)
|
||||||
|
of wTrack:
|
||||||
|
expectArg(switch, arg, pass, info)
|
||||||
|
track(arg, info)
|
||||||
else:
|
else:
|
||||||
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
|
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
|
||||||
else: InvalidCmdLineOption(pass, switch, info)
|
else: InvalidCmdLineOption(pass, switch, info)
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,11 @@ proc CommandScan(filename: string) =
|
||||||
else:
|
else:
|
||||||
rawMessage(errCannotOpenFile, f)
|
rawMessage(errCannotOpenFile, f)
|
||||||
|
|
||||||
|
proc CommandSuggest(filename: string) =
|
||||||
|
msgs.gErrorMax = high(int) # do not stop after first error
|
||||||
|
semanticPasses()
|
||||||
|
compileProject(filename)
|
||||||
|
|
||||||
proc WantFile(filename: string) =
|
proc WantFile(filename: string) =
|
||||||
if filename == "":
|
if filename == "":
|
||||||
Fatal(newLineInfo("command line", 1, 1), errCommandExpectsFilename)
|
Fatal(newLineInfo("command line", 1, 1), errCommandExpectsFilename)
|
||||||
|
|
@ -265,5 +270,9 @@ proc MainCommand(cmd, filename: string) =
|
||||||
of wI:
|
of wI:
|
||||||
gCmd = cmdInteractive
|
gCmd = cmdInteractive
|
||||||
CommandInteractive()
|
CommandInteractive()
|
||||||
|
of wSuggest:
|
||||||
|
gCmd = cmdSuggest
|
||||||
|
wantFile(filename)
|
||||||
|
CommandSuggest(filename)
|
||||||
else: rawMessage(errInvalidCommandX, cmd)
|
else: rawMessage(errInvalidCommandX, cmd)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -430,11 +430,6 @@ proc ToLinenumber*(info: TLineInfo): int =
|
||||||
proc toColumn*(info: TLineInfo): int =
|
proc toColumn*(info: TLineInfo): int =
|
||||||
result = info.col
|
result = info.col
|
||||||
|
|
||||||
proc checkpoint*(info: TLineInfo, filename: string, line: int): bool =
|
|
||||||
result = (int(info.line) == line) and
|
|
||||||
(ChangeFileExt(extractFilename(filenames[info.fileIndex]), "") ==
|
|
||||||
filename)
|
|
||||||
|
|
||||||
var checkPoints: seq[TLineInfo] = @[]
|
var checkPoints: seq[TLineInfo] = @[]
|
||||||
|
|
||||||
proc addCheckpoint*(info: TLineInfo) =
|
proc addCheckpoint*(info: TLineInfo) =
|
||||||
|
|
@ -461,13 +456,9 @@ proc getMessageStr(msg: TMsgKind, arg: string): string =
|
||||||
proc inCheckpoint*(current: TLineInfo): bool =
|
proc inCheckpoint*(current: TLineInfo): bool =
|
||||||
## prints the line information if in checkpoint
|
## prints the line information if in checkpoint
|
||||||
result = false
|
result = false
|
||||||
if not (optCheckpoints in gOptions):
|
|
||||||
return # ignore all checkpoints
|
|
||||||
for i in countup(0, high(checkPoints)):
|
for i in countup(0, high(checkPoints)):
|
||||||
if (current.line == checkPoints[i].line) and
|
if (current.line == checkPoints[i].line) and
|
||||||
(current.fileIndex == (checkPoints[i].fileIndex)):
|
(current.fileIndex == (checkPoints[i].fileIndex)):
|
||||||
MessageOut(`%`("$1($2, $3) Checkpoint: ", [toFilename(current),
|
|
||||||
coordToStr(current.line), coordToStr(current.col)]))
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ type # please make sure we have under 32 options
|
||||||
cmdGenDepend, cmdListDef, cmdCheck, # semantic checking for whole project
|
cmdGenDepend, cmdListDef, cmdCheck, # semantic checking for whole project
|
||||||
cmdParse, # parse a single file (for debugging)
|
cmdParse, # parse a single file (for debugging)
|
||||||
cmdScan, # scan a single file (for debugging)
|
cmdScan, # scan a single file (for debugging)
|
||||||
cmdDebugTrans, # debug a transformation pass
|
cmdSuggest, # suggest feature (auto-completion for IDEs)
|
||||||
cmdRst2html, # convert a reStructuredText file to HTML
|
cmdRst2html, # convert a reStructuredText file to HTML
|
||||||
cmdRst2tex, # convert a reStructuredText file to TeX
|
cmdRst2tex, # convert a reStructuredText file to TeX
|
||||||
cmdInteractive, # start interactive session
|
cmdInteractive, # start interactive session
|
||||||
|
|
|
||||||
|
|
@ -57,15 +57,12 @@ proc SearchForProc(c: PContext, fn: PSym, tos: int): PSym =
|
||||||
result = NextIdentIter(it, c.tab.stack[tos])
|
result = NextIdentIter(it, c.tab.stack[tos])
|
||||||
|
|
||||||
proc paramsFitBorrow(a, b: PNode): bool =
|
proc paramsFitBorrow(a, b: PNode): bool =
|
||||||
var
|
var length = sonsLen(a)
|
||||||
length: int
|
|
||||||
m, n: PSym
|
|
||||||
length = sonsLen(a)
|
|
||||||
result = false
|
result = false
|
||||||
if length == sonsLen(b):
|
if length == sonsLen(b):
|
||||||
for i in countup(1, length - 1):
|
for i in countup(1, length - 1):
|
||||||
m = a.sons[i].sym
|
var m = a.sons[i].sym
|
||||||
n = b.sons[i].sym
|
var n = b.sons[i].sym
|
||||||
assert((m.kind == skParam) and (n.kind == skParam))
|
assert((m.kind == skParam) and (n.kind == skParam))
|
||||||
if not equalOrDistinctOf(m.typ, n.typ): return
|
if not equalOrDistinctOf(m.typ, n.typ): return
|
||||||
if not equalOrDistinctOf(a.sons[0].typ, b.sons[0].typ): return
|
if not equalOrDistinctOf(a.sons[0].typ, b.sons[0].typ): return
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import
|
||||||
strutils, nhashes, lists, options, scanner, ast, astalgo, trees, treetab,
|
strutils, nhashes, lists, options, scanner, ast, astalgo, trees, treetab,
|
||||||
wordrecg, ropes, msgs, os, condsyms, idents, rnimsyn, types, platform, math,
|
wordrecg, ropes, msgs, os, condsyms, idents, rnimsyn, types, platform, math,
|
||||||
magicsys, pnimsyn, nversion, nimsets, semdata, evals, semfold, importer,
|
magicsys, pnimsyn, nversion, nimsets, semdata, evals, semfold, importer,
|
||||||
procfind, lookups, rodread, pragmas, passes
|
procfind, lookups, rodread, pragmas, passes, suggest
|
||||||
|
|
||||||
proc semPass*(): TPass
|
proc semPass*(): TPass
|
||||||
# implementation
|
# implementation
|
||||||
|
|
|
||||||
|
|
@ -955,6 +955,8 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode =
|
||||||
|
|
||||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
result = n
|
result = n
|
||||||
|
if gCmd == cmdSuggest:
|
||||||
|
suggestExpr(c, n)
|
||||||
if nfSem in n.flags: return
|
if nfSem in n.flags: return
|
||||||
case n.kind # atoms:
|
case n.kind # atoms:
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
|
|
|
||||||
|
|
@ -792,6 +792,8 @@ proc SemStmt(c: PContext, n: PNode): PNode =
|
||||||
const # must be last statements in a block:
|
const # must be last statements in a block:
|
||||||
LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
|
LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
|
||||||
result = n
|
result = n
|
||||||
|
if gCmd == cmdSuggest:
|
||||||
|
suggestStmt(c, n)
|
||||||
if nfSem in n.flags: return
|
if nfSem in n.flags: return
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkAsgn: result = semAsgn(c, n)
|
of nkAsgn: result = semAsgn(c, n)
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ type
|
||||||
wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wJs, wOC,
|
wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wJs, wOC,
|
||||||
wRst2html, wRst2tex, wI,
|
wRst2html, wRst2tex, wI,
|
||||||
wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar, wEmit, wThreads,
|
wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar, wEmit, wThreads,
|
||||||
wRecursivePath
|
wRecursivePath, wSuggest, wTrack
|
||||||
|
|
||||||
TSpecialWords* = set[TSpecialWord]
|
TSpecialWords* = set[TSpecialWord]
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ const
|
||||||
"pretty", "doc", "gendepend", "listdef", "check", "parse", "scan",
|
"pretty", "doc", "gendepend", "listdef", "check", "parse", "scan",
|
||||||
"js", "oc", "rst2html", "rst2tex", "i",
|
"js", "oc", "rst2html", "rst2tex", "i",
|
||||||
"write", "putenv", "prependenv", "appendenv", "threadvar", "emit",
|
"write", "putenv", "prependenv", "appendenv", "threadvar", "emit",
|
||||||
"threads", "recursivepath"]
|
"threads", "recursivepath", "suggest", "track"]
|
||||||
|
|
||||||
proc whichKeyword*(id: PIdent): TSpecialWord
|
proc whichKeyword*(id: PIdent): TSpecialWord
|
||||||
proc whichKeyword*(id: String): TSpecialWord
|
proc whichKeyword*(id: String): TSpecialWord
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -1,5 +1,5 @@
|
||||||
- 'suggest'
|
- 'suggest' needs tweaking: more places in the semantic checking
|
||||||
- Bug: var x = 89; float(x)
|
need to take it into account
|
||||||
|
|
||||||
- thread support: threadvar on Windows seems broken;
|
- thread support: threadvar on Windows seems broken;
|
||||||
add --deadlock_prevention:on|off switch
|
add --deadlock_prevention:on|off switch
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue