forked from M-Labs/artiq
compiler: give suggestions in diagnostics for unbound variable.
This uses the Jaro-Winkler edit distance, which seemed like the best fit for identifiers, even though it is intended for people's names.
This commit is contained in:
parent
9670939ca6
commit
c8cfa7c7bd
|
@ -11,6 +11,8 @@ from collections import OrderedDict, defaultdict
|
|||
from pythonparser import ast, algorithm, source, diagnostic, parse_buffer
|
||||
from pythonparser import lexer as source_lexer, parser as source_parser
|
||||
|
||||
from Levenshtein import jaro_winkler
|
||||
|
||||
from ..language import core as language_core
|
||||
from . import types, builtins, asttyped, prelude
|
||||
from .transforms import ASTTypedRewriter, Inferencer, IntMonomorphizer
|
||||
|
@ -224,12 +226,31 @@ class StitchingASTTypedRewriter(ASTTypedRewriter):
|
|||
# Try to find this value in the host environment and quote it.
|
||||
if node.id in self.host_environment:
|
||||
return self.quote(self.host_environment[node.id], node.loc)
|
||||
else:
|
||||
suggestion = self._most_similar_ident(node.id)
|
||||
if suggestion is not None:
|
||||
diag = diagnostic.Diagnostic("fatal",
|
||||
"name '{name}' is not bound to anything; did you mean '{suggestion}'?",
|
||||
{"name": node.id, "suggestion": suggestion},
|
||||
node.loc)
|
||||
self.engine.process(diag)
|
||||
else:
|
||||
diag = diagnostic.Diagnostic("fatal",
|
||||
"name '{name}' is not bound to anything", {"name": node.id},
|
||||
node.loc)
|
||||
self.engine.process(diag)
|
||||
|
||||
def _most_similar_ident(self, id):
|
||||
names = set()
|
||||
names.update(self.host_environment.keys())
|
||||
for typing_env in reversed(self.env_stack):
|
||||
names.update(typing_env.keys())
|
||||
|
||||
sorted_names = sorted(names, key=lambda other: jaro_winkler(id, other), reverse=True)
|
||||
if len(sorted_names) > 0:
|
||||
if jaro_winkler(id, sorted_names[0]) > 0.0:
|
||||
return sorted_names[0]
|
||||
|
||||
class StitchingInferencer(Inferencer):
|
||||
def __init__(self, engine, value_map, quote):
|
||||
super().__init__(engine)
|
||||
|
|
3
setup.py
3
setup.py
|
@ -27,7 +27,8 @@ requirements = [
|
|||
"sphinx", "sphinx-argparse", "pyserial", "numpy", "scipy",
|
||||
"python-dateutil", "prettytable", "h5py", "pydaqmx", "pyelftools",
|
||||
"quamash", "pyqtgraph", "pygit2", "aiohttp",
|
||||
"llvmlite_artiq", "pythonparser", "lit", "OutputCheck",
|
||||
"llvmlite_artiq", "pythonparser", "python-Levenshtein",
|
||||
"lit", "OutputCheck",
|
||||
]
|
||||
|
||||
scripts = [
|
||||
|
|
Loading…
Reference in New Issue