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
13 changes: 13 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ jobs:
steps:
- name: Checkout your repository using git
uses: actions/checkout@v4

# Generate stdlib registry for Python 3.14
- name: Setup Python 3.14
uses: actions/setup-python@v5
with:
python-version: '3.14'

- name: Generate stdlib registry for Python 3.14
run: |
cd sourcecode-parser/tools
python generate_stdlib_registry.py --all \
--output-dir ../../docs/public/assets/registries/python3.14/stdlib/v1/

- name: Create .env file
env:
POSTHOG_WEB_ANALYTICS: ${{ secrets.POSTHOG_WEB_ANALYTICS }}
Expand Down
1 change: 1 addition & 0 deletions sourcecode-parser/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ build/
.gradle/

# Generated registries (local testing only)
# Note: Production registries are in docs/public/assets/registries/ (committed for CDN hosting)
registries/
57 changes: 40 additions & 17 deletions sourcecode-parser/graph/callgraph/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,34 @@ func BuildCallGraph(codeGraph *graph.CodeGraph, registry *ModuleRegistry, projec
// Phase 3 Task 12: Initialize attribute registry for tracking class attributes
typeEngine.Attributes = NewAttributeRegistry()

// PR #2: Load stdlib registry from local directory
stdlibLoader := &StdlibRegistryLoader{
RegistryPath: "registries/python3.14/stdlib/v1",
}
stdlibRegistry, err := stdlibLoader.LoadRegistry()
// PR #3: Detect Python version and load stdlib registry from remote CDN
pythonVersion := detectPythonVersion(projectRoot)
log.Printf("Detected Python version: %s", pythonVersion)

// Create remote registry loader
remoteLoader := NewStdlibRegistryRemote(
"https://codepathfinder.dev/assets/registries",
pythonVersion,
)

// Load manifest from CDN
err := remoteLoader.LoadManifest()
if err != nil {
log.Printf("Warning: Failed to load stdlib registry: %v", err)
log.Printf("Warning: Failed to load stdlib registry from CDN: %v", err)
// Continue without stdlib resolution - not a fatal error
} else {
// Create adapter to satisfy existing StdlibRegistry interface
stdlibRegistry := &StdlibRegistry{
Modules: make(map[string]*StdlibModule),
Manifest: remoteLoader.Manifest,
}

// The remote loader will lazy-load modules as needed
// We store a reference to it for on-demand loading
typeEngine.StdlibRegistry = stdlibRegistry
log.Printf("Loaded stdlib registry: %d modules", stdlibRegistry.ModuleCount())
typeEngine.StdlibRemote = remoteLoader

log.Printf("Loaded stdlib manifest from CDN: %d modules available", remoteLoader.ModuleCount())
}

// First, index all function definitions from the code graph
Expand Down Expand Up @@ -710,9 +727,9 @@ func resolveCallTarget(target string, importMap *ImportMap, registry *ModuleRegi
if ormFQN, resolved := ResolveORMCall(target, currentModule, registry, codeGraph); resolved {
return ormFQN, true, nil
}
// PR #2: Check stdlib registry before user project registry
if typeEngine != nil && typeEngine.StdlibRegistry != nil {
if validateStdlibFQN(fullFQN, typeEngine.StdlibRegistry) {
// PR #3: Check stdlib registry before user project registry
if typeEngine != nil && typeEngine.StdlibRemote != nil {
if validateStdlibFQN(fullFQN, typeEngine.StdlibRemote) {
return fullFQN, true, nil
}
}
Expand All @@ -735,10 +752,10 @@ func resolveCallTarget(target string, importMap *ImportMap, registry *ModuleRegi
return ormFQN, true, nil
}

// PR #2: Last resort - check if target is a stdlib call (e.g., os.path.join)
// PR #3: Last resort - check if target is a stdlib call (e.g., os.path.join)
// This handles cases where stdlib modules are imported directly (import os.path)
if typeEngine != nil && typeEngine.StdlibRegistry != nil {
if validateStdlibFQN(target, typeEngine.StdlibRegistry) {
if typeEngine != nil && typeEngine.StdlibRemote != nil {
if validateStdlibFQN(target, typeEngine.StdlibRemote) {
return target, true, nil
}
}
Expand All @@ -758,6 +775,7 @@ var stdlibModuleAliases = map[string]string{
// validateStdlibFQN checks if a fully qualified name is a stdlib function.
// Supports module.function, module.submodule.function, and module.Class patterns.
// Handles platform-specific module aliases (e.g., os.path -> posixpath).
// Uses lazy loading via remote registry to download modules on-demand.
//
// Examples:
// "os.getcwd" - returns true if os.getcwd exists in stdlib
Expand All @@ -766,12 +784,12 @@ var stdlibModuleAliases = map[string]string{
//
// Parameters:
// - fqn: fully qualified name to check
// - stdlibRegistry: stdlib registry
// - remoteLoader: remote stdlib registry loader
//
// Returns:
// - true if FQN is a stdlib function or class
func validateStdlibFQN(fqn string, stdlibRegistry *StdlibRegistry) bool {
if stdlibRegistry == nil {
func validateStdlibFQN(fqn string, remoteLoader *StdlibRegistryRemote) bool {
if remoteLoader == nil {
return false
}

Expand All @@ -797,7 +815,12 @@ func validateStdlibFQN(fqn string, stdlibRegistry *StdlibRegistry) bool {
moduleName = canonicalName
}

module := stdlibRegistry.GetModule(moduleName)
// Lazy load module from remote registry
module, err := remoteLoader.GetModule(moduleName)
if err != nil {
log.Printf("Warning: Failed to load stdlib module %s: %v", moduleName, err)
continue
}
if module == nil {
continue
}
Expand Down
Loading
Loading