compiler/[msgs, suggest]: improve highlighter accuracy (#10496)

Previously the compiler would generate suggestions based on the symbol
identifier length, but that might not reflect the actual representation
of it within the actual source code.

This commit implements a simple source scanner for the suggest module to
address the problem outlined above.

Fixes nim-lang/nimsuggest#24
This commit is contained in:
alaviss 2019-02-07 23:08:15 +07:00 • committed by Miran
commit 2fdf816332
4 changed files with 63 additions and 3 deletions

View file

@ -32,7 +32,7 @@
# included from sigmatch.nim
import algorithm, prefixmatches, lineinfos, pathutils
import algorithm, prefixmatches, lineinfos, pathutils, parseutils
from wordrecg import wDeprecated, wError, wAddr, wYield, specialWords
when defined(nimsuggest):
@ -81,6 +81,38 @@ proc cmpSuggestions(a, b: Suggest): int =
# independent of hashing order:
result = cmp(a.name[], b.name[])
proc getTokenLenFromSource(conf: ConfigRef; ident: string; info: TLineInfo): int =
let
line = sourceLine(conf, info)
column = toColumn(info)
proc isOpeningBacktick(col: int): bool =
if col >= 0 and col < line.len:
if line[col] == '`':
not isOpeningBacktick(col - 1)
else:
isOpeningBacktick(col - 1)
else:
false
if column > line.len:
result = 0
elif column > 0 and line[column - 1] == '`' and isOpeningBacktick(column - 1):
result = skipUntil(line, '`', column)
if cmpIgnoreStyle(line[column..column + result - 1], ident) != 0:
result = 0
elif ident[0] in linter.Letters and ident[^1] != '=':
result = identLen(line, column)
if cmpIgnoreStyle(line[column..column + result - 1], ident) != 0:
result = 0
else:
result = skipWhile(line, OpChars + {'[', '(', '{', ']', ')', '}'}, column)
if ident[^1] == '=' and ident[0] in linter.Letters:
if line[column..column + result - 1] != "=":
result = 0
elif line[column..column + result - 1] != ident:
result = 0
proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info: TLineInfo;
quality: range[0..100]; prefix: PrefixMatch;
inTypeContext: bool; scope: int): Suggest =
@ -88,7 +120,6 @@ proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info
result.section = section
result.quality = quality
result.isGlobal = sfGlobal in s.flags
result.tokenLen = s.name.s.len
result.prefix = prefix
result.contextFits = inTypeContext == (s.kind in {skType, skGenericParam})
result.scope = scope
@ -126,6 +157,10 @@ proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info
result.line = toLinenumber(infox)
result.column = toColumn(infox)
result.version = conf.suggestVersion
result.tokenLen = if section != ideHighlight:
s.name.s.len
else:
getTokenLenFromSource(conf, s.name.s, infox)
proc `$`*(suggest: Suggest): string =
result = $suggest.section