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
10 changes: 6 additions & 4 deletions sourcecode-parser/cmd/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (
sarif "github.com/owenrumney/go-sarif/v2/sarif"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/dsl"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/builder"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/core"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/registry"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -53,15 +55,15 @@ Examples:

// Build module registry
log.Printf("Building module registry...\n")
registry, err := callgraph.BuildModuleRegistry(projectPath)
moduleRegistry, err := registry.BuildModuleRegistry(projectPath)
if err != nil {
log.Printf("Warning: failed to build module registry: %v\n", err)
registry = callgraph.NewModuleRegistry()
moduleRegistry = core.NewModuleRegistry()
}

// Build callgraph
log.Printf("Building callgraph...\n")
cg, err := callgraph.BuildCallGraph(codeGraph, registry, projectPath)
cg, err := builder.BuildCallGraph(codeGraph, moduleRegistry, projectPath)
if err != nil {
return fmt.Errorf("failed to build callgraph: %w", err)
}
Expand Down
10 changes: 6 additions & 4 deletions sourcecode-parser/cmd/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (

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

Expand Down Expand Up @@ -45,15 +47,15 @@ Examples:

// Build module registry
log.Printf("Building module registry...\n")
registry, err := callgraph.BuildModuleRegistry(projectPath)
moduleRegistry, err := registry.BuildModuleRegistry(projectPath)
if err != nil {
log.Printf("Warning: failed to build module registry: %v\n", err)
registry = callgraph.NewModuleRegistry()
moduleRegistry = core.NewModuleRegistry()
}

// Build callgraph
log.Printf("Building callgraph...\n")
cg, err := callgraph.BuildCallGraph(codeGraph, registry, projectPath)
cg, err := builder.BuildCallGraph(codeGraph, moduleRegistry, projectPath)
if err != nil {
return fmt.Errorf("failed to build callgraph: %w", err)
}
Expand Down
9 changes: 6 additions & 3 deletions sourcecode-parser/cmd/resolution_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import (

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

// Note: callgraph.InitializeCallGraph is used from the callgraph root package integration

var resolutionReportCmd = &cobra.Command{
Use: "resolution-report",
Short: "Generate a diagnostic report on call resolution statistics",
Expand Down Expand Up @@ -79,7 +82,7 @@ type resolutionStatistics struct {
FailuresByReason map[string]int // Category -> count
PatternCounts map[string]int // Target pattern -> count
FrameworkCounts map[string]int // Framework prefix -> count (for external_framework category)
UnresolvedByFQN map[string]callgraph.CallSite // For detailed inspection
UnresolvedByFQN map[string]core.CallSite // For detailed inspection

// Phase 2: Type inference statistics
TypeInferenceResolved int // Calls resolved via type inference
Expand All @@ -100,12 +103,12 @@ type resolutionStatistics struct {
}

// aggregateResolutionStatistics analyzes the call graph and collects statistics.
func aggregateResolutionStatistics(cg *callgraph.CallGraph) *resolutionStatistics {
func aggregateResolutionStatistics(cg *core.CallGraph) *resolutionStatistics {
stats := &resolutionStatistics{
FailuresByReason: make(map[string]int),
PatternCounts: make(map[string]int),
FrameworkCounts: make(map[string]int),
UnresolvedByFQN: make(map[string]callgraph.CallSite),
UnresolvedByFQN: make(map[string]core.CallSite),
TypesBySource: make(map[string]int),
ConfidenceDistribution: make(map[string]int),
StdlibByModule: make(map[string]int),
Expand Down
22 changes: 11 additions & 11 deletions sourcecode-parser/cmd/resolution_report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package cmd
import (
"testing"

"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/core"
"github.com/stretchr/testify/assert"
)

Expand All @@ -12,31 +12,31 @@ import (

func TestAggregateResolutionStatistics(t *testing.T) {
// Create a mock call graph with various call sites
cg := callgraph.NewCallGraph()
cg := core.NewCallGraph()

// Add resolved call sites
cg.AddCallSite("test.func1", callgraph.CallSite{
cg.AddCallSite("test.func1", core.CallSite{
Target: "print",
Resolved: true,
TargetFQN: "builtins.print",
})

// Add unresolved call sites with different failure reasons
cg.AddCallSite("test.func2", callgraph.CallSite{
cg.AddCallSite("test.func2", core.CallSite{
Target: "models.ForeignKey",
Resolved: false,
TargetFQN: "django.db.models.ForeignKey",
FailureReason: "external_framework",
})

cg.AddCallSite("test.func3", callgraph.CallSite{
cg.AddCallSite("test.func3", core.CallSite{
Target: "Task.objects.filter",
Resolved: false,
TargetFQN: "tasks.models.Task.objects.filter",
FailureReason: "orm_pattern",
})

cg.AddCallSite("test.func4", callgraph.CallSite{
cg.AddCallSite("test.func4", core.CallSite{
Target: "response.json",
Resolved: false,
TargetFQN: "response.json",
Expand Down Expand Up @@ -161,26 +161,26 @@ func TestDetermineStdlibType(t *testing.T) {

func TestAggregateResolutionStatistics_WithStdlib(t *testing.T) {
// Create a mock call graph with stdlib call sites
cg := callgraph.NewCallGraph()
cg := core.NewCallGraph()

// Add stdlib resolved via builtin registry
cg.AddCallSite("test.func1", callgraph.CallSite{
cg.AddCallSite("test.func1", core.CallSite{
Target: "getcwd",
Resolved: true,
TargetFQN: "os.getcwd",
TypeSource: "builtin",
})

// Add stdlib resolved via annotation
cg.AddCallSite("test.func2", callgraph.CallSite{
cg.AddCallSite("test.func2", core.CallSite{
Target: "dumps",
Resolved: true,
TargetFQN: "json.dumps",
TypeSource: "stdlib_annotation",
})

// Add stdlib resolved via type inference
cg.AddCallSite("test.func3", callgraph.CallSite{
cg.AddCallSite("test.func3", core.CallSite{
Target: "Path",
Resolved: true,
TargetFQN: "pathlib.Path",
Expand All @@ -189,7 +189,7 @@ func TestAggregateResolutionStatistics_WithStdlib(t *testing.T) {
})

// Add non-stdlib resolved call
cg.AddCallSite("test.func4", callgraph.CallSite{
cg.AddCallSite("test.func4", core.CallSite{
Target: "myfunction",
Resolved: true,
TargetFQN: "myproject.utils.myfunction",
Expand Down
12 changes: 7 additions & 5 deletions sourcecode-parser/cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (

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

Expand Down Expand Up @@ -52,16 +54,16 @@ Examples:

// Step 2: Build module registry
log.Printf("Building module registry...\n")
registry, err := callgraph.BuildModuleRegistry(projectPath)
moduleRegistry, err := registry.BuildModuleRegistry(projectPath)
if err != nil {
log.Printf("Warning: failed to build module registry: %v\n", err)
// Create empty registry as fallback
registry = callgraph.NewModuleRegistry()
moduleRegistry = core.NewModuleRegistry()
}

// Step 3: Build callgraph
log.Printf("Building callgraph...\n")
cg, err := callgraph.BuildCallGraph(codeGraph, registry, projectPath)
cg, err := builder.BuildCallGraph(codeGraph, moduleRegistry, projectPath)
if err != nil {
return fmt.Errorf("failed to build callgraph: %w", err)
}
Expand Down Expand Up @@ -105,7 +107,7 @@ Examples:
},
}

func countTotalCallSites(cg *callgraph.CallGraph) int {
func countTotalCallSites(cg *core.CallGraph) int {
total := 0
for _, sites := range cg.CallSites {
total += len(sites)
Expand Down
20 changes: 10 additions & 10 deletions sourcecode-parser/cmd/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"testing"

"github.com/shivasurya/code-pathfinder/sourcecode-parser/dsl"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/core"
"github.com/stretchr/testify/assert"
)

Expand All @@ -25,28 +25,28 @@ func createTestRuleScan(id, name, severity, cwe, owasp, description string) dsl.

func TestCountTotalCallSites(t *testing.T) {
t.Run("counts call sites across all functions", func(t *testing.T) {
cg := callgraph.NewCallGraph()
cg.CallSites["func1"] = []callgraph.CallSite{
{Target: "foo", Location: callgraph.Location{Line: 10}},
{Target: "bar", Location: callgraph.Location{Line: 20}},
cg := core.NewCallGraph()
cg.CallSites["func1"] = []core.CallSite{
{Target: "foo", Location: core.Location{Line: 10}},
{Target: "bar", Location: core.Location{Line: 20}},
}
cg.CallSites["func2"] = []callgraph.CallSite{
{Target: "baz", Location: callgraph.Location{Line: 30}},
cg.CallSites["func2"] = []core.CallSite{
{Target: "baz", Location: core.Location{Line: 30}},
}

total := countTotalCallSites(cg)
assert.Equal(t, 3, total)
})

t.Run("returns zero for empty callgraph", func(t *testing.T) {
cg := callgraph.NewCallGraph()
cg := core.NewCallGraph()
total := countTotalCallSites(cg)
assert.Equal(t, 0, total)
})

t.Run("handles function with no call sites", func(t *testing.T) {
cg := callgraph.NewCallGraph()
cg.CallSites["func1"] = []callgraph.CallSite{}
cg := core.NewCallGraph()
cg.CallSites["func1"] = []core.CallSite{}
total := countTotalCallSites(cg)
assert.Equal(t, 0, total)
})
Expand Down
12 changes: 7 additions & 5 deletions sourcecode-parser/diagnostic/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"strings"

sitter "github.com/smacker/go-tree-sitter"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/analysis/taint"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/core"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/extraction"
)

// FunctionTaintResult represents the structured taint analysis result for a single function.
Expand Down Expand Up @@ -82,7 +84,7 @@ func AnalyzeSingleFunction(

// Parse function source code
sourceCode := []byte(fn.SourceCode)
tree, err := callgraph.ParsePythonFile(sourceCode)
tree, err := extraction.ParsePythonFile(sourceCode)
if err != nil {
result.AnalysisError = true
result.ErrorMessage = fmt.Sprintf("Parse error: %v", err)
Expand All @@ -98,18 +100,18 @@ func AnalyzeSingleFunction(
}

// Extract statements (using existing logic from statement_extraction.go)
statements, err := callgraph.ExtractStatements(fn.FilePath, sourceCode, functionNode)
statements, err := extraction.ExtractStatements(fn.FilePath, sourceCode, functionNode)
if err != nil {
result.AnalysisError = true
result.ErrorMessage = fmt.Sprintf("Statement extraction error: %v", err)
return result, nil
}

// Build def-use chains (using existing logic from statement.go)
defUseChain := callgraph.BuildDefUseChains(statements)
defUseChain := core.BuildDefUseChains(statements)

// Run taint analysis (using existing logic from taint.go)
taintSummary := callgraph.AnalyzeIntraProceduralTaint(
taintSummary := taint.AnalyzeIntraProceduralTaint(
fn.FQN,
statements,
defUseChain,
Expand Down
4 changes: 2 additions & 2 deletions sourcecode-parser/diagnostic/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package diagnostic
import (
"testing"

"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph"
"github.com/shivasurya/code-pathfinder/sourcecode-parser/graph/callgraph/extraction"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -131,7 +131,7 @@ def function_two():
pass
`)

tree, err := callgraph.ParsePythonFile(sourceCode)
tree, err := extraction.ParsePythonFile(sourceCode)
require.NoError(t, err)
require.NotNil(t, tree)

Expand Down
16 changes: 8 additions & 8 deletions sourcecode-parser/dsl/call_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ package dsl
import (
"strings"

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

// CallMatcherExecutor executes call_matcher IR against callgraph.
type CallMatcherExecutor struct {
IR *CallMatcherIR
CallGraph *callgraph.CallGraph
CallGraph *core.CallGraph
}

// NewCallMatcherExecutor creates a new executor.
func NewCallMatcherExecutor(ir *CallMatcherIR, cg *callgraph.CallGraph) *CallMatcherExecutor {
func NewCallMatcherExecutor(ir *CallMatcherIR, cg *core.CallGraph) *CallMatcherExecutor {
return &CallMatcherExecutor{
IR: ir,
CallGraph: cg,
Expand All @@ -33,8 +33,8 @@ func NewCallMatcherExecutor(ir *CallMatcherIR, cg *callgraph.CallGraph) *CallMat
// C = avg call sites per function (~5-10)
// P = number of patterns (~2-5)
// Typical: 1000 functions * 7 calls * 3 patterns = 21,000 comparisons (fast!)
func (e *CallMatcherExecutor) Execute() []callgraph.CallSite {
matches := []callgraph.CallSite{}
func (e *CallMatcherExecutor) Execute() []core.CallSite {
matches := []core.CallSite{}

// Iterate over all functions' call sites
for _, callSites := range e.CallGraph.CallSites {
Expand All @@ -49,7 +49,7 @@ func (e *CallMatcherExecutor) Execute() []callgraph.CallSite {
}

// matchesCallSite checks if a call site matches any pattern.
func (e *CallMatcherExecutor) matchesCallSite(cs *callgraph.CallSite) bool {
func (e *CallMatcherExecutor) matchesCallSite(cs *core.CallSite) bool {
target := cs.Target

for _, pattern := range e.IR.Patterns {
Expand Down Expand Up @@ -103,7 +103,7 @@ func (e *CallMatcherExecutor) matchesPattern(target, pattern string) bool {

// CallMatchResult represents a match with additional context.
type CallMatchResult struct {
CallSite callgraph.CallSite
CallSite core.CallSite
MatchedBy string // Which pattern matched
FunctionFQN string // Which function contains this call
SourceFile string // Which file
Expand Down Expand Up @@ -132,7 +132,7 @@ func (e *CallMatcherExecutor) ExecuteWithContext() []CallMatchResult {
}

// getMatchedPattern returns which pattern matched (or empty string if no match).
func (e *CallMatcherExecutor) getMatchedPattern(cs *callgraph.CallSite) string {
func (e *CallMatcherExecutor) getMatchedPattern(cs *core.CallSite) string {
for _, pattern := range e.IR.Patterns {
if e.matchesPattern(cs.Target, pattern) {
return pattern
Expand Down
Loading
Loading