Skip to content
Merged

Dev #186

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
df8593b
feat: add support for C# language server and update related configura…
v4rgas Feb 14, 2025
e5dc41a
refactor: remove unused ImplementedLsp class and clean up imports; up…
v4rgas Feb 18, 2025
29b2416
refactor: remove LspCaller class and associated code
v4rgas Feb 18, 2025
f7fc44d
refactor: rename methods in LspQueryHelper class for consistency and …
v4rgas Feb 18, 2025
8523e45
feat: add logging for node processing in ProjectGraphCreator
v4rgas Feb 18, 2025
abae83c
chore: update dependencies to use git source for multilspy and clean …
v4rgas Feb 18, 2025
1674e37
fix: handle multiple definitions in get_definition_path_for_reference…
v4rgas Feb 18, 2025
d9ac770
fix: update return statement to access uri key in definitions
v4rgas Feb 18, 2025
c98b678
refactor: remove unused methods and streamline Neo4jManager class
v4rgas Feb 19, 2025
16e621d
feat: enhance Neo4jManager initialization and add GraphBuilder for pr…
v4rgas Feb 19, 2025
1e4e459
feat: integrate logging for LSP server operations and enhance project…
v4rgas Feb 19, 2025
cdb577d
feat: add Go language support and enhance project graph creation func…
v4rgas Feb 19, 2025
a9be9d3
Merge remote-tracking branch 'blarify/feat/csharp' into dev
v4rgas Feb 19, 2025
2663aa1
fix
v4rgas Feb 19, 2025
35d788d
refactor: rename multi LSP helper methods for clarity
v4rgas Feb 19, 2025
411a470
better error handling
v4rgas Feb 19, 2025
123b561
missing shutdown
v4rgas Feb 19, 2025
e3c8199
more error handling
v4rgas Feb 20, 2025
7cfca64
chore: README
v4rgas Feb 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
This repo introduces a method to represent a local code repository as a graph structure. The objective is to allow an LLM to traverse this graph to understand the code logic and flow. Providing the LLM with the power to debug, refactor, and optimize queries.

# Supported Languages

- Python
- JavaScript
- TypeScript
- Ruby
- Go
- C#

# Example
<img src="https://raw.githubusercontent.com/blarApp/blarify/refs/heads/main/docs/visualisation.png"></img>
This graph was generated from the code in this repository.
Expand Down
12 changes: 7 additions & 5 deletions blarify/code_hierarchy/languages/FoundRelationshipScope.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from dataclasses import dataclass
from tree_sitter import Node
from blarify.graph.relationship.relationship_type import RelationshipType
from typing import Optional
from typing import Optional, TYPE_CHECKING

if TYPE_CHECKING:
from tree_sitter import Node
from blarify.graph.relationship.relationship_type import RelationshipType


@dataclass
class FoundRelationshipScope:
node_in_scope: Optional[Node]
relationship_type: RelationshipType
node_in_scope: Optional["Node"]
relationship_type: "RelationshipType"

def __str__(self) -> str:
return f"FoundRelationshipScope({self.node_in_scope}, {self.relationship_type})"
2 changes: 2 additions & 0 deletions blarify/code_hierarchy/languages/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
from .typescript_definitions import TypescriptDefinitions
from .ruby_definitions import RubyDefinitions
from .fallback_definitions import FallbackDefinitions
from .csharp_definitions import CsharpDefinitions
from .go_definitions import GoDefinitions
80 changes: 80 additions & 0 deletions blarify/code_hierarchy/languages/csharp_definitions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from blarify.code_hierarchy.languages.FoundRelationshipScope import FoundRelationshipScope
from .language_definitions import LanguageDefinitions
from blarify.graph.relationship import RelationshipType

import tree_sitter_c_sharp as tscsharp
from tree_sitter import Language, Parser

from typing import Optional, Set, Dict

from blarify.graph.node import NodeLabels
from tree_sitter import Node
from blarify.graph.node import Node as GraphNode


class CsharpDefinitions(LanguageDefinitions):
def get_language_name() -> str:
return "csharp"

def get_parsers_for_extensions() -> Dict[str, Parser]:
return {
".cs": Parser(Language(tscsharp.language())),
}

def should_create_node(node: Node) -> bool:
return LanguageDefinitions._should_create_node_base_implementation(
node,
[
"method_declaration",
"class_declaration",
"interface_declaration",
"constructor_declaration",
"record_declaration",
],
)

def get_identifier_node(node: Node) -> Node:
return LanguageDefinitions._get_identifier_node_base_implementation(node)

def get_body_node(node: Node) -> Node:
return LanguageDefinitions._get_body_node_base_implementation(node)

def get_relationship_type(node: GraphNode, node_in_point_reference: Node) -> Optional[FoundRelationshipScope]:
return CsharpDefinitions._find_relationship_type(
node_label=node.label,
node_in_point_reference=node_in_point_reference,
)

