use IC for nimsuggest; wip

This commit is contained in:
Araq
2026-06-16 00:36:01 +02:00
parent f5d9e7a207
commit 9cfba6c0fb
18 changed files with 350 additions and 80 deletions

View File

@@ -35,7 +35,7 @@ import strutils, os, parseopt, parseutils, sequtils, net, rdstdin, sexp
# suggestionResultHook, because suggest.nim is included by sigmatch.
# So we import that one instead.
import compiler / [options, commands, modules,
passes, passaux, msgs,
passes, passaux, msgs, pipelines,
sigmatch, ast,
idents, modulegraphs, prefixmatches, lineinfos, cmdlinehelper,
pathutils, condsyms, syntaxes, suggestsymdb]
@@ -261,6 +261,14 @@ proc executeNoHooks(cmd: IdeCmd, file, dirtyfile: AbsoluteFile, line, col: int,
var isKnownFile = true
let dirtyIdx = fileInfoIdx(conf, file, isKnownFile)
# Cold-opened include file: nothing has been compiled/loaded yet, so its
# includer is unknown. Scan the nimcache NIFs for the module that `include`s
# this exact file and register that one edge; `parentModule(dirtyIdx)` then
# resolves to the includer, which we (re)compile below.
if conf.ideImportsFromNif and graph.needsIncludeScan(dirtyIdx):
discard graph.registerIncluderFromNif(dirtyIdx)
let isInclude = graph.inclToMod.hasKey(dirtyIdx)
if not dirtyfile.isEmpty: msgs.setDirtyFile(conf, dirtyIdx, dirtyfile)
else: msgs.setDirtyFile(conf, dirtyIdx, AbsoluteFile"")
@@ -269,9 +277,9 @@ proc executeNoHooks(cmd: IdeCmd, file, dirtyfile: AbsoluteFile, line, col: int,
conf.errorCounter = 0
if conf.suggestVersion == 1:
graph.usageSym = nil
if not isKnownFile:
if not isKnownFile and not isInclude:
graph.clearInstCache(dirtyIdx)
graph.compileProject(dirtyIdx)
graph.compilePipelineProject(dirtyIdx)
if conf.suggestVersion == 0 and conf.ideCmd in {ideUse, ideDus} and
dirtyfile.isEmpty:
discard "no need to recompile anything"
@@ -280,9 +288,11 @@ proc executeNoHooks(cmd: IdeCmd, file, dirtyfile: AbsoluteFile, line, col: int,
graph.markDirty dirtyIdx
graph.markClientsDirty dirtyIdx
if conf.ideCmd != ideMod:
if isKnownFile:
# `isInclude`: a freshly discovered include file is not "known" yet, but we
# still must (source-)compile its includer to serve the query.
if isKnownFile or isInclude:
graph.clearInstCache(modIdx)
graph.compileProject(modIdx)
graph.compilePipelineProject(modIdx)
if conf.ideCmd in {ideUse, ideDus}:
let u = if conf.suggestVersion != 1: graph.symFromInfo(conf.m.trackPos) else: graph.usageSym
if u != nil:
@@ -577,7 +587,7 @@ proc recompileFullProject(graph: ModuleGraph) =
graph.vm = nil
graph.resetAllModules()
GC_fullCollect()
graph.compileProject()
graph.compilePipelineProject()
proc mainThread(graph: ModuleGraph) =
let conf = graph.config
@@ -621,10 +631,14 @@ var
proc mainCommand(graph: ModuleGraph) =
let conf = graph.config
clearPasses(graph)
registerPass graph, verbosePass
registerPass graph, semPass
conf.setCmd cmdIdeTools
# Use the pipeline driver (same as `nim check`): it is where IC/NIF loading
# and emission live. The legacy `passes.compileProject` path has no NIF support.
setPipeLinePass(graph, SemPass)
# cmdM loads the unchanged import closure from precompiled NIF; cmdCheck
# recompiles everything from source. `ideActive` keeps suggestion collection
# and error-resilience regardless of which mode we run under.
conf.setCmd(if conf.ideImportsFromNif: cmdM else: cmdCheck)
conf.ideActive = true
defineSymbol(conf.symbols, $conf.backend)
wantMainModule(conf)
@@ -646,7 +660,7 @@ proc mainCommand(graph: ModuleGraph) =
# compile the project before showing any input so that we already
# can answer questions right away:
benchmark "Initial compilation":
compileProject(graph)
compilePipelineProject(graph)
open(requests)
open(results)
@@ -798,7 +812,7 @@ proc recompilePartially(graph: ModuleGraph, projectFileIdx = InvalidFileIdx) =
try:
benchmark "Recompilation":
graph.compileProject(projectFileIdx)
graph.compilePipelineProject(projectFileIdx)
except Exception as e:
myLog fmt "Failed to recompile partially with the following error:\n {e.msg} \n\n {e.getStackTrace()}"
try:
@@ -1311,11 +1325,10 @@ else:
proc mockCommand(graph: ModuleGraph) =
retval = graph
let conf = graph.config
conf.setCmd cmdIdeTools
conf.setCmd(if conf.ideImportsFromNif: cmdM else: cmdCheck)
conf.ideActive = true
defineSymbol(conf.symbols, $conf.backend)
clearPasses(graph)
registerPass graph, verbosePass
registerPass graph, semPass
setPipeLinePass(graph, SemPass)
wantMainModule(conf)
@@ -1331,7 +1344,7 @@ else:
# compile the project before showing any input so that we already
# can answer questions right away:
compileProject(graph)
compilePipelineProject(graph)
proc mockCmdLine(pass: TCmdLinePass, cmd: string; conf: ConfigRef) =