mcp-code-context 2.1.3 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.io/RULES.md +12 -0
- package/CHANGELOG.md +118 -58
- package/CONTRIBUTING.md +243 -0
- package/README.md +58 -7
- package/RELEASE_NOTES_v2.2.0.md +286 -0
- package/RELEASE_NOTES_v2.3.0.md +228 -0
- package/RELEASE_NOTES_v2.3.1.md +110 -0
- package/dist/src/ast/writers/safeRename.d.ts +14 -0
- package/dist/src/ast/writers/safeRename.js +258 -0
- package/dist/src/ast/writers/safeRename.js.map +1 -0
- package/dist/src/ast/writers/symbolWriter.d.ts +2 -0
- package/dist/src/ast/writers/symbolWriter.js +9 -14
- package/dist/src/ast/writers/symbolWriter.js.map +1 -1
- package/dist/src/cache/astCache.d.ts +33 -0
- package/dist/src/cache/astCache.js +113 -0
- package/dist/src/cache/astCache.js.map +1 -0
- package/dist/src/handlers/readHandlers.d.ts +70 -0
- package/dist/src/handlers/readHandlers.js +431 -0
- package/dist/src/handlers/readHandlers.js.map +1 -0
- package/dist/src/handlers/utilHandlers.d.ts +31 -0
- package/dist/src/handlers/utilHandlers.js +69 -0
- package/dist/src/handlers/utilHandlers.js.map +1 -0
- package/dist/src/handlers/writeHandlers.d.ts +57 -0
- package/dist/src/handlers/writeHandlers.js +475 -0
- package/dist/src/handlers/writeHandlers.js.map +1 -0
- package/dist/src/index.d.ts +6 -107
- package/dist/src/index.js +147 -965
- package/dist/src/index.js.map +1 -1
- package/dist/src/tools/readFileLines.d.ts +26 -0
- package/dist/src/tools/readFileLines.js +77 -0
- package/dist/src/tools/readFileLines.js.map +1 -0
- package/dist/src/tools/searchCodePattern.d.ts +32 -0
- package/dist/src/tools/searchCodePattern.js +80 -0
- package/dist/src/tools/searchCodePattern.js.map +1 -0
- package/dist/src/utils/arrayUtils.d.ts +12 -0
- package/dist/src/utils/arrayUtils.js +27 -0
- package/dist/src/utils/arrayUtils.js.map +1 -0
- package/dist/src/utils/backupManager.d.ts +13 -6
- package/dist/src/utils/backupManager.js +73 -8
- package/dist/src/utils/backupManager.js.map +1 -1
- package/dist/src/utils/constants.d.ts +46 -0
- package/dist/src/utils/constants.js +112 -0
- package/dist/src/utils/constants.js.map +1 -0
- package/dist/src/utils/ignoreManager.d.ts +8 -0
- package/dist/src/utils/ignoreManager.js +49 -0
- package/dist/src/utils/ignoreManager.js.map +1 -1
- package/dist/src/utils/normalization.d.ts +49 -0
- package/dist/src/utils/normalization.js +173 -0
- package/dist/src/utils/normalization.js.map +1 -0
- package/dist/src/utils/projectRoot.d.ts +17 -0
- package/dist/src/utils/projectRoot.js +42 -0
- package/dist/src/utils/projectRoot.js.map +1 -0
- package/dist/src/utils/secureValidation.d.ts +15 -0
- package/dist/src/utils/secureValidation.js +41 -0
- package/dist/src/utils/secureValidation.js.map +1 -0
- package/dist/src/utils/transactionManager.d.ts +45 -0
- package/dist/src/utils/transactionManager.js +102 -0
- package/dist/src/utils/transactionManager.js.map +1 -0
- package/dist/src/utils/validation.d.ts +87 -0
- package/dist/src/utils/validation.js +231 -0
- package/dist/src/utils/validation.js.map +1 -0
- package/docs/ARCHITECTURE.md +300 -0
- package/docs/architecture/ADR-001-modular-handlers.md +119 -0
- package/llms.txt +62 -7
- package/package.json +5 -5
- package/AGENT_INSTRUCTIONS.md +0 -135
- package/DEPLOYMENT_INSTRUCTIONS.md +0 -110
- package/dist/src/tests/test-confirmation-flow.d.ts +0 -1
- package/dist/src/tests/test-confirmation-flow.js +0 -43
- package/dist/src/tests/test-confirmation-flow.js.map +0 -1
- package/dist/tests/debug-replace.d.ts +0 -1
- package/dist/tests/debug-replace.js +0 -17
- package/dist/tests/debug-replace.js.map +0 -1
- package/dist/tests/test-confirmation-flow.d.ts +0 -1
- package/dist/tests/test-confirmation-flow.js +0 -43
- package/dist/tests/test-confirmation-flow.js.map +0 -1
- package/dist/tests/test-dart.d.ts +0 -1
- package/dist/tests/test-dart.js +0 -242
- package/dist/tests/test-dart.js.map +0 -1
- package/dist/tests/test-php-ast.d.ts +0 -1
- package/dist/tests/test-php-ast.js +0 -152
- package/dist/tests/test-php-ast.js.map +0 -1
- package/dist/tests/test-php.d.ts +0 -1
- package/dist/tests/test-php.js +0 -234
- package/dist/tests/test-php.js.map +0 -1
- package/dist/tests/test-smoke.d.ts +0 -5
- package/dist/tests/test-smoke.js +0 -83
- package/dist/tests/test-smoke.js.map +0 -1
- package/dist/tests/writers/test-crlf-handling.d.ts +0 -4
- package/dist/tests/writers/test-crlf-handling.js +0 -73
- package/dist/tests/writers/test-crlf-handling.js.map +0 -1
- package/dist/tests/writers/test-write-smoke.d.ts +0 -9
- package/dist/tests/writers/test-write-smoke.js +0 -346
- package/dist/tests/writers/test-write-smoke.js.map +0 -1
- package/src/ast/dartCompressor.ts +0 -1013
- package/src/ast/phpCompressor.ts +0 -814
- package/src/ast/semanticCompressor.ts +0 -808
- package/src/ast/writers/dartWriter.ts +0 -648
- package/src/ast/writers/phpWriter.ts +0 -508
- package/src/ast/writers/pyWriter.ts +0 -446
- package/src/ast/writers/symbolWriter.ts +0 -277
- package/src/ast/writers/tsWriter.ts +0 -418
- package/src/index.ts +0 -1553
- package/src/utils/backupManager.ts +0 -66
- package/src/utils/confirmationCache.ts +0 -61
- package/src/utils/diffEngine.ts +0 -223
- package/src/utils/fuzzyMatch.ts +0 -86
- package/src/utils/ignoreManager.ts +0 -144
- package/tests/test-confirmation-flow.ts +0 -49
- package/tests/test-dart.d.ts +0 -1
- package/tests/test-dart.js +0 -209
- package/tests/test-dart.js.map +0 -1
- package/tests/test-dart.ts +0 -265
- package/tests/test-php-ast.d.ts +0 -1
- package/tests/test-php-ast.js +0 -152
- package/tests/test-php-ast.js.map +0 -1
- package/tests/test-php-ast.ts +0 -155
- package/tests/test-php.d.ts +0 -1
- package/tests/test-php.js +0 -234
- package/tests/test-php.js.map +0 -1
- package/tests/test-php.ts +0 -261
- package/tests/test-smoke.d.ts +0 -5
- package/tests/test-smoke.js +0 -83
- package/tests/test-smoke.js.map +0 -1
- package/tests/test-smoke.ts +0 -93
- package/tests/writers/test-crlf-handling.ts +0 -100
- package/tests/writers/test-write-smoke.ts +0 -568
- package/tsconfig.json +0 -19
package/tests/test-php-ast.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Quick test to understand php-parser AST node structure.
|
|
3
|
-
* Run: npx ts-node src/test-php-ast.ts
|
|
4
|
-
*/
|
|
5
|
-
import { createRequire } from "node:module";
|
|
6
|
-
const require = createRequire(import.meta.url);
|
|
7
|
-
const Engine = require("php-parser");
|
|
8
|
-
|
|
9
|
-
const parser = new Engine({
|
|
10
|
-
parser: { extractDoc: true, php7: true, php8: true },
|
|
11
|
-
ast: { withPositions: true, withSource: true },
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
const code = `<?php
|
|
15
|
-
namespace App\\Services;
|
|
16
|
-
|
|
17
|
-
use App\\Models\\User;
|
|
18
|
-
use App\\Contracts\\Cacheable;
|
|
19
|
-
|
|
20
|
-
interface Loggable {
|
|
21
|
-
public function getLogName(): string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
trait HasTimestamps {
|
|
25
|
-
/** Get current timestamp */
|
|
26
|
-
private function now(): int {
|
|
27
|
-
return time();
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
abstract class BaseService {
|
|
32
|
-
abstract public function execute(): void;
|
|
33
|
-
|
|
34
|
-
protected function log(string $msg): void {
|
|
35
|
-
echo $msg;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
class UserService extends BaseService implements Loggable, Cacheable {
|
|
40
|
-
use HasTimestamps;
|
|
41
|
-
|
|
42
|
-
private string $name;
|
|
43
|
-
public const VERSION = '1.0';
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Create a new UserService instance.
|
|
47
|
-
* @param string $name The user name
|
|
48
|
-
*/
|
|
49
|
-
public function __construct(string $name) {
|
|
50
|
-
$this->name = $name;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public function execute(): void {
|
|
54
|
-
$this->log($this->name);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
public function getLogName(): string {
|
|
58
|
-
return $this->name;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
public static function create(string $n): self {
|
|
62
|
-
return new self($n);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function helper(int $x, string $y = 'default'): bool {
|
|
67
|
-
return $x > 0;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
$lambda = function(int $a): int {
|
|
71
|
-
return $a * 2;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
enum Color: string {
|
|
75
|
-
case Red = 'red';
|
|
76
|
-
case Blue = 'blue';
|
|
77
|
-
}
|
|
78
|
-
`;
|
|
79
|
-
|
|
80
|
-
const ast = parser.parseCode(code, "test.php");
|
|
81
|
-
|
|
82
|
-
function printNode(node: any, depth = 0) {
|
|
83
|
-
if (!node || typeof node !== "object") return;
|
|
84
|
-
const indent = " ".repeat(depth);
|
|
85
|
-
|
|
86
|
-
if (node.kind) {
|
|
87
|
-
const info: string[] = [`${indent}[${node.kind}]`];
|
|
88
|
-
|
|
89
|
-
if (node.name) {
|
|
90
|
-
const name = typeof node.name === "string" ? node.name : node.name?.name || "";
|
|
91
|
-
info.push(`name="${name}"`);
|
|
92
|
-
}
|
|
93
|
-
if (node.visibility) info.push(`visibility="${node.visibility}"`);
|
|
94
|
-
if (node.isStatic) info.push("static");
|
|
95
|
-
if (node.isAbstract) info.push("abstract");
|
|
96
|
-
if (node.isFinal) info.push("final");
|
|
97
|
-
if (node.nullable) info.push("nullable");
|
|
98
|
-
if (node.type) {
|
|
99
|
-
const t = typeof node.type === "string" ? node.type : node.type?.name || JSON.stringify(node.type?.kind);
|
|
100
|
-
info.push(`type=${t}`);
|
|
101
|
-
}
|
|
102
|
-
if (node.extends) {
|
|
103
|
-
const ext = typeof node.extends === "string" ? node.extends : node.extends?.name || "";
|
|
104
|
-
info.push(`extends=${ext}`);
|
|
105
|
-
}
|
|
106
|
-
if (node.implements && node.implements.length > 0) {
|
|
107
|
-
info.push(`implements=[${node.implements.map((i: any) => i.name || i).join(", ")}]`);
|
|
108
|
-
}
|
|
109
|
-
if (node.value && typeof node.value === "string") {
|
|
110
|
-
info.push(`value="${node.value.substring(0, 40)}"`);
|
|
111
|
-
}
|
|
112
|
-
if (node.leadingComments) {
|
|
113
|
-
info.push(`docComment=YES`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
console.log(info.join(" "));
|
|
117
|
-
|
|
118
|
-
// Print arguments/parameters
|
|
119
|
-
if (node.arguments && Array.isArray(node.arguments)) {
|
|
120
|
-
for (const arg of node.arguments) {
|
|
121
|
-
printNode(arg, depth + 1);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Print children/body
|
|
126
|
-
if (node.children && Array.isArray(node.children)) {
|
|
127
|
-
for (const child of node.children) {
|
|
128
|
-
printNode(child, depth + 1);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (node.body && Array.isArray(node.body)) {
|
|
132
|
-
for (const child of node.body) {
|
|
133
|
-
printNode(child, depth + 1);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (node.items && Array.isArray(node.items)) {
|
|
137
|
-
for (const item of node.items) {
|
|
138
|
-
printNode(item, depth + 1);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if (node.cases && Array.isArray(node.cases)) {
|
|
142
|
-
for (const c of node.cases) {
|
|
143
|
-
printNode(c, depth + 1);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (node.traits && Array.isArray(node.traits)) {
|
|
147
|
-
for (const t of node.traits) {
|
|
148
|
-
printNode(t, depth + 1);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
console.log("=== PHP AST Node Structure ===\n");
|
|
155
|
-
printNode(ast);
|
package/tests/test-php.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/tests/test-php.js
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Smoke test for PHP AST compression — tests against real DT24 PHP files.
|
|
3
|
-
*/
|
|
4
|
-
import { compressPHP, extractPHPSymbol } from "../src/ast/phpCompressor.js";
|
|
5
|
-
import * as fs from "node:fs";
|
|
6
|
-
function log(label, value) {
|
|
7
|
-
console.log(`\n${"─".repeat(60)}`);
|
|
8
|
-
console.log(`✅ ${label}`);
|
|
9
|
-
console.log(`${"─".repeat(60)}`);
|
|
10
|
-
console.log(typeof value === "number" ? String(value) : value);
|
|
11
|
-
}
|
|
12
|
-
function fail(label, reason) {
|
|
13
|
-
console.log(`\n${"─".repeat(60)}`);
|
|
14
|
-
console.log(`❌ FAIL: ${label}`);
|
|
15
|
-
console.log(`${"─".repeat(60)}`);
|
|
16
|
-
console.log(reason);
|
|
17
|
-
process.exitCode = 1;
|
|
18
|
-
}
|
|
19
|
-
async function main() {
|
|
20
|
-
let passed = 0;
|
|
21
|
-
let failed = 0;
|
|
22
|
-
// ─── Test 1: Compress a class with namespace ───────────────────
|
|
23
|
-
console.log("\n\n🧪 TEST 1: Compress Dt24Config.php (namespace + static class)");
|
|
24
|
-
const configPath = "c:/code/dt24-core-plugin/includes/Dt24Config.php";
|
|
25
|
-
if (fs.existsSync(configPath)) {
|
|
26
|
-
const content = fs.readFileSync(configPath, "utf-8");
|
|
27
|
-
const compressed = compressPHP(content);
|
|
28
|
-
const originalLines = content.split("\n").length;
|
|
29
|
-
const compressedLines = compressed.split("\n").length;
|
|
30
|
-
const ratio = ((1 - compressedLines / originalLines) * 100).toFixed(1);
|
|
31
|
-
log(`Dt24Config.php: ${originalLines} → ${compressedLines} lines (${ratio}% reduction)`, compressed);
|
|
32
|
-
// Verify key structures are present
|
|
33
|
-
const checks = [
|
|
34
|
-
["namespace", /namespace\s+Dt24ApiAuth/],
|
|
35
|
-
["class declaration", /class\s+Dt24Config/],
|
|
36
|
-
["static property", /\$cache/],
|
|
37
|
-
["env() method signature", /public\s+static\s+function\s+env\(/],
|
|
38
|
-
["set_config() method", /public\s+static\s+function\s+set_config\(/],
|
|
39
|
-
["body stripped", /\/\* \.\.\. \*\//],
|
|
40
|
-
];
|
|
41
|
-
for (const [name, pattern] of checks) {
|
|
42
|
-
if (pattern.test(compressed)) {
|
|
43
|
-
console.log(` ✓ Found: ${name}`);
|
|
44
|
-
passed++;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
fail(`Missing: ${name}`, `Pattern ${pattern} not found in compressed output`);
|
|
48
|
-
failed++;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
console.log(" ⚠️ Skipped (file not found)");
|
|
54
|
-
}
|
|
55
|
-
// ─── Test 2: Compress a large class with docblocks ─────────────
|
|
56
|
-
console.log("\n\n🧪 TEST 2: Compress Dt24_Api_Auth_Admin.php (class + constants + docblocks)");
|
|
57
|
-
const adminPath = "c:/code/dt24-core-plugin/admin/class-dt24-api-auth-admin.php";
|
|
58
|
-
if (fs.existsSync(adminPath)) {
|
|
59
|
-
const content = fs.readFileSync(adminPath, "utf-8");
|
|
60
|
-
const compressed = compressPHP(content);
|
|
61
|
-
const originalLines = content.split("\n").length;
|
|
62
|
-
const compressedLines = compressed.split("\n").length;
|
|
63
|
-
const ratio = ((1 - compressedLines / originalLines) * 100).toFixed(1);
|
|
64
|
-
log(`Admin: ${originalLines} → ${compressedLines} lines (${ratio}% reduction)`, compressed);
|
|
65
|
-
const checks = [
|
|
66
|
-
["class declaration", /class\s+Dt24_Api_Auth_Admin/],
|
|
67
|
-
["private property", /private\s+(.*\$plugin_name|\$plugin_name)/],
|
|
68
|
-
["const", /const\s+DT24_SECONDS_IN_MINUTES/],
|
|
69
|
-
["constructor", /function\s+__construct/],
|
|
70
|
-
["docblock", /\*\s+@param/],
|
|
71
|
-
["method signature", /function\s+check_the_elapsed_time\(/],
|
|
72
|
-
["body stripped", /\/\*\s*\.\.\.\s*\*\//],
|
|
73
|
-
["private method", /private\s+function\s+get_custom_statuses/],
|
|
74
|
-
];
|
|
75
|
-
for (const [name, pattern] of checks) {
|
|
76
|
-
if (pattern.test(compressed)) {
|
|
77
|
-
console.log(` ✓ Found: ${name}`);
|
|
78
|
-
passed++;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
fail(`Missing: ${name}`, `Pattern ${pattern} not found`);
|
|
82
|
-
failed++;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
console.log(" ⚠️ Skipped (file not found)");
|
|
88
|
-
}
|
|
89
|
-
// ─── Test 3: Extract specific symbol ──────────────────────────
|
|
90
|
-
console.log("\n\n🧪 TEST 3: Extract symbol 'env' from Dt24Config.php");
|
|
91
|
-
if (fs.existsSync(configPath)) {
|
|
92
|
-
const content = fs.readFileSync(configPath, "utf-8");
|
|
93
|
-
const symbol = extractPHPSymbol(content, "env");
|
|
94
|
-
if (symbol) {
|
|
95
|
-
log("Extracted 'env' method:", symbol);
|
|
96
|
-
if (symbol.includes("function env(") && symbol.includes("$cache")) {
|
|
97
|
-
console.log(" ✓ Symbol extraction contains both signature and body");
|
|
98
|
-
passed++;
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
fail("Symbol content", "Missing expected content");
|
|
102
|
-
failed++;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
fail("Symbol 'env'", "extractPHPSymbol returned null");
|
|
107
|
-
failed++;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
// ─── Test 4: Extract class symbol ─────────────────────────────
|
|
111
|
-
console.log("\n\n🧪 TEST 4: Extract symbol 'Dt24Config' from Dt24Config.php");
|
|
112
|
-
if (fs.existsSync(configPath)) {
|
|
113
|
-
const content = fs.readFileSync(configPath, "utf-8");
|
|
114
|
-
const symbol = extractPHPSymbol(content, "Dt24Config");
|
|
115
|
-
if (symbol) {
|
|
116
|
-
log("Extracted 'Dt24Config' class:", symbol.substring(0, 200) + "...");
|
|
117
|
-
if (symbol.includes("class Dt24Config") && symbol.includes("function env")) {
|
|
118
|
-
console.log(" ✓ Class extraction includes full body");
|
|
119
|
-
passed++;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
fail("Class content", "Missing expected content");
|
|
123
|
-
failed++;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
fail("Symbol 'Dt24Config'", "extractPHPSymbol returned null");
|
|
128
|
-
failed++;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
// ─── Test 5: Synthetic PHP with all features ──────────────────
|
|
132
|
-
console.log("\n\n🧪 TEST 5: Synthetic PHP (namespace, interface, trait, enum, abstract class)");
|
|
133
|
-
const syntheticPHP = `<?php
|
|
134
|
-
namespace App\\Services;
|
|
135
|
-
|
|
136
|
-
use App\\Models\\User;
|
|
137
|
-
use App\\Contracts\\Cacheable;
|
|
138
|
-
|
|
139
|
-
interface Loggable {
|
|
140
|
-
public function getLogName(): string;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
trait HasTimestamps {
|
|
144
|
-
/** Get current timestamp */
|
|
145
|
-
private function now(): int {
|
|
146
|
-
return time();
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
abstract class BaseService {
|
|
151
|
-
abstract public function execute(): void;
|
|
152
|
-
|
|
153
|
-
protected function log(string $msg): void {
|
|
154
|
-
echo $msg;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
class UserService extends BaseService implements Loggable, Cacheable {
|
|
159
|
-
use HasTimestamps;
|
|
160
|
-
|
|
161
|
-
private string $name;
|
|
162
|
-
public const VERSION = '1.0';
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Create a new UserService instance.
|
|
166
|
-
* @param string $name The user name
|
|
167
|
-
*/
|
|
168
|
-
public function __construct(string $name) {
|
|
169
|
-
$this->name = $name;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public function execute(): void {
|
|
173
|
-
$this->log($this->name);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
public function getLogName(): string {
|
|
177
|
-
return $this->name;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
public static function create(string $n): self {
|
|
181
|
-
return new self($n);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function helper(int $x, string $y = 'default'): bool {
|
|
186
|
-
return $x > 0;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
enum Color: string {
|
|
190
|
-
case Red = 'red';
|
|
191
|
-
case Blue = 'blue';
|
|
192
|
-
}
|
|
193
|
-
`;
|
|
194
|
-
const compressed = compressPHP(syntheticPHP);
|
|
195
|
-
const originalLines = syntheticPHP.split("\n").length;
|
|
196
|
-
const compressedLines = compressed.split("\n").length;
|
|
197
|
-
const ratio = ((1 - compressedLines / originalLines) * 100).toFixed(1);
|
|
198
|
-
log(`Synthetic: ${originalLines} → ${compressedLines} lines (${ratio}% reduction)`, compressed);
|
|
199
|
-
const syntheticChecks = [
|
|
200
|
-
["namespace", /namespace App\\Services/],
|
|
201
|
-
["use statement", /use App\\Models\\User/],
|
|
202
|
-
["interface", /interface Loggable/],
|
|
203
|
-
["trait", /trait HasTimestamps/],
|
|
204
|
-
["abstract class", /abstract class BaseService/],
|
|
205
|
-
["abstract method", /abstract public function execute/],
|
|
206
|
-
["class extends+implements", /class UserService extends BaseService implements Loggable, Cacheable/],
|
|
207
|
-
["trait use", /use HasTimestamps/],
|
|
208
|
-
["const", /public const VERSION/],
|
|
209
|
-
["docblock", /@param string \$name/],
|
|
210
|
-
["static method", /public static function create/],
|
|
211
|
-
["return type self", /: self/],
|
|
212
|
-
["top-level function", /function helper\(/],
|
|
213
|
-
["default param", /\$y = 'default'/],
|
|
214
|
-
["enum", /enum Color: string/],
|
|
215
|
-
["enum case", /case Red = 'red'/],
|
|
216
|
-
["body stripped", /\/\* \.\.\. \*\//],
|
|
217
|
-
];
|
|
218
|
-
for (const [name, pattern] of syntheticChecks) {
|
|
219
|
-
if (pattern.test(compressed)) {
|
|
220
|
-
console.log(` ✓ Found: ${name}`);
|
|
221
|
-
passed++;
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
fail(`Missing: ${name}`, `Pattern ${pattern} not found`);
|
|
225
|
-
failed++;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
// ─── Summary ─────────────────────────────────────────────────
|
|
229
|
-
console.log(`\n\n${"═".repeat(60)}`);
|
|
230
|
-
console.log(`📊 RESULTS: ${passed} passed, ${failed} failed`);
|
|
231
|
-
console.log(`${"═".repeat(60)}\n`);
|
|
232
|
-
}
|
|
233
|
-
main().catch(console.error);
|
|
234
|
-
//# sourceMappingURL=test-php.js.map
|
package/tests/test-php.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-php.js","sourceRoot":"","sources":["test-php.ts"],"names":[],"mappings":"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"}
|
package/tests/test-php.ts
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Smoke test for PHP AST compression — tests against real DT24 PHP files.
|
|
3
|
-
*/
|
|
4
|
-
import { compressPHP, extractPHPSymbol } from "../src/ast/phpCompressor.js";
|
|
5
|
-
import * as fs from "node:fs";
|
|
6
|
-
import * as path from "node:path";
|
|
7
|
-
|
|
8
|
-
function log(label: string, value: string | number) {
|
|
9
|
-
console.log(`\n${"─".repeat(60)}`);
|
|
10
|
-
console.log(`✅ ${label}`);
|
|
11
|
-
console.log(`${"─".repeat(60)}`);
|
|
12
|
-
console.log(typeof value === "number" ? String(value) : value);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function fail(label: string, reason: string) {
|
|
16
|
-
console.log(`\n${"─".repeat(60)}`);
|
|
17
|
-
console.log(`❌ FAIL: ${label}`);
|
|
18
|
-
console.log(`${"─".repeat(60)}`);
|
|
19
|
-
console.log(reason);
|
|
20
|
-
process.exitCode = 1;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function main() {
|
|
24
|
-
let passed = 0;
|
|
25
|
-
let failed = 0;
|
|
26
|
-
|
|
27
|
-
// ─── Test 1: Compress a class with namespace ───────────────────
|
|
28
|
-
console.log("\n\n🧪 TEST 1: Compress Dt24Config.php (namespace + static class)");
|
|
29
|
-
|
|
30
|
-
const configPath = "c:/code/dt24-core-plugin/includes/Dt24Config.php";
|
|
31
|
-
if (fs.existsSync(configPath)) {
|
|
32
|
-
const content = fs.readFileSync(configPath, "utf-8");
|
|
33
|
-
const compressed = compressPHP(content);
|
|
34
|
-
const originalLines = content.split("\n").length;
|
|
35
|
-
const compressedLines = compressed.split("\n").length;
|
|
36
|
-
const ratio = ((1 - compressedLines / originalLines) * 100).toFixed(1);
|
|
37
|
-
|
|
38
|
-
log(
|
|
39
|
-
`Dt24Config.php: ${originalLines} → ${compressedLines} lines (${ratio}% reduction)`,
|
|
40
|
-
compressed,
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
// Verify key structures are present
|
|
44
|
-
const checks = [
|
|
45
|
-
["namespace", /namespace\s+Dt24ApiAuth/],
|
|
46
|
-
["class declaration", /class\s+Dt24Config/],
|
|
47
|
-
["static property", /\$cache/],
|
|
48
|
-
["env() method signature", /public\s+static\s+function\s+env\(/],
|
|
49
|
-
["set_config() method", /public\s+static\s+function\s+set_config\(/],
|
|
50
|
-
["body stripped", /\/\* \.\.\. \*\//],
|
|
51
|
-
] as const;
|
|
52
|
-
|
|
53
|
-
for (const [name, pattern] of checks) {
|
|
54
|
-
if (pattern.test(compressed)) {
|
|
55
|
-
console.log(` ✓ Found: ${name}`);
|
|
56
|
-
passed++;
|
|
57
|
-
} else {
|
|
58
|
-
fail(`Missing: ${name}`, `Pattern ${pattern} not found in compressed output`);
|
|
59
|
-
failed++;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
console.log(" ⚠️ Skipped (file not found)");
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// ─── Test 2: Compress a large class with docblocks ─────────────
|
|
67
|
-
console.log("\n\n🧪 TEST 2: Compress Dt24_Api_Auth_Admin.php (class + constants + docblocks)");
|
|
68
|
-
|
|
69
|
-
const adminPath = "c:/code/dt24-core-plugin/admin/class-dt24-api-auth-admin.php";
|
|
70
|
-
if (fs.existsSync(adminPath)) {
|
|
71
|
-
const content = fs.readFileSync(adminPath, "utf-8");
|
|
72
|
-
const compressed = compressPHP(content);
|
|
73
|
-
const originalLines = content.split("\n").length;
|
|
74
|
-
const compressedLines = compressed.split("\n").length;
|
|
75
|
-
const ratio = ((1 - compressedLines / originalLines) * 100).toFixed(1);
|
|
76
|
-
|
|
77
|
-
log(
|
|
78
|
-
`Admin: ${originalLines} → ${compressedLines} lines (${ratio}% reduction)`,
|
|
79
|
-
compressed,
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
const checks = [
|
|
83
|
-
["class declaration", /class\s+Dt24_Api_Auth_Admin/],
|
|
84
|
-
["private property", /private\s+(.*\$plugin_name|\$plugin_name)/],
|
|
85
|
-
["const", /const\s+DT24_SECONDS_IN_MINUTES/],
|
|
86
|
-
["constructor", /function\s+__construct/],
|
|
87
|
-
["docblock", /\*\s+@param/],
|
|
88
|
-
["method signature", /function\s+check_the_elapsed_time\(/],
|
|
89
|
-
["body stripped", /\/\*\s*\.\.\.\s*\*\//],
|
|
90
|
-
["private method", /private\s+function\s+get_custom_statuses/],
|
|
91
|
-
] as const;
|
|
92
|
-
|
|
93
|
-
for (const [name, pattern] of checks) {
|
|
94
|
-
if (pattern.test(compressed)) {
|
|
95
|
-
console.log(` ✓ Found: ${name}`);
|
|
96
|
-
passed++;
|
|
97
|
-
} else {
|
|
98
|
-
fail(`Missing: ${name}`, `Pattern ${pattern} not found`);
|
|
99
|
-
failed++;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
} else {
|
|
103
|
-
console.log(" ⚠️ Skipped (file not found)");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// ─── Test 3: Extract specific symbol ──────────────────────────
|
|
107
|
-
console.log("\n\n🧪 TEST 3: Extract symbol 'env' from Dt24Config.php");
|
|
108
|
-
|
|
109
|
-
if (fs.existsSync(configPath)) {
|
|
110
|
-
const content = fs.readFileSync(configPath, "utf-8");
|
|
111
|
-
const symbol = extractPHPSymbol(content, "env");
|
|
112
|
-
|
|
113
|
-
if (symbol) {
|
|
114
|
-
log("Extracted 'env' method:", symbol);
|
|
115
|
-
if (symbol.includes("function env(") && symbol.includes("$cache")) {
|
|
116
|
-
console.log(" ✓ Symbol extraction contains both signature and body");
|
|
117
|
-
passed++;
|
|
118
|
-
} else {
|
|
119
|
-
fail("Symbol content", "Missing expected content");
|
|
120
|
-
failed++;
|
|
121
|
-
}
|
|
122
|
-
} else {
|
|
123
|
-
fail("Symbol 'env'", "extractPHPSymbol returned null");
|
|
124
|
-
failed++;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// ─── Test 4: Extract class symbol ─────────────────────────────
|
|
129
|
-
console.log("\n\n🧪 TEST 4: Extract symbol 'Dt24Config' from Dt24Config.php");
|
|
130
|
-
|
|
131
|
-
if (fs.existsSync(configPath)) {
|
|
132
|
-
const content = fs.readFileSync(configPath, "utf-8");
|
|
133
|
-
const symbol = extractPHPSymbol(content, "Dt24Config");
|
|
134
|
-
|
|
135
|
-
if (symbol) {
|
|
136
|
-
log("Extracted 'Dt24Config' class:", symbol.substring(0, 200) + "...");
|
|
137
|
-
if (symbol.includes("class Dt24Config") && symbol.includes("function env")) {
|
|
138
|
-
console.log(" ✓ Class extraction includes full body");
|
|
139
|
-
passed++;
|
|
140
|
-
} else {
|
|
141
|
-
fail("Class content", "Missing expected content");
|
|
142
|
-
failed++;
|
|
143
|
-
}
|
|
144
|
-
} else {
|
|
145
|
-
fail("Symbol 'Dt24Config'", "extractPHPSymbol returned null");
|
|
146
|
-
failed++;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// ─── Test 5: Synthetic PHP with all features ──────────────────
|
|
151
|
-
console.log("\n\n🧪 TEST 5: Synthetic PHP (namespace, interface, trait, enum, abstract class)");
|
|
152
|
-
|
|
153
|
-
const syntheticPHP = `<?php
|
|
154
|
-
namespace App\\Services;
|
|
155
|
-
|
|
156
|
-
use App\\Models\\User;
|
|
157
|
-
use App\\Contracts\\Cacheable;
|
|
158
|
-
|
|
159
|
-
interface Loggable {
|
|
160
|
-
public function getLogName(): string;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
trait HasTimestamps {
|
|
164
|
-
/** Get current timestamp */
|
|
165
|
-
private function now(): int {
|
|
166
|
-
return time();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
abstract class BaseService {
|
|
171
|
-
abstract public function execute(): void;
|
|
172
|
-
|
|
173
|
-
protected function log(string $msg): void {
|
|
174
|
-
echo $msg;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
class UserService extends BaseService implements Loggable, Cacheable {
|
|
179
|
-
use HasTimestamps;
|
|
180
|
-
|
|
181
|
-
private string $name;
|
|
182
|
-
public const VERSION = '1.0';
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Create a new UserService instance.
|
|
186
|
-
* @param string $name The user name
|
|
187
|
-
*/
|
|
188
|
-
public function __construct(string $name) {
|
|
189
|
-
$this->name = $name;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
public function execute(): void {
|
|
193
|
-
$this->log($this->name);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
public function getLogName(): string {
|
|
197
|
-
return $this->name;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
public static function create(string $n): self {
|
|
201
|
-
return new self($n);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function helper(int $x, string $y = 'default'): bool {
|
|
206
|
-
return $x > 0;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
enum Color: string {
|
|
210
|
-
case Red = 'red';
|
|
211
|
-
case Blue = 'blue';
|
|
212
|
-
}
|
|
213
|
-
`;
|
|
214
|
-
|
|
215
|
-
const compressed = compressPHP(syntheticPHP);
|
|
216
|
-
const originalLines = syntheticPHP.split("\n").length;
|
|
217
|
-
const compressedLines = compressed.split("\n").length;
|
|
218
|
-
const ratio = ((1 - compressedLines / originalLines) * 100).toFixed(1);
|
|
219
|
-
|
|
220
|
-
log(
|
|
221
|
-
`Synthetic: ${originalLines} → ${compressedLines} lines (${ratio}% reduction)`,
|
|
222
|
-
compressed,
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
const syntheticChecks = [
|
|
226
|
-
["namespace", /namespace App\\Services/],
|
|
227
|
-
["use statement", /use App\\Models\\User/],
|
|
228
|
-
["interface", /interface Loggable/],
|
|
229
|
-
["trait", /trait HasTimestamps/],
|
|
230
|
-
["abstract class", /abstract class BaseService/],
|
|
231
|
-
["abstract method", /abstract public function execute/],
|
|
232
|
-
["class extends+implements", /class UserService extends BaseService implements Loggable, Cacheable/],
|
|
233
|
-
["trait use", /use HasTimestamps/],
|
|
234
|
-
["const", /public const VERSION/],
|
|
235
|
-
["docblock", /@param string \$name/],
|
|
236
|
-
["static method", /public static function create/],
|
|
237
|
-
["return type self", /: self/],
|
|
238
|
-
["top-level function", /function helper\(/],
|
|
239
|
-
["default param", /\$y = 'default'/],
|
|
240
|
-
["enum", /enum Color: string/],
|
|
241
|
-
["enum case", /case Red = 'red'/],
|
|
242
|
-
["body stripped", /\/\* \.\.\. \*\//],
|
|
243
|
-
] as const;
|
|
244
|
-
|
|
245
|
-
for (const [name, pattern] of syntheticChecks) {
|
|
246
|
-
if (pattern.test(compressed)) {
|
|
247
|
-
console.log(` ✓ Found: ${name}`);
|
|
248
|
-
passed++;
|
|
249
|
-
} else {
|
|
250
|
-
fail(`Missing: ${name}`, `Pattern ${pattern} not found`);
|
|
251
|
-
failed++;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// ─── Summary ─────────────────────────────────────────────────
|
|
256
|
-
console.log(`\n\n${"═".repeat(60)}`);
|
|
257
|
-
console.log(`📊 RESULTS: ${passed} passed, ${failed} failed`);
|
|
258
|
-
console.log(`${"═".repeat(60)}\n`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
main().catch(console.error);
|