# Path: langserver/symbols.py
# class SymbolKind(Enum):
#     """SymbolKind corresponds to the SymbolKind enum type found in the LSP
#     spec."""
#     File = 1
#     Module = 2
#     Namespace = 3
#     Package = 4
#     Class = 5
#     Method = 6
#     Property = 7
#     Field = 8
#     Constructor = 9
#     Enum = 10
#     Interface = 11
#     Function = 12
#     Variable = 13
#     Constant = 14
#     String = 15
#     Number = 16
#     Boolean = 17
#     Array = 18
# 
# class Symbol:
#     def __init__(self, name, kind, line, col, container=None, file=None):
#         self.name = name
#         self.kind = kind
#         self.line = line
#         self.col = col
#         self.container = container
#         self.file = file
# 
#     def score(self, query: str) -> int:
#         """Score a symbol based on how well it matches a query.
# 
#         Useful for sorting.
#         """
#         score = 0
#         if self.kind == SymbolKind.Class:
#             score += 1
#         if self.kind != SymbolKind.Variable:
#             score += 1
#         if self.container is None:
#             score += 1
#         if self.file and 'test' not in self.file:
#             score += 5
#         if query == "":
#             return score
#         min_score = score
#         l_name, l_query = self.name.lower(), query.lower()
#         if query == self.name:
#             score += 10
#         elif l_name == l_query:
#             score += 8
#         if self.name.startswith(query):
#             score += 5
#         elif l_name.startswith(l_query):
#             score += 4
#         if l_query in l_name:
#             score += 2
#         if self.container:
#             if self.container.lower().startswith(l_query):
#                 score += 2
#             if l_query == self.container.lower() + "." + l_name:
#                 score += 10
#         if self.file and self.file.lower().startswith(l_query):
#             score += 1
#         if score <= min_score:
#             score = -1
#         return score
# 
#     def json_object(self):
#         d = {
#             "name": self.name,
#             "kind": self.kind.value,
#             "location": {
#                 "uri": "file://" + self.file,
#                 "range": {
#                     "start": {
#                         "line": self.line - 1,
#                         "character": self.col,
#                     },
#                     "end": {
#                         "line": self.line - 1,
#                         "character": self.col + len(self.name),
#                     }
#                 }
#             },
#         }
#         if self.container is not None:
#             d["containerName"] = self.container
#         return d


from .symbols import SymbolKind, Symbol
import ast
import os
import logging


log = logging.getLogger(__name__)


class TargetedSymbolVisitor:
    """The purpose of this class is to take a SymbolDescriptor (typically the
    result of a preceding x-definition request) and perform a more precise
    symbol search based on the extra metadata available in the descriptor."""

    def __init__(self, name, kind, path):
        self.name = name
        self.kind = kind
        # the AST nodes for modules don't contain their name, so we have to
        # infer it from the file or folder name
        folder, file = os.path.split(path)
        if file == "__init__.py":
            self.module = os.path.basename(folder)
        else:
            basename, _ = os.path.splitext(file)
            self.module = basename

    def visit_Module(self, node, container):
        if self.kind == "module" and self.name == self.module:

# Path: langserver/symbols.py
# class SymbolKind(Enum):
#     """SymbolKind corresponds to the SymbolKind enum type found in the LSP
#     spec."""
#     File = 1
#     Module = 2
#     Namespace = 3
#     Package = 4
#     Class = 5
#     Method = 6
#     Property = 7
#     Field = 8
#     Constructor = 9
#     Enum = 10
#     Interface = 11
#     Function = 12
#     Variable = 13
#     Constant = 14
#     String = 15
#     Number = 16
#     Boolean = 17
#     Array = 18
# 
# class Symbol:
#     def __init__(self, name, kind, line, col, container=None, file=None):
#         self.name = name
#         self.kind = kind
#         self.line = line
#         self.col = col
#         self.container = container
#         self.file = file
# 
#     def score(self, query: str) -> int:
#         """Score a symbol based on how well it matches a query.
# 
#         Useful for sorting.
#         """
#         score = 0
#         if self.kind == SymbolKind.Class:
#             score += 1
#         if self.kind != SymbolKind.Variable:
#             score += 1
#         if self.container is None:
#             score += 1
#         if self.file and 'test' not in self.file:
#             score += 5
#         if query == "":
#             return score
#         min_score = score
#         l_name, l_query = self.name.lower(), query.lower()
#         if query == self.name:
#             score += 10
#         elif l_name == l_query:
#             score += 8
#         if self.name.startswith(query):
#             score += 5
#         elif l_name.startswith(l_query):
#             score += 4
#         if l_query in l_name:
#             score += 2
#         if self.container:
#             if self.container.lower().startswith(l_query):
#                 score += 2
#             if l_query == self.container.lower() + "." + l_name:
#                 score += 10
#         if self.file and self.file.lower().startswith(l_query):
#             score += 1
#         if score <= min_score:
#             score = -1
#         return score
# 
#     def json_object(self):
#         d = {
#             "name": self.name,
#             "kind": self.kind.value,
#             "location": {
#                 "uri": "file://" + self.file,
#                 "range": {
#                     "start": {
#                         "line": self.line - 1,
#                         "character": self.col,
#                     },
#                     "end": {
#                         "line": self.line - 1,
#                         "character": self.col + len(self.name),
#                     }
#                 }
#             },
#         }
#         if self.container is not None:
#             d["containerName"] = self.container
#         return d


# Path: langserver/definitions.py
from .symbols import SymbolKind, Symbol
import ast
import os
import logging



log = logging.getLogger(__name__)


class TargetedSymbolVisitor:
    """The purpose of this class is to take a SymbolDescriptor (typically the
    result of a preceding x-definition request) and perform a more precise
    symbol search based on the extra metadata available in the descriptor."""

    def __init__(self, name, kind, path):
        self.name = name
        self.kind = kind
        # the AST nodes for modules don't contain their name, so we have to
        # infer it from the file or folder name
        folder, file = os.path.split(path)
        if file == "__init__.py":
            self.module = os.path.basename(folder)
        else:
            basename, _ = os.path.splitext(file)
            self.module = basename

    def visit_Module(self, node, container):
        if self.kind == "module" and self.name == self.module:

            yield Symbol(