optimze Server
This commit is contained in:
+42
-28
@@ -9,6 +9,8 @@ import os
|
|||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
|
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
import operator
|
import operator
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
@@ -151,7 +153,9 @@ def inlay_hints(params: lsp.InlayHintParams):
|
|||||||
if not GLOBAL_SETTINGS.get("inlayHint", False):
|
if not GLOBAL_SETTINGS.get("inlayHint", False):
|
||||||
return []
|
return []
|
||||||
document = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
|
document = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
|
||||||
tree = LSP_SERVER.parser.parse(document.source)
|
|
||||||
|
# Reuse cached AST
|
||||||
|
tree = LSP_SERVER.get_tree(document)
|
||||||
|
|
||||||
# Merge proc signatures across files and traverse once
|
# Merge proc signatures across files and traverse once
|
||||||
merged_signatures = {}
|
merged_signatures = {}
|
||||||
@@ -177,7 +181,8 @@ def semantic_tokens(params: lsp.SemanticTokensParams):
|
|||||||
plugins = []
|
plugins = []
|
||||||
hl = _Highlighter(plugins, LSP_SERVER.poco_completion)
|
hl = _Highlighter(plugins, LSP_SERVER.poco_completion)
|
||||||
|
|
||||||
tree = LSP_SERVER.parser.parse(document.source)
|
# Reuse cached AST
|
||||||
|
tree = LSP_SERVER.get_tree(document)
|
||||||
tree.accept(hl, recurse=True)
|
tree.accept(hl, recurse=True)
|
||||||
|
|
||||||
tokens = hl.tokens()
|
tokens = hl.tokens()
|
||||||
@@ -407,33 +412,42 @@ def initialize(params: lsp.InitializeParams) -> lsp.InitializeResult:
|
|||||||
|
|
||||||
|
|
||||||
@LSP_SERVER.feature(lsp.INITIALIZED)
|
@LSP_SERVER.feature(lsp.INITIALIZED)
|
||||||
def initialized(params: lsp.InitializedParams):
|
def initialized(_params: lsp.InitializedParams):
|
||||||
root = LSP_SERVER.workspace.root_path
|
"""Kick off background indexing to avoid blocking initialization."""
|
||||||
psc_files = get_all_psc_files(pathlib.Path(root))
|
|
||||||
for psc_file in psc_files:
|
|
||||||
poco_files = read_psc_file(psc_file)
|
|
||||||
for sourced_layer in poco_files:
|
|
||||||
completion.reset()
|
|
||||||
try:
|
|
||||||
file_root = pathlib.Path(root).joinpath(sourced_layer.subfolder if sourced_layer.subfolder else "")
|
|
||||||
for tcl_file in sourced_layer.files:
|
|
||||||
filepath = pathlib.Path(file_root).joinpath(f"{tcl_file}.tcl")
|
|
||||||
if not filepath.exists():
|
|
||||||
continue
|
|
||||||
completion.reset()
|
|
||||||
document = LSP_SERVER.workspace.get_text_document(filepath.as_uri()) # filepath.read_text(encoding="utf-8")
|
|
||||||
tree = LSP_SERVER.parser.parse(document.source)
|
|
||||||
tree.accept(completion, recurse=True)
|
|
||||||
remove_existing_items(completion.custom_functions, LSP_SERVER.poco_completion)
|
|
||||||
LSP_SERVER.poco_completion[str(filepath)] = completion.custom_functions
|
|
||||||
remove_shared_keys(LSP_SERVER.proc_signatures, completion.proc_signatures)
|
|
||||||
LSP_SERVER.proc_signatures[str(filepath)] = completion.proc_signatures
|
|
||||||
# Build proc docs for this file
|
|
||||||
from tools.proc_docs import build_proc_docs
|
|
||||||
|
|
||||||
LSP_SERVER.proc_docs[str(filepath)] = build_proc_docs(tree, document.source)
|
def index_workspace():
|
||||||
except Exception as e:
|
try:
|
||||||
log_to_output(f"Fehler beim Parsen von {filepath}: {e}")
|
root = LSP_SERVER.workspace.root_path
|
||||||
|
log_to_output("Background indexing started...")
|
||||||
|
psc_files = get_all_psc_files(pathlib.Path(root))
|
||||||
|
for psc_file in psc_files:
|
||||||
|
poco_files = read_psc_file(psc_file)
|
||||||
|
for sourced_layer in poco_files:
|
||||||
|
completion.reset()
|
||||||
|
try:
|
||||||
|
file_root = pathlib.Path(root).joinpath(sourced_layer.subfolder if sourced_layer.subfolder else "")
|
||||||
|
for tcl_file in sourced_layer.files:
|
||||||
|
filepath = pathlib.Path(file_root).joinpath(f"{tcl_file}.tcl")
|
||||||
|
if not filepath.exists():
|
||||||
|
continue
|
||||||
|
completion.reset()
|
||||||
|
document = LSP_SERVER.workspace.get_text_document(filepath.as_uri())
|
||||||
|
tree = LSP_SERVER.parser.parse(document.source)
|
||||||
|
tree.accept(completion, recurse=True)
|
||||||
|
remove_existing_items(completion.custom_functions, LSP_SERVER.poco_completion)
|
||||||
|
LSP_SERVER.poco_completion[str(filepath)] = completion.custom_functions
|
||||||
|
remove_shared_keys(LSP_SERVER.proc_signatures, completion.proc_signatures)
|
||||||
|
LSP_SERVER.proc_signatures[str(filepath)] = completion.proc_signatures
|
||||||
|
from tools.proc_docs import build_proc_docs
|
||||||
|
|
||||||
|
LSP_SERVER.proc_docs[str(filepath)] = build_proc_docs(tree, document.source)
|
||||||
|
except Exception as e:
|
||||||
|
log_to_output(f"Fehler beim Parsen von {filepath}: {e}")
|
||||||
|
log_to_output("Background indexing completed.")
|
||||||
|
except Exception as e:
|
||||||
|
log_to_output(f"Background indexing failed: {e}")
|
||||||
|
|
||||||
|
threading.Thread(target=index_workspace, name="nxps-indexer", daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
@LSP_SERVER.feature(lsp.EXIT)
|
@LSP_SERVER.feature(lsp.EXIT)
|
||||||
|
|||||||
@@ -26,6 +26,37 @@ class TclLanguageServer(server.LanguageServer):
|
|||||||
self.poco_completion: dict = {}
|
self.poco_completion: dict = {}
|
||||||
self.proc_signatures: dict = {}
|
self.proc_signatures: dict = {}
|
||||||
self.proc_docs: dict = {}
|
self.proc_docs: dict = {}
|
||||||
|
# Cache: (uri, version) -> (tree, violations)
|
||||||
|
self._ast_cache = {}
|
||||||
|
|
||||||
|
def get_tree(self, document: TextDocument):
|
||||||
|
key = (document.uri, document.version)
|
||||||
|
cached = self._ast_cache.get(key)
|
||||||
|
if cached:
|
||||||
|
return cached[0]
|
||||||
|
# Parse and cache
|
||||||
|
self.parser.violations = []
|
||||||
|
tree = self.parser.parse(document.source)
|
||||||
|
violations = list(self.parser.violations)
|
||||||
|
self._ast_cache[key] = (tree, violations)
|
||||||
|
return tree
|
||||||
|
|
||||||
|
def get_tree_and_violations(self, document: TextDocument):
|
||||||
|
key = (document.uri, document.version)
|
||||||
|
cached = self._ast_cache.get(key)
|
||||||
|
if cached:
|
||||||
|
return cached
|
||||||
|
# Parse and cache
|
||||||
|
self.parser.violations = []
|
||||||
|
tree = self.parser.parse(document.source)
|
||||||
|
violations = list(self.parser.violations)
|
||||||
|
self._ast_cache[key] = (tree, violations)
|
||||||
|
return tree, violations
|
||||||
|
|
||||||
|
def clear_cache_for_uri(self, uri: str):
|
||||||
|
to_delete = [k for k in self._ast_cache.keys() if k[0] == uri]
|
||||||
|
for k in to_delete:
|
||||||
|
del self._ast_cache[k]
|
||||||
|
|
||||||
def update_poco_completion_for_file(self, document: TextDocument):
|
def update_poco_completion_for_file(self, document: TextDocument):
|
||||||
"""Update poco_completion for a specific file when it changes"""
|
"""Update poco_completion for a specific file when it changes"""
|
||||||
@@ -42,7 +73,7 @@ class TclLanguageServer(server.LanguageServer):
|
|||||||
# Parse and extract new completion items
|
# Parse and extract new completion items
|
||||||
completion.reset()
|
completion.reset()
|
||||||
try:
|
try:
|
||||||
tree = self.parser.parse(document.source)
|
tree = self.get_tree(document)
|
||||||
tree.accept(completion, recurse=True)
|
tree.accept(completion, recurse=True)
|
||||||
remove_existing_items(completion.custom_functions, self.poco_completion)
|
remove_existing_items(completion.custom_functions, self.poco_completion)
|
||||||
self.poco_completion[filepath] = completion.custom_functions
|
self.poco_completion[filepath] = completion.custom_functions
|
||||||
@@ -81,10 +112,7 @@ class TclLanguageServer(server.LanguageServer):
|
|||||||
self,
|
self,
|
||||||
document: TextDocument,
|
document: TextDocument,
|
||||||
) -> List[Violation]:
|
) -> List[Violation]:
|
||||||
violations = []
|
tree, violations = self.get_tree_and_violations(document)
|
||||||
self.parser.violations = []
|
|
||||||
tree = self.parser.parse(document.source)
|
|
||||||
violations += self.parser.violations
|
|
||||||
for checker in checks.get_checkers():
|
for checker in checks.get_checkers():
|
||||||
violations += checker.check(document.source, tree)
|
violations += checker.check(document.source, tree)
|
||||||
return violations
|
return violations
|
||||||
|
|||||||
Reference in New Issue
Block a user