def get_node_label_from_type(type: str) -> NodeLabels:
return {
"class_declaration": NodeLabels.CLASS,
"method_declaration": NodeLabels.FUNCTION,
"interface_declaration": NodeLabels.CLASS,
"constructor_declaration": NodeLabels.FUNCTION,
"record_declaration": NodeLabels.CLASS,
}[type]

def get_language_file_extensions() -> Set[str]:
return {".cs"}

def _find_relationship_type(node_label: str, node_in_point_reference: Node) -> Optional[FoundRelationshipScope]:
relationship_types = CsharpDefinitions._get_relationship_types_by_label()
relevant_relationship_types = relationship_types.get(node_label, {})

return LanguageDefinitions._traverse_and_find_relationships(
node_in_point_reference, relevant_relationship_types
)

def _get_relationship_types_by_label() -> dict[str, RelationshipType]:
return {
NodeLabels.CLASS: {
"object_creation_expression": RelationshipType.INSTANTIATES,
"using_directive": RelationshipType.IMPORTS,
"variable_declaration": RelationshipType.TYPES,
"parameter": RelationshipType.TYPES,
"base_list": RelationshipType.INHERITS,
},
NodeLabels.FUNCTION: {
"invocation_expression": RelationshipType.CALLS,
},
}
82 changes: 82 additions & 0 deletions blarify/code_hierarchy/languages/go_definitions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from blarify.code_hierarchy.languages.FoundRelationshipScope import FoundRelationshipScope
from .language_definitions import LanguageDefinitions
from blarify.graph.relationship import RelationshipType

import tree_sitter_go as tsgo
from tree_sitter import Language, Parser

from typing import Optional, Set, Dict

from blarify.graph.node import NodeLabels
from tree_sitter import Node
from blarify.graph.node import Node as GraphNode


class GoDefinitions(LanguageDefinitions):
def get_language_name() -> str:
return "go"

def get_parsers_for_extensions() -> Dict[str, Parser]:
return {
".go": Parser(Language(tsgo.language())),
}

def should_create_node(node: Node) -> bool:
return LanguageDefinitions._should_create_node_base_implementation(
node,
["type_declaration", "method_declaration", "function_declaration"],
)

def get_identifier_node(node: Node) -> Node:
print("NODE IDENTIFIER", node.type)
if node.type == "type_declaration":
for child in node.named_children:
if child.type == "type_spec" or "type_alias":
node = child

return LanguageDefinitions._get_identifier_node_base_implementation(node)

def get_body_node(node: Node) -> Node:
if node.type == "type_declaration":
for child in node.named_children:
if child.type == "type_spec":
node = child

return LanguageDefinitions._get_body_node_base_implementation(node)

def get_relationship_type(node: GraphNode, node_in_point_reference: Node) -> Optional[FoundRelationshipScope]:
return GoDefinitions._find_relationship_type(
node_label=node.label,
node_in_point_reference=node_in_point_reference,
)

def get_node_label_from_type(type: str) -> NodeLabels:
return {
"type_declaration": NodeLabels.CLASS,
"method_declaration": NodeLabels.FUNCTION,
"function_declaration": NodeLabels.FUNCTION,
}[type]

def get_language_file_extensions() -> Set[str]:
return {".go"}

def _find_relationship_type(node_label: str, node_in_point_reference: Node) -> Optional[FoundRelationshipScope]:
relationship_types = GoDefinitions._get_relationship_types_by_label()
relevant_relationship_types = relationship_types.get(node_label, {})

return LanguageDefinitions._traverse_and_find_relationships(
node_in_point_reference, relevant_relationship_types
)

def _get_relationship_types_by_label() -> dict[str, RelationshipType]:
return {
NodeLabels.CLASS: {
"import_declaration": RelationshipType.IMPORTS,
"field_declaration": RelationshipType.TYPES,
"composite_literal": RelationshipType.INSTANTIATES,
},
NodeLabels.FUNCTION: {
"import_declaration": RelationshipType.IMPORTS,
"call_expression": RelationshipType.CALLS,
},
}
6 changes: 2 additions & 4 deletions blarify/code_hierarchy/languages/language_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ def get_identifier_node(node: Node) -> Node:
def _get_identifier_node_base_implementation(node: Node) -> Node:
if identifier := node.child_by_field_name("name"):
return identifier

raise IdentifierNodeNotFound(
f"No identifier node found for node type {node.type} at {node.start_point} - {node.end_point}"
)
error = f"No identifier node found for node type {node.type} at {node.start_point} - {node.end_point}"
raise IdentifierNodeNotFound(error)

@staticmethod
@abstractmethod
Expand Down
2 changes: 0 additions & 2 deletions blarify/code_references/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from .lsp_caller import LspCaller
from .lsp_helper import LspQueryHelper, FileExtensionNotSupported
from .implemented_lsp import ImplementedLsp
7 changes: 0 additions & 7 deletions blarify/code_references/implemented_lsp.py

This file was deleted.

Loading