aboutsummaryrefslogtreecommitdiffstats
path: root/python/vhdl_langserver
diff options
context:
space:
mode:
Diffstat (limited to 'python/vhdl_langserver')
-rw-r--r--python/vhdl_langserver/document.py93
-rw-r--r--python/vhdl_langserver/lsp.py55
-rw-r--r--python/vhdl_langserver/lsptools.py6
-rw-r--r--python/vhdl_langserver/main.py69
-rw-r--r--python/vhdl_langserver/references.py22
-rw-r--r--python/vhdl_langserver/symbols.py181
-rw-r--r--python/vhdl_langserver/version.py2
-rw-r--r--python/vhdl_langserver/vhdl_ls.py111
-rw-r--r--python/vhdl_langserver/workspace.py155
9 files changed, 391 insertions, 303 deletions
diff --git a/python/vhdl_langserver/document.py b/python/vhdl_langserver/document.py
index 1b3cbf40b..82d11fe56 100644
--- a/python/vhdl_langserver/document.py
+++ b/python/vhdl_langserver/document.py
@@ -23,7 +23,7 @@ class Document(object):
# back to bytes using this encoding. And we hope the result would be
# the same as the file. Because VHDL uses the iso 8859-1 character
# set, we use the same encoding. The client should also use 8859-1.
- encoding = 'iso-8859-1'
+ encoding = "iso-8859-1"
initial_gap_size = 4096
@@ -40,11 +40,11 @@ class Document(object):
src_bytes = source.encode(Document.encoding, "replace")
src_len = len(src_bytes)
buf_len = src_len + Document.initial_gap_size
- fileid = name_table.Get_Identifier(filename.encode('utf-8'))
+ fileid = name_table.Get_Identifier(filename.encode("utf-8"))
if os.path.isabs(filename):
dirid = name_table.Null_Identifier
else:
- dirid = name_table.Get_Identifier(dirname.encode('utf-8'))
+ dirid = name_table.Get_Identifier(dirname.encode("utf-8"))
sfe = files_map.Reserve_Source_File(dirid, fileid, buf_len)
files_map_editor.Fill_Text(sfe, ctypes.c_char_p(src_bytes), src_len)
return sfe
@@ -52,42 +52,45 @@ class Document(object):
def reload(self, source):
"""Reload the source of a document. """
src_bytes = source.encode(Document.encoding, "replace")
- files_map_editor.Fill_Text(self._fe,
- ctypes.c_char_p(src_bytes), len(src_bytes))
+ files_map_editor.Fill_Text(self._fe, ctypes.c_char_p(src_bytes), len(src_bytes))
def __str__(self):
return str(self.uri)
def apply_change(self, change):
"""Apply a change to the document."""
- text = change['text']
- change_range = change.get('range')
+ text = change["text"]
+ change_range = change.get("range")
text_bytes = text.encode(Document.encoding, "replace")
if not change_range:
# The whole file has changed
raise AssertionError
- #if len(text_bytes) < thin.Files_Map.Get_Buffer_Length(self._fe):
+ # if len(text_bytes) < thin.Files_Map.Get_Buffer_Length(self._fe):
# xxxx_replace
- #else:
+ # else:
# xxxx_free
# xxxx_allocate
- #return
+ # return
- start_line = change_range['start']['line']
- start_col = change_range['start']['character']
- end_line = change_range['end']['line']
- end_col = change_range['end']['character']
+ start_line = change_range["start"]["line"]
+ start_col = change_range["start"]["character"]
+ end_line = change_range["end"]["line"]
+ end_col = change_range["end"]["character"]
status = files_map_editor.Replace_Text(
self._fe,
- start_line + 1, start_col,
- end_line + 1, end_col,
- ctypes.c_char_p(text_bytes), len(text_bytes))
+ start_line + 1,
+ start_col,
+ end_line + 1,
+ end_col,
+ ctypes.c_char_p(text_bytes),
+ len(text_bytes),
+ )
if status:
return
-
+
# Failed to replace text.
# Increase size
self.gap_size *= 2
@@ -101,9 +104,13 @@ class Document(object):
self._fe = new_sfe
status = files_map_editor.Replace_Text(
self._fe,
- start_line + 1, start_col,
- end_line + 1, end_col,
- ctypes.c_char_p(text_bytes), len(text_bytes))
+ start_line + 1,
+ start_col,
+ end_line + 1,
+ end_col,
+ ctypes.c_char_p(text_bytes),
+ len(text_bytes),
+ )
assert status
def check_document(self, text):
@@ -112,7 +119,8 @@ class Document(object):
text_bytes = text.encode(Document.encoding, "replace")
files_map_editor.Check_Buffer_Content(
- self._fe, ctypes.c_char_p(text_bytes), len(text_bytes))
+ self._fe, ctypes.c_char_p(text_bytes), len(text_bytes)
+ )
@staticmethod
def add_to_library(tree):
@@ -127,8 +135,10 @@ class Document(object):
next_unit = nodes.Get_Chain(unit)
nodes.Set_Chain(unit, nodes.Null_Iir)
lib_unit = nodes.Get_Library_Unit(unit)
- if (lib_unit != nodes.Null_Iir
- and nodes.Get_Identifier(unit) != name_table.Null_Identifier):
+ if (
+ lib_unit != nodes.Null_Iir
+ and nodes.Get_Identifier(unit) != name_table.Null_Identifier
+ ):
# Put the unit (only if it has a library unit) in the library.
libraries.Add_Design_Unit_Into_Library(unit, False)
tree = nodes.Get_Design_File(unit)
@@ -163,13 +173,13 @@ class Document(object):
def flatten_symbols(self, syms, parent):
res = []
for s in syms:
- s['location'] = {'uri': self.uri, 'range': s['range']}
- del s['range']
- s.pop('detail', None)
+ s["location"] = {"uri": self.uri, "range": s["range"]}
+ del s["range"]
+ s.pop("detail", None)
if parent is not None:
- s['containerName'] = parent
+ s["containerName"] = parent
res.append(s)
- children = s.pop('children', None)
+ children = s.pop("children", None)
if children is not None:
res.extend(self.flatten_symbols(children, s))
return res
@@ -178,20 +188,22 @@ class Document(object):
log.debug("document_symbols")
if self._tree == nodes.Null_Iir:
return []
- syms = symbols.get_symbols_chain(self._fe, nodes.Get_First_Design_Unit(self._tree))
+ syms = symbols.get_symbols_chain(
+ self._fe, nodes.Get_First_Design_Unit(self._tree)
+ )
return self.flatten_symbols(syms, None)
def position_to_location(self, position):
- pos = files_map.File_Line_To_Position(self._fe, position['line'] + 1)
- return files_map.File_Pos_To_Location(self._fe, pos) + position['character']
+ pos = files_map.File_Line_To_Position(self._fe, position["line"] + 1)
+ return files_map.File_Pos_To_Location(self._fe, pos) + position["character"]
def goto_definition(self, position):
loc = self.position_to_location(position)
return references.goto_definition(self._tree, loc)
def format_range(self, rng):
- first_line = rng['start']['line'] + 1
- last_line = rng['end']['line'] + (1 if rng['end']['character'] != 0 else 0)
+ first_line = rng["start"]["line"] + 1
+ last_line = rng["end"]["line"] + (1 if rng["end"]["character"] != 0 else 0)
if last_line < first_line:
return None
if self._tree == nodes.Null_Iir:
@@ -201,9 +213,14 @@ class Document(object):
buffer = formatters.Get_C_String(hand)
buf_len = formatters.Get_Length(hand)
newtext = buffer[:buf_len].decode(Document.encoding)
- res = [ {'range': {
- 'start': { 'line': first_line - 1, 'character': 0},
- 'end': { 'line': last_line, 'character': 0}},
- 'newText': newtext}]
+ res = [
+ {
+ "range": {
+ "start": {"line": first_line - 1, "character": 0},
+ "end": {"line": last_line, "character": 0},
+ },
+ "newText": newtext,
+ }
+ ]
formatters.Free_Handle(hand)
return res
diff --git a/python/vhdl_langserver/lsp.py b/python/vhdl_langserver/lsp.py
index 9a93b2a16..60f32be76 100644
--- a/python/vhdl_langserver/lsp.py
+++ b/python/vhdl_langserver/lsp.py
@@ -10,7 +10,7 @@ except ImportError:
from urllib2 import quote
from urlparse import unquote
-log = logging.getLogger('ghdl-ls')
+log = logging.getLogger("ghdl-ls")
class ProtocolError(Exception):
@@ -49,7 +49,7 @@ def path_from_uri(uri):
def path_to_uri(path):
# Convert path to file uri (add html like head part)
if os.name == "nt":
- return "file:///" + quote(path.replace('\\', '/'))
+ return "file:///" + quote(path.replace("\\", "/"))
else:
return "file://" + quote(path)
@@ -71,20 +71,20 @@ class LanguageProtocolServer(object):
# Return on EOF.
if not line:
return None
- if line[-2:] != '\r\n':
+ if line[-2:] != "\r\n":
raise ProtocolError("invalid end of line in header")
line = line[:-2]
if not line:
# End of headers.
- log.debug('Headers: %r', headers)
- length = headers.get('Content-Length', None)
+ log.debug("Headers: %r", headers)
+ length = headers.get("Content-Length", None)
if length is not None:
body = self.conn.read(int(length))
return body
else:
raise ProtocolError("missing Content-Length in header")
else:
- key, value = line.split(': ', 1)
+ key, value = line.split(": ", 1)
headers[key] = value
def run(self):
@@ -96,22 +96,22 @@ class LanguageProtocolServer(object):
# Text to JSON
msg = json.loads(body)
- log.debug('Read msg: %s', msg)
+ log.debug("Read msg: %s", msg)
reply = self.handle(msg)
if reply is not None:
self.write_output(reply)
def handle(self, msg):
- if msg.get('jsonrpc', None) != '2.0':
+ if msg.get("jsonrpc", None) != "2.0":
raise ProtocolError("invalid jsonrpc version")
- tid = msg.get('id', None)
- method = msg.get('method', None)
+ tid = msg.get("id", None)
+ method = msg.get("method", None)
if method is None:
# This is a reply.
- log.error('Unexpected reply for %s', tid)
+ log.error("Unexpected reply for %s", tid)
return
- params = msg.get('params', None)
+ params = msg.get("params", None)
fmethod = self.handler.dispatcher.get(method, None)
if fmethod:
if params is None:
@@ -120,20 +120,20 @@ class LanguageProtocolServer(object):
response = fmethod(**params)
except Exception as e:
log.exception(
- "Caught exception while handling %s with params %s:",
- method, params
+ "Caught exception while handling %s with params %s:", method, params
)
self.show_message(
MessageType.Error,
- ("Caught exception while handling {}, " +
- "see VHDL language server output for details.").format(
- method)
+ (
+ "Caught exception while handling {}, "
+ + "see VHDL language server output for details."
+ ).format(method),
)
response = None
if tid is None:
# If this was just a notification, discard it
return None
- log.debug('Response: %s', response)
+ log.debug("Response: %s", response)
rbody = {
"jsonrpc": "2.0",
"id": tid,
@@ -141,7 +141,7 @@ class LanguageProtocolServer(object):
}
else:
# Unknown method.
- log.error('Unknown method %s', method)
+ log.error("Unknown method %s", method)
# If this was just a notification, discard it
if tid is None:
return None
@@ -151,15 +151,15 @@ class LanguageProtocolServer(object):
"id": tid,
"error": {
"code": JSONErrorCodes.MethodNotFound,
- "message": "unknown method {}".format(method)
- }
+ "message": "unknown method {}".format(method),
+ },
}
return rbody
def write_output(self, body):
output = json.dumps(body, separators=(",", ":"))
- self.conn.write('Content-Length: {}\r\n'.format(len(output)))
- self.conn.write('\r\n')
+ self.conn.write("Content-Length: {}\r\n".format(len(output)))
+ self.conn.write("\r\n")
self.conn.write(output)
def notify(self, method, params):
@@ -187,12 +187,13 @@ class LanguageProtocolServer(object):
self.running = False
def show_message(self, typ, message):
- self.notify('window/showMessage', {'type': typ, 'message': message})
+ self.notify("window/showMessage", {"type": typ, "message": message})
def configuration(self, items):
- return self.send_request("workspace/configuration", {'items': items})
+ return self.send_request("workspace/configuration", {"items": items})
-#----------------------------------------------------------------------
+
+# ----------------------------------------------------------------------
# Standard defines and object types
#
@@ -243,7 +244,7 @@ class DiagnosticSeverity(object):
class TextDocumentSyncKind(object):
- NONE = 0,
+ NONE = (0,)
FULL = 1
INCREMENTAL = 2
diff --git a/python/vhdl_langserver/lsptools.py b/python/vhdl_langserver/lsptools.py
index 8b9fd0a17..648f0a8c0 100644
--- a/python/vhdl_langserver/lsptools.py
+++ b/python/vhdl_langserver/lsptools.py
@@ -29,11 +29,9 @@ def json2lsp():
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help="sub-command help")
- parser_l2j = subparsers.add_parser('lsp2json',
- help='convert lsp dump to JSON')
+ parser_l2j = subparsers.add_parser("lsp2json", help="convert lsp dump to JSON")
parser_l2j.set_defaults(func=lsp2json)
- parser_j2l = subparsers.add_parser('json2lsp',
- help='convert JSON to lsp dump')
+ parser_j2l = subparsers.add_parser("json2lsp", help="convert JSON to lsp dump")
parser_j2l.set_defaults(func=json2lsp)
args = parser.parse_args()
args.func()
diff --git a/python/vhdl_langserver/main.py b/python/vhdl_langserver/main.py
index 0759043e6..5fe0e0549 100644
--- a/python/vhdl_langserver/main.py
+++ b/python/vhdl_langserver/main.py
@@ -13,15 +13,16 @@ from . import version
from . import lsp
from . import vhdl_ls
-logger = logging.getLogger('ghdl-ls')
+logger = logging.getLogger("ghdl-ls")
class LSPConnTrace(object):
"""Wrapper class to save in and out packets"""
+
def __init__(self, basename, conn):
self.conn = conn
- self.trace_in = open(basename + '.in', 'w')
- self.trace_out = open(basename + '.out', 'w')
+ self.trace_in = open(basename + ".in", "w")
+ self.trace_out = open(basename + ".out", "w")
def readline(self):
res = self.conn.readline()
@@ -42,32 +43,31 @@ class LSPConnTrace(object):
def rotate_log_files(basename, num):
for i in range(num, 0, -1):
- oldfile = '{}.{}'.format(basename, i - 1)
+ oldfile = "{}.{}".format(basename, i - 1)
if os.path.isfile(oldfile):
- os.rename(oldfile, '{}.{}'.format(basename, i))
+ os.rename(oldfile, "{}.{}".format(basename, i))
if os.path.isfile(basename):
- os.rename(basename, '{}.0'.format(basename))
+ os.rename(basename, "{}.0".format(basename))
def main():
- parser = argparse.ArgumentParser(
- description='VHDL Language Protocol Server')
- parser.add_argument(
- '--version', '-V', action='version', version='%(prog)s ' + version.__version__)
- parser.add_argument(
- '--verbose', '-v', action='count', default=0,
- help='Show debug output')
+ parser = argparse.ArgumentParser(description="VHDL Language Protocol Server")
parser.add_argument(
- '--log-file',
- help="Redirect logs to the given file instead of stderr")
+ "--version", "-V", action="version", version="%(prog)s " + version.__version__
+ )
parser.add_argument(
- '--trace-file',
- help="Save rpc data to FILE.in and FILE.out")
+ "--verbose", "-v", action="count", default=0, help="Show debug output"
+ )
parser.add_argument(
- '--input', '-i',
- help="Read request from file")
+ "--log-file", help="Redirect logs to the given file instead of stderr"
+ )
+ parser.add_argument("--trace-file", help="Save rpc data to FILE.in and FILE.out")
+ parser.add_argument("--input", "-i", help="Read request from file")
parser.add_argument(
- '--disp-config', action='store_true', help="Disp installation configuration and exit")
+ "--disp-config",
+ action="store_true",
+ help="Disp installation configuration and exit",
+ )
args = parser.parse_args()
@@ -86,36 +86,39 @@ def main():
if args.log_file:
rotate_log_files(args.log_file, 5)
- logstream = open(args.log_file, 'w')
+ logstream = open(args.log_file, "w")
else:
logstream = sys.stderr
- logging.basicConfig(format='%(asctime)-15s [%(levelname)s] %(message)s',
- stream=logstream, level=loglevel)
+ logging.basicConfig(
+ format="%(asctime)-15s [%(levelname)s] %(message)s",
+ stream=logstream,
+ level=loglevel,
+ )
if args.verbose != 0:
- sys.stderr.write('Args: {}\n'.format(sys.argv))
- sys.stderr.write('Current directory: {}\n'.format(os.getcwd()))
+ sys.stderr.write("Args: {}\n".format(sys.argv))
+ sys.stderr.write("Current directory: {}\n".format(os.getcwd()))
- logger.info('Args: %s', sys.argv)
- logger.info('Current directory is %s', os.getcwd())
+ logger.info("Args: %s", sys.argv)
+ logger.info("Current directory is %s", os.getcwd())
# Connection
instream = sys.stdin.buffer
if args.input is not None:
- instream = open(args.input, 'rb')
+ instream = open(args.input, "rb")
conn = lsp.LSPConn(instream, sys.stdout.buffer)
trace_file = args.trace_file
if trace_file is None:
- trace_file = os.environ.get('GHDL_LS_TRACE')
+ trace_file = os.environ.get("GHDL_LS_TRACE")
if trace_file is not None:
if args.input is None:
- rotate_log_files(trace_file + '.in', 5)
- rotate_log_files(trace_file + '.out', 5)
+ rotate_log_files(trace_file + ".in", 5)
+ rotate_log_files(trace_file + ".out", 5)
conn = LSPConnTrace(trace_file, conn)
else:
- logger.info('Traces disabled when -i/--input')
+ logger.info("Traces disabled when -i/--input")
handler = vhdl_ls.VhdlLanguageServer()
@@ -123,5 +126,5 @@ def main():
server = lsp.LanguageProtocolServer(handler, conn)
server.run()
except Exception:
- logger.exception('Uncaught error')
+ logger.exception("Uncaught error")
sys.exit(1)
diff --git a/python/vhdl_langserver/references.py b/python/vhdl_langserver/references.py
index 76cca2a19..f716548eb 100644
--- a/python/vhdl_langserver/references.py
+++ b/python/vhdl_langserver/references.py
@@ -22,12 +22,14 @@ def find_def(n, loc):
if n == nodes.Null_Iir:
return None
k = nodes.Get_Kind(n)
- if k in [nodes.Iir_Kind.Simple_Name,
- nodes.Iir_Kind.Character_Literal,
- nodes.Iir_Kind.Operator_Symbol,
- nodes.Iir_Kind.Selected_Name,
- nodes.Iir_Kind.Attribute_Name,
- nodes.Iir_Kind.Selected_Element]:
+ if k in [
+ nodes.Iir_Kind.Simple_Name,
+ nodes.Iir_Kind.Character_Literal,
+ nodes.Iir_Kind.Operator_Symbol,
+ nodes.Iir_Kind.Selected_Name,
+ nodes.Iir_Kind.Attribute_Name,
+ nodes.Iir_Kind.Selected_Element,
+ ]:
n_loc = nodes.Get_Location(n)
if loc >= n_loc:
ident = nodes.Get_Identifier(n)
@@ -39,7 +41,7 @@ def find_def(n, loc):
elif k == nodes.Iir_Kind.Design_File:
return find_def_chain(nodes.Get_First_Design_Unit(n), loc)
elif k == nodes.Iir_Kind.Design_Unit:
- #if loc > elocations.Get_End_Location(unit):
+ # if loc > elocations.Get_End_Location(unit):
# return None
res = find_def_chain(nodes.Get_Context_Items(n), loc)
if res is not None:
@@ -89,6 +91,10 @@ def goto_definition(n, loc):
log.debug("for loc %u found node %s", loc, ref)
if ref is None:
return None
- log.debug("for loc %u id=%s", loc, name_table.Get_Name_Ptr(nodes.Get_Identifier(ref)).decode('utf-8'))
+ log.debug(
+ "for loc %u id=%s",
+ loc,
+ name_table.Get_Name_Ptr(nodes.Get_Identifier(ref)).decode("utf-8"),
+ )
ent = nodes.Get_Named_Entity(ref)
return None if ent == nodes.Null_Iir else ent
diff --git a/python/vhdl_langserver/symbols.py b/python/vhdl_langserver/symbols.py
index 11335408c..d0bd269de 100644
--- a/python/vhdl_langserver/symbols.py
+++ b/python/vhdl_langserver/symbols.py
@@ -8,63 +8,69 @@ import libghdl.thin.vhdl.elocations as elocations
from . import lsp
SYMBOLS_MAP = {
- nodes.Iir_Kind.Package_Declaration: {'kind': lsp.SymbolKind.Package, 'detail': '(declaration)'},
- nodes.Iir_Kind.Package_Body: {'kind': lsp.SymbolKind.Package, 'detail': '(body)'},
- nodes.Iir_Kind.Entity_Declaration: {'kind': lsp.SymbolKind.Module},
- nodes.Iir_Kind.Architecture_Body: {'kind': lsp.SymbolKind.Module},
- nodes.Iir_Kind.Configuration_Declaration: {'kind': lsp.SymbolKind.Module},
- nodes.Iir_Kind.Package_Instantiation_Declaration: {'kind': lsp.SymbolKind.Module},
- nodes.Iir_Kind.Component_Declaration: {'kind': lsp.SymbolKind.Module},
- nodes.Iir_Kind.Context_Declaration: {'kind': lsp.SymbolKind.Module},
- nodes.Iir_Kind.Use_Clause: {'kind': None},
- nodes.Iir_Kind.Library_Clause: {'kind': None},
- nodes.Iir_Kind.Procedure_Declaration: {'kind': lsp.SymbolKind.Function},
- nodes.Iir_Kind.Function_Declaration: {'kind': lsp.SymbolKind.Function},
- nodes.Iir_Kind.Interface_Procedure_Declaration: {'kind': lsp.SymbolKind.Function},
- nodes.Iir_Kind.Interface_Function_Declaration: {'kind': lsp.SymbolKind.Function},
- nodes.Iir_Kind.Procedure_Body: {'kind': lsp.SymbolKind.Function, 'detail': '(body)'},
- nodes.Iir_Kind.Function_Body: {'kind': lsp.SymbolKind.Function, 'detail': '(body)'},
- nodes.Iir_Kind.Type_Declaration: {'kind': lsp.SymbolKind.Constructor},
- nodes.Iir_Kind.Subtype_Declaration: {'kind': lsp.SymbolKind.Constructor},
- nodes.Iir_Kind.Attribute_Declaration: {'kind': lsp.SymbolKind.Property},
- nodes.Iir_Kind.Attribute_Specification: {'kind': None},
- nodes.Iir_Kind.Disconnection_Specification: {'kind': None},
- nodes.Iir_Kind.Anonymous_Type_Declaration: {'kind': None},
- nodes.Iir_Kind.Variable_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Constant_Declaration: {'kind': lsp.SymbolKind.Constant},
- nodes.Iir_Kind.Signal_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Signal_Attribute_Declaration: {'kind': None},
- nodes.Iir_Kind.File_Declaration: {'kind': lsp.SymbolKind.File},
- nodes.Iir_Kind.Interface_Variable_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Interface_Constant_Declaration: {'kind': lsp.SymbolKind.Constant},
- nodes.Iir_Kind.Interface_Signal_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Interface_File_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.File_Declaration: {'kind': lsp.SymbolKind.File},
- nodes.Iir_Kind.Object_Alias_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Non_Object_Alias_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Protected_Type_Body: {'kind': lsp.SymbolKind.Class},
- nodes.Iir_Kind.Group_Template_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Group_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Concurrent_Simple_Signal_Assignment: {'kind': None},
- nodes.Iir_Kind.Concurrent_Conditional_Signal_Assignment: {'kind': None},
- nodes.Iir_Kind.Concurrent_Selected_Signal_Assignment: {'kind': None},
- nodes.Iir_Kind.Concurrent_Procedure_Call_Statement: {'kind': None},
- nodes.Iir_Kind.Concurrent_Assertion_Statement: {'kind': None},
- nodes.Iir_Kind.Component_Instantiation_Statement: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Block_Statement: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.If_Generate_Statement: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.For_Generate_Statement: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Case_Generate_Statement: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Sensitized_Process_Statement: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Process_Statement: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Psl_Assert_Directive: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Psl_Assume_Directive: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Psl_Cover_Directive: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Psl_Restrict_Directive: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Psl_Endpoint_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Psl_Declaration: {'kind': lsp.SymbolKind.Variable},
- nodes.Iir_Kind.Psl_Assert_Directive: {'kind': lsp.SymbolKind.Method},
- nodes.Iir_Kind.Configuration_Specification: {'kind': None},
+ nodes.Iir_Kind.Package_Declaration: {
+ "kind": lsp.SymbolKind.Package,
+ "detail": "(declaration)",
+ },
+ nodes.Iir_Kind.Package_Body: {"kind": lsp.SymbolKind.Package, "detail": "(body)"},
+ nodes.Iir_Kind.Entity_Declaration: {"kind": lsp.SymbolKind.Module},
+ nodes.Iir_Kind.Architecture_Body: {"kind": lsp.SymbolKind.Module},
+ nodes.Iir_Kind.Configuration_Declaration: {"kind": lsp.SymbolKind.Module},
+ nodes.Iir_Kind.Package_Instantiation_Declaration: {"kind": lsp.SymbolKind.Module},
+ nodes.Iir_Kind.Component_Declaration: {"kind": lsp.SymbolKind.Module},
+ nodes.Iir_Kind.Context_Declaration: {"kind": lsp.SymbolKind.Module},
+ nodes.Iir_Kind.Use_Clause: {"kind": None},
+ nodes.Iir_Kind.Library_Clause: {"kind": None},
+ nodes.Iir_Kind.Procedure_Declaration: {"kind": lsp.SymbolKind.Function},
+ nodes.Iir_Kind.Function_Declaration: {"kind": lsp.SymbolKind.Function},
+ nodes.Iir_Kind.Interface_Procedure_Declaration: {"kind": lsp.SymbolKind.Function},
+ nodes.Iir_Kind.Interface_Function_Declaration: {"kind": lsp.SymbolKind.Function},
+ nodes.Iir_Kind.Procedure_Body: {
+ "kind": lsp.SymbolKind.Function,
+ "detail": "(body)",
+ },
+ nodes.Iir_Kind.Function_Body: {"kind": lsp.SymbolKind.Function, "detail": "(body)"},
+ nodes.Iir_Kind.Type_Declaration: {"kind": lsp.SymbolKind.Constructor},
+ nodes.Iir_Kind.Subtype_Declaration: {"kind": lsp.SymbolKind.Constructor},
+ nodes.Iir_Kind.Attribute_Declaration: {"kind": lsp.SymbolKind.Property},
+ nodes.Iir_Kind.Attribute_Specification: {"kind": None},
+ nodes.Iir_Kind.Disconnection_Specification: {"kind": None},
+ nodes.Iir_Kind.Anonymous_Type_Declaration: {"kind": None},
+ nodes.Iir_Kind.Variable_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Constant_Declaration: {"kind": lsp.SymbolKind.Constant},
+ nodes.Iir_Kind.Signal_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Signal_Attribute_Declaration: {"kind": None},
+ nodes.Iir_Kind.File_Declaration: {"kind": lsp.SymbolKind.File},
+ nodes.Iir_Kind.Interface_Variable_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Interface_Constant_Declaration: {"kind": lsp.SymbolKind.Constant},
+ nodes.Iir_Kind.Interface_Signal_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Interface_File_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.File_Declaration: {"kind": lsp.SymbolKind.File},
+ nodes.Iir_Kind.Object_Alias_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Non_Object_Alias_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Protected_Type_Body: {"kind": lsp.SymbolKind.Class},
+ nodes.Iir_Kind.Group_Template_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Group_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Concurrent_Simple_Signal_Assignment: {"kind": None},
+ nodes.Iir_Kind.Concurrent_Conditional_Signal_Assignment: {"kind": None},
+ nodes.Iir_Kind.Concurrent_Selected_Signal_Assignment: {"kind": None},
+ nodes.Iir_Kind.Concurrent_Procedure_Call_Statement: {"kind": None},
+ nodes.Iir_Kind.Concurrent_Assertion_Statement: {"kind": None},
+ nodes.Iir_Kind.Component_Instantiation_Statement: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Block_Statement: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.If_Generate_Statement: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.For_Generate_Statement: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Case_Generate_Statement: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Sensitized_Process_Statement: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Process_Statement: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Psl_Assert_Directive: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Psl_Assume_Directive: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Psl_Cover_Directive: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Psl_Restrict_Directive: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Psl_Endpoint_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Psl_Declaration: {"kind": lsp.SymbolKind.Variable},
+ nodes.Iir_Kind.Psl_Assert_Directive: {"kind": lsp.SymbolKind.Method},
+ nodes.Iir_Kind.Configuration_Specification: {"kind": None},
}
@@ -72,7 +78,7 @@ def location_to_position(fe, loc):
assert loc != files_map.No_Location
line = files_map.Location_File_To_Line(loc, fe)
off = files_map.Location_File_Line_To_Offset(loc, fe, line)
- return {'line': line - 1, 'character': off}
+ return {"line": line - 1, "character": off}
def get_symbols_chain(fe, n):
@@ -89,11 +95,10 @@ def get_symbols(fe, n):
m = SYMBOLS_MAP.get(k, None)
if m is None:
raise AssertionError("get_symbol: unhandled {}".format(pyutils.kind_image(k)))
- kind = m['kind']
+ kind = m["kind"]
if kind is None:
return None
- if k in [nodes.Iir_Kind.Procedure_Declaration,
- nodes.Iir_Kind.Function_Declaration]:
+ if k in [nodes.Iir_Kind.Procedure_Declaration, nodes.Iir_Kind.Function_Declaration]:
# Discard implicit declarations.
if nodes.Get_Implicit_Definition(n) < nodes.Iir_Predefined.PNone:
return None
@@ -101,13 +106,12 @@ def get_symbols(fe, n):
# Use the body instead.
# FIXME: but get interface from the spec!
return None
- res = {'kind': kind}
- detail = m.get('detail')
+ res = {"kind": kind}
+ detail = m.get("detail")
if detail is not None:
- res['detail'] = detail
+ res["detail"] = detail
# Get the name
- if k in [nodes.Iir_Kind.Function_Body,
- nodes.Iir_Kind.Procedure_Body]:
+ if k in [nodes.Iir_Kind.Function_Body, nodes.Iir_Kind.Procedure_Body]:
nid = nodes.Get_Identifier(nodes.Get_Subprogram_Specification(n))
else:
nid = nodes.Get_Identifier(n)
@@ -116,15 +120,17 @@ def get_symbols(fe, n):
else:
name = pyutils.name_image(nid)
# Get the range. Use elocations when possible.
- if k in (nodes.Iir_Kind.Architecture_Body,
- nodes.Iir_Kind.Entity_Declaration,
- nodes.Iir_Kind.Package_Declaration,
- nodes.Iir_Kind.Package_Body,
- nodes.Iir_Kind.Component_Declaration,
- nodes.Iir_Kind.Process_Statement,
- nodes.Iir_Kind.Sensitized_Process_Statement,
- nodes.Iir_Kind.If_Generate_Statement,
- nodes.Iir_Kind.For_Generate_Statement):
+ if k in (
+ nodes.Iir_Kind.Architecture_Body,
+ nodes.Iir_Kind.Entity_Declaration,
+ nodes.Iir_Kind.Package_Declaration,
+ nodes.Iir_Kind.Package_Body,
+ nodes.Iir_Kind.Component_Declaration,
+ nodes.Iir_Kind.Process_Statement,
+ nodes.Iir_Kind.Sensitized_Process_Statement,
+ nodes.Iir_Kind.If_Generate_Statement,
+ nodes.Iir_Kind.For_Generate_Statement,
+ ):
start_loc = elocations.Get_Start_Location(n)
end_loc = elocations.Get_End_Location(n)
if end_loc == files_map.No_Location:
@@ -133,30 +139,39 @@ def get_symbols(fe, n):
else:
start_loc = nodes.Get_Location(n)
end_loc = start_loc + name_table.Get_Name_Length(nid)
- res['range'] = {'start': location_to_position(fe, start_loc),
- 'end': location_to_position(fe, end_loc)}
+ res["range"] = {
+ "start": location_to_position(fe, start_loc),
+ "end": location_to_position(fe, end_loc),
+ }
# Gather children.
# FIXME: should we use a list of fields to inspect ?
children = []
- #if nodes_meta.Has_Generic_Chain(k):
+ # if nodes_meta.Has_Generic_Chain(k):
# children.extend(get_symbols_chain(fe, nodes.Get_Generic_Chain(n)))
- #if nodes_meta.Has_Port_Chain(k):
+ # if nodes_meta.Has_Port_Chain(k):
# children.extend(get_symbols_chain(fe, nodes.Get_Port_Chain(n)))
- #if nodes_meta.Has_Interface_Declaration_Chain(k):
+ # if nodes_meta.Has_Interface_Declaration_Chain(k):
# children.extend(get_symbols_chain(fe, nodes.Get_Interface_Declaration_Chain(n)))
if k in (nodes.Iir_Kind.Package_Declaration, nodes.Iir_Kind.Package_Body):
children.extend(get_symbols_chain(fe, nodes.Get_Declaration_Chain(n)))
if nodes_meta.Has_Concurrent_Statement_Chain(k):
children.extend(get_symbols_chain(fe, nodes.Get_Concurrent_Statement_Chain(n)))
if nodes_meta.Has_Generate_Statement_Body(k):
- children.extend(get_symbols_chain(fe, nodes.Get_Concurrent_Statement_Chain(nodes.Get_Generate_Statement_Body(n))))
+ children.extend(
+ get_symbols_chain(
+ fe,
+ nodes.Get_Concurrent_Statement_Chain(
+ nodes.Get_Generate_Statement_Body(n)
+ ),
+ )
+ )
if children:
- res['children'] = children
+ res["children"] = children
else:
# Discard anonymous symbols without children.
if name is None:
return None
- res['name'] = name if name is not None else '<anon>'
+ res["name"] = name if name is not None else "<anon>"
return res
diff --git a/python/vhdl_langserver/version.py b/python/vhdl_langserver/version.py
index e92dbbbcc..4b0d124d5 100644
--- a/python/vhdl_langserver/version.py
+++ b/python/vhdl_langserver/version.py
@@ -1 +1 @@
-__version__ = '0.1dev'
+__version__ = "0.1dev"
diff --git a/python/vhdl_langserver/vhdl_ls.py b/python/vhdl_langserver/vhdl_ls.py
index c2559630e..61c4aed23 100644
--- a/python/vhdl_langserver/vhdl_ls.py
+++ b/python/vhdl_langserver/vhdl_ls.py
@@ -12,23 +12,23 @@ class VhdlLanguageServer(object):
self.lsp = None
self._shutdown = False
self.dispatcher = {
- 'initialize': self.initialize,
- 'initialized': self.initialized,
- 'shutdown': self.shutdown,
- '$/setTraceNotification': self.setTraceNotification,
- 'textDocument/didOpen': self.textDocument_didOpen,
- 'textDocument/didChange': self.textDocument_didChange,
- 'textDocument/didClose': self.textDocument_didClose,
- 'textDocument/didSave': self.textDocument_didSave,
+ "initialize": self.initialize,
+ "initialized": self.initialized,
+ "shutdown": self.shutdown,
+ "$/setTraceNotification": self.setTraceNotification,
+ "textDocument/didOpen": self.textDocument_didOpen,
+ "textDocument/didChange": self.textDocument_didChange,
+ "textDocument/didClose": self.textDocument_didClose,
+ "textDocument/didSave": self.textDocument_didSave,
# 'textDocument/hover': self.hover,
- 'textDocument/definition': self.textDocument_definition,
- 'textDocument/documentSymbol': self.textDocument_documentSymbol,
+ "textDocument/definition": self.textDocument_definition,
+ "textDocument/documentSymbol": self.textDocument_documentSymbol,
# 'textDocument/completion': self.completion,
- 'textDocument/rangeFormatting': self.textDocument_rangeFormatting,
- 'workspace/xShowAllFiles': self.workspace_xShowAllFiles,
- 'workspace/xGetAllEntities': self.workspace_xGetAllEntities,
- 'workspace/xGetEntityInterface': self.workspace_xGetEntityInterface,
- }
+ "textDocument/rangeFormatting": self.textDocument_rangeFormatting,
+ "workspace/xShowAllFiles": self.workspace_xShowAllFiles,
+ "workspace/xGetAllEntities": self.workspace_xGetAllEntities,
+ "workspace/xGetEntityInterface": self.workspace_xGetEntityInterface,
+ }
def set_lsp(self, server):
self.lsp = server
@@ -41,80 +41,91 @@ class VhdlLanguageServer(object):
def capabilities(self):
server_capabilities = {
- 'textDocumentSync': {
- 'openClose': True,
- 'change': lsp.TextDocumentSyncKind.INCREMENTAL,
- 'save': {
- 'includeText': True}
- },
- 'hoverProvider': False,
+ "textDocumentSync": {
+ "openClose": True,
+ "change": lsp.TextDocumentSyncKind.INCREMENTAL,
+ "save": {"includeText": True},
+ },
+ "hoverProvider": False,
# 'completionProvider': False,
# 'signatureHelpProvider': {
# 'triggerCharacters': ['(', ',']
# },
- 'definitionProvider': True,
- 'referencesProvider': False,
- 'documentHighlightProvider': False,
- 'documentSymbolProvider': True,
- 'codeActionProvider': False,
- 'documentFormattingProvider': False,
- 'documentRangeFormattingProvider': True,
- 'renameProvider': False,
+ "definitionProvider": True,
+ "referencesProvider": False,
+ "documentHighlightProvider": False,
+ "documentSymbolProvider": True,
+ "codeActionProvider": False,
+ "documentFormattingProvider": False,
+ "documentRangeFormattingProvider": True,
+ "renameProvider": False,
}
return server_capabilities
- def initialize(self, processId, rootPath, capabilities, rootUri=None,
- initializationOptions=None, **_):
- log.debug('Language server initialized with %s %s %s %s',
- processId, rootUri, rootPath, initializationOptions)
+ def initialize(
+ self,
+ processId,
+ rootPath,
+ capabilities,
+ rootUri=None,
+ initializationOptions=None,
+ **_
+ ):
+ log.debug(
+ "Language server initialized with %s %s %s %s",
+ processId,
+ rootUri,
+ rootPath,
+ initializationOptions,
+ )
if rootUri is None:
- rootUri = lsp.path_to_uri(rootPath) if rootPath is not None else ''
+ rootUri = lsp.path_to_uri(rootPath) if rootPath is not None else ""
self.workspace = Workspace(rootUri, self.lsp)
# Get our capabilities
- return {'capabilities': self.capabilities()}
+ return {"capabilities": self.capabilities()}
def initialized(self):
# Event when the client is fully initialized.
return None
def textDocument_didOpen(self, textDocument=None):
- doc_uri = textDocument['uri']
- self.workspace.put_document(doc_uri, textDocument['text'],
- version=textDocument.get('version'))
+ doc_uri = textDocument["uri"]
+ self.workspace.put_document(
+ doc_uri, textDocument["text"], version=textDocument.get("version")
+ )
self.lint(doc_uri)
- def textDocument_didChange(self, textDocument=None, contentChanges=None,
- **_kwargs):
- doc_uri = textDocument['uri']
- new_version = textDocument.get('version')
+ def textDocument_didChange(self, textDocument=None, contentChanges=None, **_kwargs):
+ doc_uri = textDocument["uri"]
+ new_version = textDocument.get("version")
self.workspace.apply_changes(doc_uri, contentChanges, new_version)
def lint(self, doc_uri):
self.workspace.lint(doc_uri)
def textDocument_didClose(self, textDocument=None, **_kwargs):
- self.workspace.rm_document(textDocument['uri'])
+ self.workspace.rm_document(textDocument["uri"])
def textDocument_didSave(self, textDocument=None, text=None, **_kwargs):
if text is not None:
# Sanity check: check we have the same content for the document.
- self.workspace.check_document(textDocument['uri'], text)
+ self.workspace.check_document(textDocument["uri"], text)
else:
log.debug("did save - no text")
- self.lint(textDocument['uri'])
+ self.lint(textDocument["uri"])
def textDocument_definition(self, textDocument=None, position=None):
- return self.workspace.goto_definition(textDocument['uri'], position)
+ return self.workspace.goto_definition(textDocument["uri"], position)
def textDocument_documentSymbol(self, textDocument=None):
- doc = self.workspace.get_or_create_document(textDocument['uri'])
+ doc = self.workspace.get_or_create_document(textDocument["uri"])
return doc.document_symbols()
def textDocument_rangeFormatting(self, textDocument=None, range=None, options=None):
- doc_uri = textDocument['uri']
+ doc_uri = textDocument["uri"]
doc = self.workspace.get_document(doc_uri)
- assert doc is not None, 'Try to format a non-loaded document'
+ assert doc is not None, "Try to format a non-loaded document"
res = doc.format_range(range)
if res is not None:
self.lint(doc_uri)
diff --git a/python/vhdl_langserver/workspace.py b/python/vhdl_langserver/workspace.py
index a2cf9db4b..9d61225ee 100644
--- a/python/vhdl_langserver/workspace.py
+++ b/python/vhdl_langserver/workspace.py
@@ -24,6 +24,7 @@ log = logging.getLogger(__name__)
class ProjectError(Exception):
"Exception raised in case of unrecoverable error in the project file."
+
def __init__(self, msg):
super().__init__()
self.msg = msg
@@ -34,13 +35,13 @@ class Workspace(object):
self._root_uri = root_uri
self._server = server
self._root_path = lsp.path_from_uri(self._root_uri)
- self._docs = {} # uri -> doc
- self._fe_map = {} # fe -> doc
+ self._docs = {} # uri -> doc
+ self._fe_map = {} # fe -> doc
self._prj = {}
self._last_linted_doc = None
errorout_memory.Install_Handler()
libghdl.thin.flags.Flag_Elocations.value = True
- #thin.Flags.Verbose.value = True
+ # thin.Flags.Verbose.value = True
# We do analysis even in case of errors.
libghdl.thin.vhdl.parse.Flag_Parse_Parenthesis.value = True
# Force analysis to get more feedback + navigation even in case
@@ -52,7 +53,7 @@ class Workspace(object):
self.read_project()
self.set_options_from_project()
libghdl.analyze_init()
- self._diags_set = set() # Documents with at least one diagnostic.
+ self._diags_set = set() # Documents with at least one diagnostic.
self.read_files_from_project()
self.gather_diagnostics(None)
@@ -89,7 +90,9 @@ class Workspace(object):
path = lsp.path_from_uri(doc_uri)
if source is None:
source = open(path).read()
- sfe = document.Document.load(source, os.path.dirname(path), os.path.basename(path))
+ sfe = document.Document.load(
+ source, os.path.dirname(path), os.path.basename(path)
+ )
return self._create_document(doc_uri, sfe)
def get_or_create_document(self, doc_uri):
@@ -143,14 +146,14 @@ class Workspace(object):
fd.close()
except OSError as err:
self._server.show_message(
- lsp.MessageType.Error,
- "cannot load {}: {}".format(name, err.strerror))
+ lsp.MessageType.Error, "cannot load {}: {}".format(name, err.strerror)
+ )
return
doc = self.create_document_from_sfe(sfe, absname)
doc.parse_document()
def read_project(self):
- prj_file = os.path.join(self.root_path, 'hdl-prj.json')
+ prj_file = os.path.join(self.root_path, "hdl-prj.json")
if not os.path.exists(prj_file):
log.info("project file %s does not exist", prj_file)
return
@@ -159,7 +162,8 @@ class Workspace(object):
except OSError as err:
self._server.show_message(
lsp.MessageType.Error,
- "cannot open project file {}: {}".format(prj_file, err.strerror))
+ "cannot open project file {}: {}".format(prj_file, err.strerror),
+ )
return
log.info("reading project file %s", prj_file)
try:
@@ -169,7 +173,9 @@ class Workspace(object):
self._server.show_message(
lsp.MessageType.Error,
"json error in project file {}:{}:{}".format(
- prj_file, e.lineno, e.colno))
+ prj_file, e.lineno, e.colno
+ ),
+ )
f.close()
def set_options_from_project(self):
@@ -178,43 +184,48 @@ class Workspace(object):
return
if not isinstance(self._prj, dict):
raise ProjectError("project file is not a dictionnary")
- opts = self._prj.get('options', None)
+ opts = self._prj.get("options", None)
if opts is None:
return
if not isinstance(opts, dict):
raise ProjectError("'options' is not a dictionnary")
- ghdl_opts = opts.get('ghdl_analysis', None)
+ ghdl_opts = opts.get("ghdl_analysis", None)
if ghdl_opts is None:
return
log.info("Using options: %s", ghdl_opts)
for opt in ghdl_opts:
- if not libghdl.set_option(opt.encode('utf-8')):
- self._server.show_message(lsp.MessageType.Error,
- "error with option: {}".format(opt))
+ if not libghdl.set_option(opt.encode("utf-8")):
+ self._server.show_message(
+ lsp.MessageType.Error, "error with option: {}".format(opt)
+ )
except ProjectError as e:
- self._server.show_message(lsp.MessageType.Error,
- "error in project file: {}".format(e.msg))
+ self._server.show_message(
+ lsp.MessageType.Error, "error in project file: {}".format(e.msg)
+ )
def read_files_from_project(self):
try:
- files = self._prj.get('files', [])
+ files = self._prj.get("files", [])
if not isinstance(files, list):
raise ProjectError("'files' is not a list")
for f in files:
if not isinstance(f, dict):
raise ProjectError("an element of 'files' is not a dict")
- name = f.get('file')
+ name = f.get("file")
if not isinstance(name, str):
raise ProjectError("a 'file' is not a string")
- lang = f.get('language', 'vhdl')
- if lang == 'vhdl':
+ lang = f.get("language", "vhdl")
+ if lang == "vhdl":
self.add_vhdl_file(name)
except ProjectError as e:
- self._server.show_message(lsp.MessageType.Error,
- "error in project file: {}".format(e.msg))
+ self._server.show_message(
+ lsp.MessageType.Error, "error in project file: {}".format(e.msg)
+ )
def get_configuration(self):
- self._server.configuration([{'scopeUri': '', 'section': 'vhdl.maxNumberOfProblems'}])
+ self._server.configuration(
+ [{"scopeUri": "", "section": "vhdl.maxNumberOfProblems"}]
+ )
def gather_diagnostics(self, doc):
# Gather messages (per file)
@@ -222,15 +233,14 @@ class Workspace(object):
diags = {}
diag = {}
for i in range(nbr_msgs):
- hdr = errorout_memory.Get_Error_Record(i+1)
- msg = errorout_memory.Get_Error_Message(i+1).decode('utf-8')
+ hdr = errorout_memory.Get_Error_Record(i + 1)
+ msg = errorout_memory.Get_Error_Message(i + 1).decode("utf-8")
if hdr.file == 0:
# Possible for error limit reached.
continue
err_range = {
- 'start': {'line': hdr.line - 1, 'character': hdr.offset},
- 'end': {'line': hdr.line - 1,
- 'character': hdr.offset + hdr.length},
+ "start": {"line": hdr.line - 1, "character": hdr.offset},
+ "end": {"line": hdr.line - 1, "character": hdr.offset + hdr.length},
}
if hdr.group <= errorout_memory.Msg_Main:
if hdr.id <= errorout.Msgid.Msgid_Note:
@@ -239,12 +249,14 @@ class Workspace(object):
severity = lsp.DiagnosticSeverity.Warning
else:
severity = lsp.DiagnosticSeverity.Error
- diag = {'source': 'ghdl',
- 'range': err_range,
- 'message': msg,
- 'severity': severity}
+ diag = {
+ "source": "ghdl",
+ "range": err_range,
+ "message": msg,
+ "severity": severity,
+ }
if hdr.group == errorout_memory.Msg_Main:
- diag['relatedInformation'] = []
+ diag["relatedInformation"] = []
fdiag = diags.get(hdr.file, None)
if fdiag is None:
diags[hdr.file] = [diag]
@@ -254,9 +266,12 @@ class Workspace(object):
assert diag
if True:
doc = self.sfe_to_document(hdr.file)
- diag['relatedInformation'].append(
- {'location': {'uri': doc.uri, 'range': err_range},
- 'message': msg})
+ diag["relatedInformation"].append(
+ {
+ "location": {"uri": doc.uri, "range": err_range},
+ "message": msg,
+ }
+ )
errorout_memory.Clear_Errors()
# Publish diagnostics
for sfe, diag in diags.items():
@@ -275,7 +290,9 @@ class Workspace(object):
# Avoid infinite recursion
antideps[unit] = None
for un in udeps:
- log.debug("obsolete %d %s", un, pyutils.name_image(nodes.Get_Identifier(un)))
+ log.debug(
+ "obsolete %d %s", un, pyutils.name_image(nodes.Get_Identifier(un))
+ )
# Recurse
self.obsolete_dependent_units(un, antideps)
if nodes.Set_Date_State(un) == nodes.Date_State.Disk:
@@ -319,7 +336,7 @@ class Workspace(object):
def apply_changes(self, doc_uri, contentChanges, new_version):
doc = self.get_document(doc_uri)
- assert doc is not None, 'try to modify a non-loaded document'
+ assert doc is not None, "try to modify a non-loaded document"
self.obsolete_doc(doc)
prev_sfe = doc._fe
for change in contentChanges:
@@ -338,15 +355,18 @@ class Workspace(object):
pass
def apply_edit(self, edit):
- return self._server.request('workspace/applyEdit', {'edit': edit})
+ return self._server.request("workspace/applyEdit", {"edit": edit})
def publish_diagnostics(self, doc_uri, diagnostics):
- self._server.notify('textDocument/publishDiagnostics',
- params={'uri': doc_uri, 'diagnostics': diagnostics})
+ self._server.notify(
+ "textDocument/publishDiagnostics",
+ params={"uri": doc_uri, "diagnostics": diagnostics},
+ )
def show_message(self, message, msg_type=lsp.MessageType.Info):
- self._server.notify('window/showMessage',
- params={'type': msg_type, 'message': message})
+ self._server.notify(
+ "window/showMessage", params={"type": msg_type, "message": message}
+ )
def declaration_to_location(self, decl):
"Convert declaration :param decl: to an LSP Location"
@@ -359,10 +379,14 @@ class Workspace(object):
return None
fe = files_map.Location_To_File(decl_loc)
doc = self.sfe_to_document(fe)
- res = {'uri': doc.uri}
+ res = {"uri": doc.uri}
nid = nodes.Get_Identifier(decl)
- res['range'] = {'start': symbols.location_to_position(fe, decl_loc),
- 'end': symbols.location_to_position(fe, decl_loc + name_table.Get_Name_Length(nid))}
+ res["range"] = {
+ "start": symbols.location_to_position(fe, decl_loc),
+ "end": symbols.location_to_position(
+ fe, decl_loc + name_table.Get_Name_Length(nid)
+ ),
+ }
return res
def goto_definition(self, doc_uri, position):
@@ -383,10 +407,14 @@ class Workspace(object):
res = []
for fe in range(1, files_map.Get_Last_Source_File_Entry() + 1):
doc = self._fe_map.get(fe, None)
- res.append({'fe': fe,
- 'uri': doc.uri if doc is not None else None,
- 'name': pyutils.name_image(files_map.Get_File_Name(fe)),
- 'dir': pyutils.name_image(files_map.Get_Directory_Name(fe))})
+ res.append(
+ {
+ "fe": fe,
+ "uri": doc.uri if doc is not None else None,
+ "name": pyutils.name_image(files_map.Get_File_Name(fe)),
+ "dir": pyutils.name_image(files_map.Get_Directory_Name(fe)),
+ }
+ )
return res
def x_get_all_entities(self):
@@ -405,7 +433,7 @@ class Workspace(object):
files = nodes.Get_Chain(files)
ents = [pyutils.name_image(nodes.Get_Identifier(e)) for e in ents]
lib_name = pyutils.name_image(nodes.Get_Identifier(lib))
- res.extend([{'name': n, 'library': lib_name} for n in ents])
+ res.extend([{"name": n, "library": lib_name} for n in ents])
lib = nodes.Get_Chain(lib)
return res
@@ -413,24 +441,33 @@ class Workspace(object):
def create_interfaces(inters):
res = []
while inters != nodes.Null_Iir:
- res.append({'name': name_table.Get_Name_Ptr(nodes.Get_Identifier(inters)).decode('latin-1')})
+ res.append(
+ {
+ "name": name_table.Get_Name_Ptr(
+ nodes.Get_Identifier(inters)
+ ).decode("latin-1")
+ }
+ )
inters = nodes.Get_Chain(inters)
return res
+
# Find library
- lib_id = name_table.Get_Identifier(library.encode('utf-8'))
+ lib_id = name_table.Get_Identifier(library.encode("utf-8"))
lib = libraries.Get_Library_No_Create(lib_id)
if lib == name_table.Null_Identifier:
return None
# Find entity
- ent_id = name_table.Get_Identifier(name.encode('utf-8'))
+ ent_id = name_table.Get_Identifier(name.encode("utf-8"))
unit = libraries.Find_Primary_Unit(lib, ent_id)
if unit == nodes.Null_Iir:
return None
ent = nodes.Get_Library_Unit(unit)
- return {'library': library,
- 'entity': name,
- 'generics': create_interfaces(nodes.Get_Generic_Chain(ent)),
- 'ports': create_interfaces(nodes.Get_Port_Chain(ent))}
+ return {
+ "library": library,
+ "entity": name,
+ "generics": create_interfaces(nodes.Get_Generic_Chain(ent)),
+ "ports": create_interfaces(nodes.Get_Port_Chain(ent)),
+ }
def compute_anti_dependences(self):
"""Return a dictionnary of anti dependencies for design unit"""