optimze Server

This commit is contained in:
Christoph Brandau
2025-08-12 07:48:05 +02:00
parent c0635e48ea
commit 7263b6f530
2 changed files with 75 additions and 33 deletions
+19 -5
View File
@@ -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,8 +412,13 @@ 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):
"""Kick off background indexing to avoid blocking initialization."""
def index_workspace():
try:
root = LSP_SERVER.workspace.root_path root = LSP_SERVER.workspace.root_path
log_to_output("Background indexing started...")
psc_files = get_all_psc_files(pathlib.Path(root)) psc_files = get_all_psc_files(pathlib.Path(root))
for psc_file in psc_files: for psc_file in psc_files:
poco_files = read_psc_file(psc_file) poco_files = read_psc_file(psc_file)
@@ -421,19 +431,23 @@ def initialized(params: lsp.InitializedParams):
if not filepath.exists(): if not filepath.exists():
continue continue
completion.reset() completion.reset()
document = LSP_SERVER.workspace.get_text_document(filepath.as_uri()) # filepath.read_text(encoding="utf-8") document = LSP_SERVER.workspace.get_text_document(filepath.as_uri())
tree = LSP_SERVER.parser.parse(document.source) tree = LSP_SERVER.parser.parse(document.source)
tree.accept(completion, recurse=True) tree.accept(completion, recurse=True)
remove_existing_items(completion.custom_functions, LSP_SERVER.poco_completion) remove_existing_items(completion.custom_functions, LSP_SERVER.poco_completion)
LSP_SERVER.poco_completion[str(filepath)] = completion.custom_functions LSP_SERVER.poco_completion[str(filepath)] = completion.custom_functions
remove_shared_keys(LSP_SERVER.proc_signatures, completion.proc_signatures) remove_shared_keys(LSP_SERVER.proc_signatures, completion.proc_signatures)
LSP_SERVER.proc_signatures[str(filepath)] = 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 from tools.proc_docs import build_proc_docs
LSP_SERVER.proc_docs[str(filepath)] = build_proc_docs(tree, document.source) LSP_SERVER.proc_docs[str(filepath)] = build_proc_docs(tree, document.source)
except Exception as e: except Exception as e:
log_to_output(f"Fehler beim Parsen von {filepath}: {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)
+33 -5
View File
@@ -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