Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.languageServer": "None"
}
5 changes: 3 additions & 2 deletions sourcecode-parser/graph/callgraph/attribute_extraction.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
sitter "github.com/smacker/go-tree-sitter"
"github.com/smacker/go-tree-sitter/python"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/registry"
)

// ExtractClassAttributes extracts all class attributes from a Python file
Expand Down Expand Up @@ -37,7 +38,7 @@ func ExtractClassAttributes(
sourceCode []byte,
modulePath string,
typeEngine *TypeInferenceEngine,
registry *AttributeRegistry,
attrRegistry *registry.AttributeRegistry,
) error {
// Parse file with tree-sitter
parser := sitter.NewParser()
Expand Down Expand Up @@ -94,7 +95,7 @@ func ExtractClassAttributes(
classAttrs.Attributes = attributeMap

// Add to registry
registry.AddClassAttributes(classAttrs)
attrRegistry.AddClassAttributes(classAttrs)
}

return nil
Expand Down
93 changes: 6 additions & 87 deletions sourcecode-parser/graph/callgraph/attribute_registry.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package callgraph

import (
"sync"

"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/core"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/registry"
)

// Deprecated: Use core.ClassAttribute instead.
Expand All @@ -14,92 +13,12 @@ type ClassAttribute = core.ClassAttribute
// This alias will be removed in a future version.
type ClassAttributes = core.ClassAttributes

// AttributeRegistry is the global registry of class attributes
// It provides thread-safe access to class attribute information.
type AttributeRegistry struct {
Classes map[string]*ClassAttributes // Map from class FQN to class attributes
mu sync.RWMutex // Protects concurrent access
}
// Deprecated: Use registry.AttributeRegistry instead.
// This alias will be removed in a future version.
type AttributeRegistry = registry.AttributeRegistry

// NewAttributeRegistry creates a new empty AttributeRegistry.
// Deprecated: Use registry.NewAttributeRegistry instead.
func NewAttributeRegistry() *AttributeRegistry {
return &AttributeRegistry{
Classes: make(map[string]*ClassAttributes),
}
}

// GetClassAttributes retrieves attributes for a given class FQN
// Returns nil if class is not in registry.
func (ar *AttributeRegistry) GetClassAttributes(classFQN string) *ClassAttributes {
ar.mu.RLock()
defer ar.mu.RUnlock()
return ar.Classes[classFQN]
}

// GetAttribute retrieves a specific attribute from a class
// Returns nil if class or attribute is not found.
func (ar *AttributeRegistry) GetAttribute(classFQN, attrName string) *ClassAttribute {
ar.mu.RLock()
defer ar.mu.RUnlock()

classAttrs, exists := ar.Classes[classFQN]
if !exists || classAttrs == nil {
return nil
}

return classAttrs.Attributes[attrName]
}

// AddClassAttributes adds or updates attributes for a class
// Thread-safe for concurrent modifications.
func (ar *AttributeRegistry) AddClassAttributes(classAttrs *ClassAttributes) {
ar.mu.Lock()
defer ar.mu.Unlock()
ar.Classes[classAttrs.ClassFQN] = classAttrs
}

// AddAttribute adds a single attribute to a class
// Creates the ClassAttributes entry if it doesn't exist.
func (ar *AttributeRegistry) AddAttribute(classFQN string, attr *ClassAttribute) {
ar.mu.Lock()
defer ar.mu.Unlock()

classAttrs, exists := ar.Classes[classFQN]
if !exists {
classAttrs = &ClassAttributes{
ClassFQN: classFQN,
Attributes: make(map[string]*ClassAttribute),
Methods: []string{},
}
ar.Classes[classFQN] = classAttrs
}

classAttrs.Attributes[attr.Name] = attr
}

// HasClass checks if a class is registered.
func (ar *AttributeRegistry) HasClass(classFQN string) bool {
ar.mu.RLock()
defer ar.mu.RUnlock()
_, exists := ar.Classes[classFQN]
return exists
}

// GetAllClasses returns a list of all registered class FQNs.
func (ar *AttributeRegistry) GetAllClasses() []string {
ar.mu.RLock()
defer ar.mu.RUnlock()

classes := make([]string, 0, len(ar.Classes))
for classFQN := range ar.Classes {
classes = append(classes, classFQN)
}
return classes
}

// Size returns the number of registered classes.
func (ar *AttributeRegistry) Size() int {
ar.mu.RLock()
defer ar.mu.RUnlock()
return len(ar.Classes)
return registry.NewAttributeRegistry()
}
7 changes: 4 additions & 3 deletions sourcecode-parser/graph/callgraph/attribute_resolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/registry"
)

// FailureStats tracks why attribute chain resolution fails.
Expand Down Expand Up @@ -63,7 +64,7 @@ func ResolveSelfAttributeCall(
target string,
callerFQN string,
typeEngine *TypeInferenceEngine,
builtins *BuiltinRegistry,
builtins *registry.BuiltinRegistry,
callGraph *CallGraph,
) (string, bool, *TypeInfo) {
attributeFailureStats.TotalAttempts++
Expand Down Expand Up @@ -228,7 +229,7 @@ func PrintAttributeFailureStats() {
//
// Returns:
// - class FQN if found, empty string otherwise
func findClassContainingMethod(methodFQN string, registry *AttributeRegistry) string {
func findClassContainingMethod(methodFQN string, registry *registry.AttributeRegistry) string {
// Extract method name from FQN (last part after final dot)
methodName := methodFQN
if lastDot := strings.LastIndex(methodFQN, "."); lastDot != -1 {
Expand Down Expand Up @@ -269,7 +270,7 @@ func findClassContainingMethod(methodFQN string, registry *AttributeRegistry) st
// - moduleRegistry: module registry for resolving class names
// - codeGraph: code graph for finding class definitions
func ResolveAttributePlaceholders(
registry *AttributeRegistry,
registry *registry.AttributeRegistry,
typeEngine *TypeInferenceEngine,
moduleRegistry *ModuleRegistry,
codeGraph *graph.CodeGraph,
Expand Down
5 changes: 3 additions & 2 deletions sourcecode-parser/graph/callgraph/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

sitter "github.com/smacker/go-tree-sitter"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph"
cgregistry "github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/registry"
)

// ImportMapCache provides thread-safe caching of ImportMap instances.
Expand Down Expand Up @@ -142,10 +143,10 @@ func BuildCallGraph(codeGraph *graph.CodeGraph, registry *ModuleRegistry, projec

// Initialize type inference engine
typeEngine := NewTypeInferenceEngine(registry)
typeEngine.Builtins = NewBuiltinRegistry()
typeEngine.Builtins = cgregistry.NewBuiltinRegistry()

// Phase 3 Task 12: Initialize attribute registry for tracking class attributes
typeEngine.Attributes = NewAttributeRegistry()
typeEngine.Attributes = cgregistry.NewAttributeRegistry()

// PR #3: Detect Python version and load stdlib registry from remote CDN
pythonVersion := detectPythonVersion(projectRoot)
Expand Down
Loading
Loading