Skip to content

Commit 0efb89f

Browse files
committed
🔥 REFACTOR: Implement FrameworkEnricher pattern for PHP
- Introduce FrameworkEnricher interface in core PHP analyzer - Isolate Laravel and WordPress specific analysis into enricher.go - Resolve plugin overhead with blank imports on run/test files - Maintain lazy-loading decoupled structure to prevent import cycles
1 parent 7ed1be3 commit 0efb89f

5 files changed

Lines changed: 109 additions & 1 deletion

File tree

internal/daemon/run.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/html"
2828
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/javascript"
2929
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/php"
30+
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/php/laravel"
31+
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/php/wordpress"
3032
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/python"
3133
"github.com/doITmagic/rag-code-mcp/pkg/storage"
3234
"github.com/modelcontextprotocol/go-sdk/mcp"

internal/service/tools/tests/tools_suite_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import (
44
"testing"
55

66
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/go"
7+
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/javascript"
78
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/php"
9+
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/php/laravel"
10+
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/php/wordpress"
811
_ "github.com/doITmagic/rag-code-mcp/pkg/parser/python"
912

1013
. "github.com/onsi/ginkgo/v2"

pkg/parser/php/laravel/enricher.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package laravel
2+
3+
import (
4+
"github.com/doITmagic/rag-code-mcp/pkg/parser/php"
5+
)
6+
7+
// Enricher implements the php.FrameworkEnricher interface for Laravel analysis
8+
type Enricher struct {
9+
adapter *Adapter
10+
}
11+
12+
func init() {
13+
php.RegisterEnricher(&Enricher{
14+
adapter: NewAdapter(),
15+
})
16+
}
17+
18+
// IsApplicable checks if the parsed paths correspond to a Laravel project
19+
func (e *Enricher) IsApplicable(ca *php.CodeAnalyzer, paths []string) bool {
20+
return ca.IsLaravelProject()
21+
}
22+
23+
// Enrich receives the base PHP chunks and analyzed packages and returns chunks merged with Laravel specifics
24+
func (e *Enricher) Enrich(ca *php.CodeAnalyzer, packages []*php.PackageInfo, paths []string, chunks []php.CodeChunk) []php.CodeChunk {
25+
// Run Laravel-specific package analysis for Controllers and Eloquent Models
26+
for _, pkg := range packages {
27+
analyzer := NewAnalyzer(pkg)
28+
info := analyzer.Analyze()
29+
30+
// Enrich existing chunks with Laravel context (table, fillable, api routes)
31+
e.adapter.enrichChunks(chunks, info)
32+
}
33+
34+
// Analyze Routes (these are handled separately since they are mostly top level closures inside routes/)
35+
routeFiles := e.adapter.findRouteFiles(paths)
36+
if len(routeFiles) > 0 {
37+
routeAnalyzer := NewRouteAnalyzer()
38+
routes, err := routeAnalyzer.Analyze(routeFiles)
39+
if err == nil {
40+
routeChunks := e.adapter.convertRoutesToChunks(routes)
41+
chunks = append(chunks, routeChunks...)
42+
}
43+
}
44+
45+
return chunks
46+
}

pkg/parser/php/php_analyzer.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ import (
1010
pkgParser "github.com/doITmagic/rag-code-mcp/pkg/parser"
1111
)
1212

13+
// FrameworkEnricher defines an interface for adding framework-specific parsing (e.g., Laravel, WordPress).
14+
type FrameworkEnricher interface {
15+
IsApplicable(ca *CodeAnalyzer, paths []string) bool
16+
Enrich(ca *CodeAnalyzer, packages []*PackageInfo, paths []string, chunks []CodeChunk) []CodeChunk
17+
}
18+
19+
var enrichers []FrameworkEnricher
20+
21+
// RegisterEnricher adds a framework-specific enricher to the PHP parser.
22+
func RegisterEnricher(e FrameworkEnricher) {
23+
enrichers = append(enrichers, e)
24+
}
25+
1326
func init() {
1427
pkgParser.Register(NewAnalyzer())
1528
}
@@ -38,11 +51,22 @@ func (a *Analyzer) CanHandle(filePath string) bool {
3851

3952
// Analyze extracts symbols from a file or directory.
4053
func (a *Analyzer) Analyze(ctx context.Context, path string) (*pkgParser.Result, error) {
41-
chunks, err := a.codeAnalyzer.AnalyzePaths([]string{path})
54+
paths := []string{path}
55+
chunks, err := a.codeAnalyzer.AnalyzePaths(paths)
4256
if err != nil {
4357
return nil, err
4458
}
4559

60+
// Fetch packages analyzed by the core PHP parser
61+
packages := a.codeAnalyzer.GetPackages()
62+
63+
// Run all registered framework enrichers
64+
for _, enricher := range enrichers {
65+
if enricher.IsApplicable(a.codeAnalyzer, paths) {
66+
chunks = enricher.Enrich(a.codeAnalyzer, packages, paths, chunks)
67+
}
68+
}
69+
4670
// If no symbols found and the file is in a routes/ directory,
4771
// try extracting Route::* calls as symbols (Laravel convention).
4872
if len(chunks) == 0 && isRouteFile(path) {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package wordpress
2+
3+
import "github.com/doITmagic/rag-code-mcp/pkg/parser/php"
4+
5+
// Enricher implements the php.FrameworkEnricher interface for WordPress analysis
6+
type Enricher struct {
7+
analyzer *Analyzer
8+
}
9+
10+
func init() {
11+
php.RegisterEnricher(&Enricher{
12+
analyzer: NewAnalyzer(),
13+
})
14+
}
15+
16+
// IsApplicable checks if the parsed paths correspond to a WordPress project
17+
func (e *Enricher) IsApplicable(ca *php.CodeAnalyzer, paths []string) bool {
18+
return IsWordPressProject(paths)
19+
}
20+
21+
// Enrich receives the base PHP chunks and analyzed packages and returns chunks merged with WordPress specifics
22+
func (e *Enricher) Enrich(ca *php.CodeAnalyzer, packages []*php.PackageInfo, paths []string, chunks []php.CodeChunk) []php.CodeChunk {
23+
// Reusing logic from wordpress.Analyzer
24+
wpInfo := e.analyzer.analyzeWordPress(packages, paths)
25+
26+
// Enrich existing basic PHP chunks with WP info (e.g. marking Widgets)
27+
e.analyzer.enrichChunks(chunks, wpInfo)
28+
29+
// Extract new specific chunks like Hooks, Blocks, Shortcodes, CPTs
30+
wpChunks := e.analyzer.convertToChunks(wpInfo)
31+
32+
return append(chunks, wpChunks...)
33+
}

0 commit comments

Comments
 (0)