Skip to content

Commit 0c8c43f

Browse files
authored
Merge pull request #205 from RightCapitalHQ/feature/add-async-parser-and-change-type-generation
feat(cli-helpers): add async PHP file parsing method
2 parents 191f2c2 + 3f4ec3a commit 0c8c43f

File tree

4 files changed

+94
-22
lines changed

4 files changed

+94
-22
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "feat(cli-helpers): add async PHP file parsing method and refactor path resolution",
4+
"packageName": "@rightcapital/php-parser",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

src/php-parser/helpers/cli-helpers.ts

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { execSync } from 'node:child_process';
1+
import { execFile, execSync } from 'node:child_process';
22
import * as fs from 'node:fs';
33
import { tmpdir } from 'node:os';
4-
import { resolve } from 'node:path';
4+
import * as path from 'node:path';
55

66
import { PROJECT_ROOT } from '../../constants';
77
import type { NodeTypeInheritingFromNodeAbstract } from '../types/types';
88

9-
const defaultPhpParserBinaryPath = resolve(
9+
const defaultPhpParserBinaryPath = path.resolve(
1010
PROJECT_ROOT,
1111
'vendor',
1212
'bin',
@@ -42,6 +42,46 @@ export class CliHelpers {
4242
) as NodeTypeInheritingFromNodeAbstract[];
4343
}
4444

45+
/**
46+
* Using PHP version php phaser to Parse PHP File to AST (Async version)
47+
*
48+
* @param phpFilePath The PHP file path to parse
49+
* @returns Promise resolving to an AST in JSON format from php parser
50+
*/
51+
public static async parsePhpFileToAstAsync(
52+
phpFilePath: string,
53+
): Promise<NodeTypeInheritingFromNodeAbstract[]> {
54+
return new Promise((resolve, reject) => {
55+
execFile(
56+
PHP_PARSER_BINARY,
57+
[phpFilePath, '-j'],
58+
{
59+
encoding: 'utf8',
60+
maxBuffer: MAX_BUFFER_SIZE_FOR_PHP_BINARY_OUTPUT,
61+
},
62+
(error, stdout) => {
63+
if (error) {
64+
reject(new Error(`Failed to parse PHP file: ${error.message}`));
65+
return;
66+
}
67+
68+
try {
69+
const result = JSON.parse(
70+
stdout,
71+
) as NodeTypeInheritingFromNodeAbstract[];
72+
resolve(result);
73+
} catch (parseError) {
74+
reject(
75+
new Error(
76+
`Failed to parse JSON output: ${parseError instanceof Error ? parseError.message : String(parseError)}`,
77+
),
78+
);
79+
}
80+
},
81+
);
82+
});
83+
}
84+
4585
/**
4686
* Parse a PHP Code string to AST in JSON format
4787
* Because we are invoking PHP parser to parse the string
@@ -56,7 +96,7 @@ export class CliHelpers {
5696
/**
5797
* Temp file like "php-parser-{current time}.tmp" +
5898
*/
59-
const temporaryFilename = resolve(
99+
const temporaryFilename = path.resolve(
60100
tmpdir(),
61101
`${currentDate.getTime()}.${currentDate.getMilliseconds()}.tmp`,
62102
);

src/php-parser/helpers/type-generation-helpers.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,39 @@ export class TypeGenerationHelpers {
3232

3333
const combinationTypesPart = Object.entries(allNodes)
3434
.map(([name, nodeItem]) => {
35+
const validSubNodeTypes = nodeItem.subNodeNames
36+
.filter((subNodeName) => {
37+
const subNode = allNodes[subNodeName];
38+
const hasNodeType =
39+
subNode &&
40+
subNode.nodeType !== undefined &&
41+
subNode.nodeType !== '';
42+
const isUnionType =
43+
subNode &&
44+
subNode.subNodeNames &&
45+
subNode.subNodeNames.length > 0;
46+
47+
return hasNodeType || isUnionType;
48+
})
49+
.map((subNodeName) =>
50+
TypeGenerationHelpers.getGroupedTypeNameForNode(subNodeName),
51+
);
52+
53+
const shouldIncludeSelf =
54+
nodeItem.nodeType !== undefined && nodeItem.nodeType !== '';
55+
56+
const typeComponents = [
57+
...(shouldIncludeSelf ? [name] : []),
58+
...validSubNodeTypes,
59+
];
60+
61+
if (typeComponents.length === 0) {
62+
typeComponents.push(name);
63+
}
64+
3565
return `export type ${TypeGenerationHelpers.getGroupedTypeNameForNode(
3666
name,
37-
)} = ${[
38-
name,
39-
...nodeItem.subNodeNames.map((subNodeName) =>
40-
TypeGenerationHelpers.getGroupedTypeNameForNode(subNodeName),
41-
),
42-
].join(' | ')};`;
67+
)} = ${typeComponents.join(' | ')};`;
4368
})
4469
.join('\n');
4570

0 commit comments

Comments
 (0)